首页 > 编程语言 >实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)

时间:2022-11-09 13:42:56浏览次数:80  
标签:直线 实用技巧 mask cv2 OpenCV 源码 交点 np 255



导读

本期将介绍使用OpenCV用两种不同的方法实现快速查找计算直线/网格线交点坐标。

直线交点计算思路与常用方法

直线交点的计算这里列举几个比较常用的方法:

① 在知道直线方程的前提下(或知道直线上一点和直线角度),联立方程求解交点坐标(注意数学坐标系和图像坐标系的关系);

② 不知道直线方程,通过检测直线的方法(例如霍夫变换)计算直线方程,然后联立方程求解交点坐标;


第一种方法当然是最理想的情况,这样计算的交点也最准确。但是大多数情况我们并不能预先知道直线方程。第二种方法在干扰少的情况比较适用,当然我们还要考虑OpenCV的直线检测方法可能会有重复直线被检测,还需要做剔除操作。


综上来看,前面两种方法并不是非常好用,下面来介绍两种简单实用的方法:

③;

本文使用方法③和方法④,设置合适的参数即可检测到直线交点位置。

效果展示

本文演示图片包含2张,一张是简单的三条直线相交,另一张是多条直线相交形成网格,分别计算它们的交点位置并标识,效果如下:

原图:

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测

结果图:

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测_02

原图:

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_公众号_03

结果图:

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测_04


实现步骤与对应代码

方法③实现步骤与代码

(1) Harris角点检测+阈值处理;

import cv2
import numpy as np


img = cv2.imread('1.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
mask = np.zeros(gray.shape,np.uint8)
dst = cv2.cornerHarris(gray,2,3,0.04)
ret,thresh = cv2.threshold(dst,0.01,255,cv2.THRESH_BINARY)
cv2.imshow('thresh',thresh)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_05

(2) 形态学膨胀(将角点连接起来);

k1=np.ones((5,5), np.uint8)#指定膨胀核大小
mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, k1)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测_06

(3) 轮廓筛选,w>10 and h > 10,直线交点位置轮廓更大。

contours,hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
(x, y, w, h) = cv2.boundingRect(cnt)
if w > 10 and h > 10:
cx = int(x + w / 2)
cy = int(y + h / 2)
cv2.circle(img,(cx, cy),10,(0,255,0),2, cv2.LINE_AA)
cv2.circle(img,(cx, cy),2,(0,0,255),-1, cv2.LINE_AA)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_公众号_07

对于图2,代码修改两处参数:

k1=np.ones((1,7), np.uint8)
......
if w > 1 and h > 1:
......

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_08

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_09

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_公众号_10

方法④实现步骤与代码

(1) 固定阈值二值化凸显直线为白色,背景为黑色;

import numpy as np
import cv2


img= cv2.imread('1.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thres= cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
cv2.imshow('thres', thres)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测_11

(2) 指定核做开运算,再做闭运算;

k1=np.ones((1,7), np.uint8)
k2=np.ones((7,1), np.uint8)


mask = cv2.morphologyEx(thres, cv2.MORPH_OPEN, k1)
cv2.imshow('open', mask)


mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, k2)
cv2.imshow('close', mask)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测_12

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_13

(3) 轮廓查找与中心计算标示;

contours,hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
(x, y, w, h) = cv2.boundingRect(cnt)
#cv2.rectangle(img, (x, y),(x+w,y+h),(0, 255, 0), 2)
cx = int(x + w / 2)
cy = int(y + h / 2)
cv2.circle(img,(cx, cy),10,(0,255,0),2, cv2.LINE_AA)
cv2.circle(img,(cx, cy),2,(0,0,255),-1, cv2.LINE_AA)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_角点检测_14

对于图2,代码修改两处参数:

ret, thres= cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)
......
k1=np.ones((3,1), np.uint8)
k2=np.ones((1,7), np.uint8)

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_15

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_公众号_16

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_17

实用技巧 | OpenCV快速计算直线/网格线交点坐标(附源码)_深度学习_18

此处涉及到的形态学技巧原来有介绍过,可以参看下面链接查看:

​OpenCV形态学处理使用技巧与应用演示​

结尾语:

文章实现的步骤并非最优,但基本检测效果还OK,大家跟着上述步骤和代码完全可以自己做出来。当然如果你懒得动手,那就加入知识星球获取吧,那里为你准备了完整源码和测试素材,还有C++源码。

更多实用文章请移步至--精华文章--专题文章分类。

—THE END—




标签:直线,实用技巧,mask,cv2,OpenCV,源码,交点,np,255
From: https://blog.51cto.com/stq054188/5835901

相关文章