为什么 Opencv/Hough 变换找不到整行?

问题描述

我完成了一个关于寻找车道的 OpenCv 教程,我正在尝试应用它来寻找地板上的一块胶带。我运行了代码并设置了感兴趣的区域,但它只找到了磁带的几个边缘。我认为这与厚度有关,但我不是 100% 确定。任何帮助将不胜感激。

Track

Track 2

Track 3

import cv2
import numpy as np
import matplotlib.pyplot as plt

def canny(image):
    gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    blur = cv2.GaussianBlur(gray,(5,5),0)
    canny = cv2.Canny(blur,50,150)
    return canny

def display_lines(image,lines):
    line_image = np.zeros_like(image)
    if lines is not None:
        for line in lines:
            x1,y1,x2,y2 = line.reshape(4)
            cv2.line(line_image,(x1,y1),(x2,y2),(255,0),10)
    return line_image

def region_of_interest(image):
    height = image.shape[0]
    polygons = np.array([
        [(200,height),(400,(355,0)]
        ])
    mask = np.zeros_like(image)
    cv2.fillpoly(mask,polygons,255)
    masked_image = cv2.bitwise_and(image,mask)
    return masked_image

image = cv2.imread('tape3.jpg')
lane_image = np.copy(image)
canny_image = canny(image)
cropped_image = region_of_interest(canny_image)
lines = cv2.houghlinesp(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=40,maxLineGap=5)
line_image = display_lines(lane_image,lines)
combo_image = cv2.addWeighted(lane_image,0.8,line_image,1,1)
# cv2 print image
print(region_of_interest(image))
cv2.imshow("result",combo_image)
cv2.waitKey(0)

解决方法

这可能无法回答您最初的问题,但这可能是实现您正在寻找的目标的另一种方式。

我首先对图像的灰度进行阈值处理以尝试隔离磁带

enter image description here

然后我用opencv的findContours得到每个白色blob的分割点

enter image description here

我使用的阈值方法对光线和阴影很敏感,因此如果这不是可行的约束条件,您可能需要找到其他一些阈值方法。如果需要考虑不同颜色的胶带,您可以关闭其他值的阈值(分别转换为 HSV 或 LAB 以及关闭 H 或 B 通道的阈值以寻找红色)。

编辑:

如果您仍想使用 HoughLinesP,这里有一个包含您的图片的工作示例。

首先我应用了 canny:

enter image description here

然后我使用了 HoughLinesP 函数:

enter image description here

我以前从未使用过 houghLinesP,所以我不确定潜在的陷阱,但它似乎有效,尽管它实际上用这些参数创建了一堆重叠的线,你必须使用它位。

相关代码:

# canny
canned = cv2.Canny(gray,591,269);

# dilate
kernel = np.ones((3,3),np.uint8);
canned = cv2.dilate(canned,kernel,iterations = 1);

# hough
lines = cv2.HoughLinesP(canned,rho = 1,theta = 1*np.pi/180,threshold = 30,minLineLength = 10,maxLineGap = 20);

编辑 2:

我查看了该函数的文档,第三个参数 (theta) 指的是角度分辨率。我认为它可能在您的代码中不起作用,因为您没有在 Canny 之后对图像运行扩张。使用 1 度搜索分辨率,不难想象我们可能会错过 Canny 返回的非常细的线。通过使用更大的内核(或多次扩张),甚至可能比我在示例中更值得扩张这些线。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...