如何优化不同图像的线条检测?

问题描述

一点背景:
我试图检测立方体的消失点,然后将具有相同消失点的线组合在一起
我在边缘/线检测阶段遇到问题。


例如:

Original Image

Desired Output


  1. 问题是我通过对参数 [thresholding,canny,Hough_Line] 稍作修改就获得了霍夫线所需的输出
  2. 例如,我优化了这个特定图像的参数 Input1 ,我得到了所需的输出
  3. 但如果我对 Different Image 应用相同的值,那么同一行会检测到很多重复的行。
  4. 我已经编写了一个过滤算法来连接相似的行。但是这里检测到的线具有非常不同的 [rho,theta],我必须大量增加过滤算法的阈值,这最终会影响其他线。
  5. 我认为问题是因为在边缘检测过程中线断裂,因此被解释为不同的线,我不确定。
  6. 我尝试在预处理中使用膨胀和腐蚀,但我遇到了同样的问题,即不同图像的内核大小不同,所以我注释掉了那部分。
  7. 我可以为不同的图像调整参数,但这里的差异非常大,所以我觉得这里的问题出在我的预处理功能上。
  8. 我已经粘贴了我认为与这个问题相关的函数以避免混乱,如果有人需要完整的我可以分享 github 链接

代码

def pre_processing(path):

'''
    pre_processing:

            Param  : 
                path : Path for the image to processed.

            Return :
                edge_image : NumpyArray that stores the grayscale values of 
                             Input image.
'''

image = cv2.imread(path)

image = cv2.bitwise_not(image)

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

# print("Gray:",gray,"\n")
# plt.imshow(gray,cmap='gray')
# plt.show()

blur = cv2.GaussianBlur(gray,(5,5),0)

# print("blur:",blur,"\n")
# plt.imshow(blur,cmap='gray')
# plt.show()

ret,thresh = cv2.threshold(blur,50,255,cv2.THRESH_BINARY)



return thresh    

def filter_threshold(indexes,filter_indexes,filt_rho = 20,filt_theta= 0.2):

'''
    Filter_threshold:

        Param:
            indexes :  The raw [rho,theta] values with duplicates for same line.
            filter_indexes : A list to store indexes of unique lines.
            filt_rho : acceptable rho ranges to group lines.
            filt_theta  : acceptable theta ranges to group lines.

        Return :  
            filter_indexes : Dataset that stores filtered(duplicate values) 
                             (rho,theta) values.
'''
a = 0

rho = indexes[a][0]
theta = indexes[a][1]
unfilt_indexes = []

for j in range(len(indexes)):

    
    if rho<0:
        rho *= -1
        theta -= np.pi

    curr_rho = indexes[j][0]
    curr_theta = indexes[j][1]

    if curr_rho<0:
        curr_rho *= -1
        curr_theta -= np.pi

    if a == j:
        pass
    elif (0 <= abs(curr_rho-rho) <filt_rho) and (0 <= abs(curr_theta-theta)<filt_theta):

        pass

    else:
        unfilt_indexes.append([curr_rho,curr_theta])

filter_indexes.append([rho,theta])

if len(unfilt_indexes)>0:
    x = filter_threshold(unfilt_indexes,filter_indexes)

return filter_indexes

path = "/work/cubes/4.jpg"
thresh = pre_processing(path)

edge_image = cv2.Canny(thresh,100,200)

hough_threshold = 40
lines = cv2.houghlines(edge_image,1,(np.pi/180),hough_threshold)

filtered_indexes = []
filtered_indexes = filter_threshold(lines,filtered_indexes,20,0.2)

解决方法

当您拥有如此清晰的图像且线段很容易跟踪时,使用 Hough 或 LSD 之类的大锤并尝试从如此获得的混乱中检索解决方案,这有点令人难过。

另请注意,可以仅从六边形轮廓中获得消失点。

下面是通过简单轮廓检测(在不同图像上)获得的六边形。从轮廓中,您可以通过查找对齐像素的长段来分割出边。 (道格拉斯-普克是一个选项。)

enter image description here

更一般地,您可以分割出所有白色区域并为它们拟合多边形以获取边缘片段并将它们扩展到消失点。

相关问答

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