如何使用OpenCV检测测试条?

如何使用OpenCV检测测试条?,opencv,computer-vision,object-detection,object-recognition,Opencv,Computer Vision,Object Detection,Object Recognition,我是计算机视觉的新手,我正在尝试检测此图像中的所有测试条: 我想要得到的结果是: 我认为这应该很容易,因为所有的目标对象都是矩形的,并且具有固定的纵横比。但我不知道应该使用哪种算法或函数 我在OpenCV中尝试了边缘检测和2D特征检测示例,但结果并不理想。我应该如何检测这些相似但差异很小的物体 更新: 测试条的颜色可以不同,当然,结果线的阴影也可以不同。但它们都有相同的参考线,如图所示: 我不知道该如何描述这些简单的物体检测功能,因为我在网上找到的大多数例子都是针对复杂的物体,如建筑物或人

我是计算机视觉的新手,我正在尝试检测此图像中的所有测试条:

我想要得到的结果是:

我认为这应该很容易,因为所有的目标对象都是矩形的,并且具有固定的纵横比。但我不知道应该使用哪种算法或函数

我在OpenCV中尝试了边缘检测和2D特征检测示例,但结果并不理想。我应该如何检测这些相似但差异很小的物体

更新:

测试条的颜色可以不同,当然,结果线的阴影也可以不同。但它们都有相同的参考线,如图所示:


我不知道该如何描述这些简单的物体检测功能,因为我在网上找到的大多数例子都是针对复杂的物体,如建筑物或人脸

解决方案并不精确,但它提供了一个良好的起点。不过,您必须使用这些参数。如果您使用一些阈值方法对条带进行分区,然后像@api55所提到的那样单独应用hough线,这将对您有很大帮助

这是我得到的结果

代码

import cv2
import numpy as np

# read image
img = cv2.imread('KbxN6.jpg')
# filter it
img = cv2.GaussianBlur(img, (11, 11), 0)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# get edges using laplacian
laplacian_val = cv2.Laplacian(gray_img, cv2.CV_32F)

# lap_img = np.zeros_like(laplacian_val, dtype=np.float32)
# cv2.normalize(laplacian_val, lap_img, 1, 255, cv2.NORM_MINMAX)
# cv2.imwrite('laplacian_val.jpg', lap_img)

# apply threshold to edges
ret, laplacian_th = cv2.threshold(laplacian_val, thresh=2, maxval=255, type=cv2.THRESH_BINARY)
# filter out salt and pepper noise
laplacian_med = cv2.medianBlur(laplacian_th, 5)
# cv2.imwrite('laplacian_blur.jpg', laplacian_med)
laplacian_fin = np.array(laplacian_med, dtype=np.uint8)

# get lines in the filtered laplacian using Hough lines
lines = cv2.HoughLines(laplacian_fin,1,np.pi/180,480)
for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))
    # overlay line on original image
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

# cv2.imwrite('processed.jpg', img)
# cv2.imshow('Window', img)
# cv2.waitKey(0)

这个解决方案并不精确,但它提供了一个很好的起点。不过,您必须使用这些参数。如果您使用一些阈值方法对条带进行分区,然后像@api55所提到的那样单独应用hough线,这将对您有很大帮助

这是我得到的结果

代码

import cv2
import numpy as np

# read image
img = cv2.imread('KbxN6.jpg')
# filter it
img = cv2.GaussianBlur(img, (11, 11), 0)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# get edges using laplacian
laplacian_val = cv2.Laplacian(gray_img, cv2.CV_32F)

# lap_img = np.zeros_like(laplacian_val, dtype=np.float32)
# cv2.normalize(laplacian_val, lap_img, 1, 255, cv2.NORM_MINMAX)
# cv2.imwrite('laplacian_val.jpg', lap_img)

# apply threshold to edges
ret, laplacian_th = cv2.threshold(laplacian_val, thresh=2, maxval=255, type=cv2.THRESH_BINARY)
# filter out salt and pepper noise
laplacian_med = cv2.medianBlur(laplacian_th, 5)
# cv2.imwrite('laplacian_blur.jpg', laplacian_med)
laplacian_fin = np.array(laplacian_med, dtype=np.uint8)

# get lines in the filtered laplacian using Hough lines
lines = cv2.HoughLines(laplacian_fin,1,np.pi/180,480)
for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))
    # overlay line on original image
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

# cv2.imwrite('processed.jpg', img)
# cv2.imshow('Window', img)
# cv2.waitKey(0)

这是另一种解决方案,将函数findcontours与canny边缘检测结合使用。代码是基于这个非常轻微


结果:


我想可以通过调整以下参数进行改进:

  • 图像调整宽度
  • 链约无()

它也可用于过滤小轮廓或合并彼此接近的轮廓。

这是一种替代解决方案,使用FindCountors函数结合canny边缘检测。代码是基于这个非常轻微


结果:


我想可以通过调整以下参数进行改进:

  • 图像调整宽度
  • 链约无()

它也可以用于过滤小轮廓或合并彼此接近的轮廓。

仅一些建议,1)尝试消除背景(阈值)。2) 寻找直线,也许可以帮上忙,3)找到这些直线的交点4)用这些交点创建矩形。奖励)您可以尝试将每个对象(轮廓)从其余对象(其余=黑色)中分离出来,并在没有任何其他可能影响结果的数据的情况下逐个分析它们。您是否还有其他图像可以查看它们的变化?@MarkSetchell请查看我的更新可以使用不同颜色的背景,例如蓝色?背景是否总是平淡无奇的,或者有时可能是图案?条带的数量是否固定?或者最多可以有多少条?敏?条纹是否总是水平的?@MarkSetchell背景可以是不同的颜色。实际上,我可以选择背景的颜色/样式,如果这样可以更容易地进行检测的话。我希望条带的数量无关紧要,但我可以决定条带的数量,如果这能使检测更容易的话。至于条纹的方向,我希望它不必排得很好,但整体水平的ish是可以接受的。只是一些建议,1)尝试消除背景(阈值)。2) 寻找直线,也许可以帮上忙,3)找到这些直线的交点4)用这些交点创建矩形。奖励)您可以尝试将每个对象(轮廓)从其余对象(其余=黑色)中分离出来,并在没有任何其他可能影响结果的数据的情况下逐个分析它们。您是否还有其他图像可以查看它们的变化?@MarkSetchell请查看我的更新可以使用不同颜色的背景,例如蓝色?背景是否总是平淡无奇的,或者有时可能是图案?条带的数量是否固定?或者最多可以有多少条?敏?条纹是否总是水平的?@MarkSetchell背景可以是不同的颜色。实际上,我可以选择背景的颜色/样式,如果这样可以更容易地进行检测的话。我希望条带的数量无关紧要,但我可以决定条带的数量,如果这能使检测更容易的话。至于条带的方向,我希望它不必排得很好,但整体水平的ish是可以接受的。