繁体   English   中英

如何准确检测和定位汽车保险丝?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM