【问题标题】:Find positions of objects on the noisy image在噪声图像上查找对象的位置
【发布时间】:2018-10-12 15:30:02
【问题描述】:

我有一堆图像,我需要确定十字的位置,以便进一步转换图像和对齐过程。问题是图像非常嘈杂,而且我对计算机视觉的所有这些东西都很陌生。一般来说,我试图通过opencv和python来解决这个任务。我尝试了opencv库教程中描述的几种方法,但没有得到合适的结果。

考虑:我需要确定十字中心的确切位置(我可以手动处理像素精度)。我通过findContours 函数获得的最佳结果。我采用了code from the tutorial,我得到了:

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

random.seed(42)

img = cv.imread("sample.png")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.blur(img_gray, (3,3))

threshold = 150

dst = cv.Canny(img_gray, threshold, threshold * 2)
_, contours, hierarchy = cv.findContours(dst, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

result = np.zeros((dst.shape[0], dst.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
    color = (random.randint(0, 256), random.randint(0, 256), random.randint(0, 256))
    cv.drawContours(result, contours, i, color, 2, cv.LINE_8, hierarchy, 0)

cv.imwrite("result.png", result)

fig, ax = plt.subplots()
fig.set_size_inches(10, 10);
ax.imshow(result, interpolation='none', cmap='gray');

导致: 现在我对以下步骤感到困惑。如何定义哪个轮廓是交叉的,哪个不是?如何处理由多个轮廓组成的十字架?

真的很感激任何帮助!

【问题讨论】:

    标签: python opencv contour


    【解决方案1】:

    一种简单的方法可以确定什么是十字架,什么不是十字架提供。如果你观察到图像上的噪点没有十字架那么大。

    我还举了一个例子来说明我将如何尝试解决这样的任务。您可以尝试通过执行直方图均衡化然后使用 OTSU 阈值进行阈值化并执行阈值打开(腐蚀后膨胀)来对图像进行降噪。然后,您可以过滤掉轮廓的高度和重量的交叉点,然后计算上述标准中轮廓的每个边界框的中点。希望它有点帮助。干杯!

    例子:

    import cv2
    import numpy as np
    
    img = cv2.imread('croses.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    equ = cv2.equalizeHist(gray)
    _, thresh = cv2.threshold(equ,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    kernel = np.ones((2,2),np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
    _, contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    
    for cnt in contours:
        x,y,w,h = cv2.boundingRect(cnt)
        if w > 40 and h > 40:
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
            cv2.circle(img,(int(x+(w/2)), int(y+(h/2))),3,(0,0,255),-1)
    
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果:

    【讨论】:

    • 完美运行!我会试着弄清楚这里发生了什么。谢谢!顺便说一句,您是否建议将标记的类型从交叉更改为其他更好识别的东西?
    • 这些十字架是你自己做的吗?也许您可以绘制矩形?...您可以制定排序 cv2.contourArea() 的标准并使用 cv2.moments() 找到中心?因为我不知道这个任务的确切应用,所以不能给出一个好主意。
    • 是的,我自己做十字架。以前,当我手动执行此任务时(我的意思是搜索十字中心),十字非常好 - 它们具有小特征,这就是我能够非常准确地找到中心的原因。我认为矩形比十字架更糟糕。我想到了一些更复杂的东西,并使用模板匹配算法而不是边界框。如果这对您有帮助的话,可以通过电子束光刻技术制作十字架。
    • 你可以尝试模板匹配,但它需要更多的工作,而且根据我的经验(也许其他人有更好的)并没有像纯数学概念算法那样好的结果。如果您想要更复杂的方式,我认为更好的方法是特征匹配。但我对问题的看法是,如果“简单”的工作并不复杂。您可以尝试制作 X 而不是 +。这样,如果 X“腿”之一较短,您将获得更好的边界框。但是,您可以改进对精确交叉点的搜索而不是计算它;)
    猜你喜欢
    • 2022-01-27
    • 2013-02-13
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2018-11-09
    相关资源
    最近更新 更多