[英]How to accurately detect and localize car fuse?
目前我正在做一个项目,我需要测量汽车保险丝的宽度。 为了实现这一点,我需要检测和定位图像上的保险丝。 fuse_image
我的计划是用保险丝找到边界矩形区域,然后在该区域的固定 position 中搜索线轮廓。 fuse_contours
我已经尝试过 ORB,基于 BRISK 特征的模板匹配,但结果不可接受。 也许任何人都可以提出一些可能的方法来解决这个任务?
我们可以通过应用Canny操作来查看图像的特征来解决这个问题。 结果是:
目的是计算宽度。 因此我们只需要图像的左右外长度。 我们不需要内线。 为了去除内部特征,我们可以平滑图像。
我们如何准确计算宽度? 我们可以参考哪些特征? 如果我们考虑基数? 基本特征是:
我们如何找到基本特征坐标?
蓝点是y坐标值最高的点
红点是x坐标值最高的那个
对于所有检测到的线坐标,我们需要找到对应的 x 坐标值的最高 y 坐标值。 我们需要找到对应 y 值的最高 x 坐标值。
为了检测线坐标,我们可以使用快速线检测器。 结果将是:
我们可以计算出欧几里得距离,即:146.49 像素
这个想法是基于找到基础然后计算欧几里得距离。
更新
保险丝的方向可以是随机的。
首先,我们需要得到图像的保险丝部分。
其次,我们需要得到精明的特征(或任何其他过滤方法)
此时我们需要找到保险丝的左侧(蓝点)和右侧(红点)部分:
如果我们连接它们:
我们将有一个大概的保险丝长度。
那么我们如何找到保险丝的左右部分呢?
查找左侧部分:
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, 0, 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, 0), 5)
cv2.circle(img, (x_max, int((y_min + y_max)/2)), 3, (0, 0, 255), 5)
# Write coordinates to the console
print("Coordinates: ({}, {})->({}, {})".format(x_min, int((y_min + y_max)/2), x_max, int((y_min + y_max)/2)))
# Draw the minimum and maximum coordinates
cv2.line(img, (x_min, int((y_min + y_max)/2)), (x_max, int((y_min + y_max)/2)), (0, 255, 0), 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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.