简体   繁体   中英

How to accurately detect and localize car fuse?

Currently I'm working on a project, where I need to measure the width of car fuse wire. In order to achieve that I need to detect and localize the fuse on the image. fuse_image

My plan is to find bounding rectangle region with the fuse and then search for a wire contours in fixed position of that region. fuse_contours

I have already tried ORB, BRISK feature based template matching, but the results were not acceptable. Maybe anyone can suggest some possible methods to solve this task?

We can start the problem by applying Canny operation to see the features of the image. Result is:

在此处输入图像描述

The aim is to calculate the width. Therefore we only need the left and right outer length of the image. We don't need inner lines. To remove the inner features we can smooth the image.

在此处输入图像描述

How do we accurately calculate the width? What part of the features can we take as an reference? If we consider the base? The base features are:

在此处输入图像描述

How do we find the base feature coordinates?

  • Blue point is the one with the highest y coordinate value

  • Red point is the one with the highest x coordinate value

For all detected line coordinates, we need to find the highest y coordinate value with the corresponding x coordinate value. We need to find the highest x coordinate value with the corresponding y value.

For detecting line coordinates we can use fast line detector . Result will be:

在此处输入图像描述

We can calculate the euclidian-distance, which will be: 146.49 pixel

The idea is based on the finding the base and then calculating the euclidean-distance.


Update

The orientation of the fuse can be random.

First, we need to get the fuse part of the image.

在此处输入图像描述

Second, we need to get the canny features (or any other filtering method)

在此处输入图像描述

At this point we need to find the left (blue-dot) and right (red-dot) part of the fuse:

在此处输入图像描述

If we connect them:

在此处输入图像描述

We will have an approximate length of the fuse.

So How do we find the left and right parts of the fuse?

  • Finding left part:

    •  1. From the current x1, x2 tuples 2. If min(x1, x2) < x_min 3. x_min = min(x1, x2)
  • Finding right part:

    •  1. From the current x1, x2 tuples 2. If max(x1, x2) > x_max 3. x_max = max(x1, x2)

This is my idea for approaching the problem. You can modify for better results.


Code:

# 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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