如何解决如何准确检测和定位汽车保险丝?
目前我正在做一个项目,我需要测量汽车保险丝的宽度。为了实现这一点,我需要检测和定位图像上的保险丝。 fuse_image
我的计划是找到带有保险丝的边界矩形区域,然后在该区域的固定位置搜索导线轮廓。fuse_contours
我已经尝试过基于 ORB、BRISK 特征的模板匹配,但结果不可接受。也许有人可以提出一些可能的方法来解决这个任务?
解决方法
我们可以通过应用Canny操作来查看图像的特征来开始这个问题。结果是:
目的是计算宽度。因此我们只需要图像的左右外长。我们不需要内线。要移除内部特征,我们可以smooth 图像。
我们如何准确计算宽度?我们可以将哪些部分的功能作为参考?如果我们考虑基数?基本功能是:
我们如何找到基本特征坐标?
-
蓝点是y坐标值最高的点
-
红点是x坐标值最高的点
对于所有检测到的线坐标,我们需要找到对应的x坐标值的最高y坐标值。我们需要找到对应的 y 值的最高 x 坐标值。
为了检测线坐标,我们可以使用 fast line detector。结果将是:
我们可以计算欧几里得距离,即:146.49 像素
这个想法是基于找到基数然后计算欧几里得距离。
更新
保险丝的方向可以随意。
首先,我们需要获取图像的保险丝部分。
其次,我们需要获得 canny 特征(或任何其他过滤方法)
此时我们需要找到保险丝的左侧(蓝点)和右侧(红点)部分:
如果我们连接它们:
我们将获得大约长度的保险丝。
那么我们如何找到保险丝的左右部分?
-
寻找左边部分:
-
1. From the current x1,x2 tuples 2. If min(x1,x2) < x_min 3. x_min = min(x1,x2)
-
-
找到正确的部分:
-
1. From the current x1,x2 tuples 2. If max(x1,x2) > x_max 3. x_max = max(x1,x2)
-
这是我解决问题的想法。您可以修改以获得更好的结果。
代码:
# Load libraries
import cv2
import numpy as np
# Load the image
img = cv2.imread("E8XlZ.jpg")
# Get the image dimension
(h,w) = img.shape[:2]
# Convert to hsv
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# Get the binary-mask
msk = cv2.inRange(hsv,np.array([0,24,161]),np.array([77,255,217]))
# Display the mask
cv2.imshow("msk",msk)
cv2.waitKey(0)
# Smooth the image
gauss = cv2.GaussianBlur(msk,(21,21),0)
# Canny features
cny = cv2.Canny(gauss,50,200)
# Display canny features
cv2.imshow("cny",cny)
cv2.waitKey(0)
# Initialize line-detector
lns = cv2.ximgproc.createFastLineDetector().detect(cny)
# Initialize temporary variables
x_min,x_max,y_min,y_max = w,0
# Detect the lines
for line in lns:
# Get current coordinates
x1 = int(line[0][0])
y1 = int(line[0][1])
x2 = int(line[0][2])
y2 = int(line[0][3])
# Get maximum coordinates
if max(x1,x2) > x_max:
x_max = max(x1,x2)
y_max = y1 if x_max == x1 else y2
if min(x1,x2) < x_min:
x_min = min(x1,x2)
y_min = y1 if x_min == x1 else y2
# Draw the points
cv2.circle(img,(x_min,int((y_min + y_max)/2)),3,(255,0),5)
cv2.circle(img,(x_max,(0,255),5)
# Write coordinates to the console
print("Coordinates: ({},{})->({},{})".format(x_min,int((y_min + y_max)/2),int((y_min + y_max)/2)))
# Draw the minimum and maximum coordinates
cv2.line(img,5)
# Calculate the euclidean distance
pt1 = np.array((x_min,int((y_min + y_max)/2)))
pt2 = np.array((x_max,int((y_min + y_max)/2)))
dist = np.linalg.norm(pt1 - pt2)
print("Result: %.2f pixel" % dist)
# Display the result
cv2.imshow("img",img)
cv2.waitKey(0)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。