我需要使用OpenCV在图像中找到正方形(在matlab或其他任何问题上都没问题,通常我期望的是一些想法)。 >

我需要在上面的图像中准确找到那些彩色的正方形(而不是白色的长条)。
我使用了通用方法(OpenCV样本随附),即在所有颜色平面中找到轮廓,对其进行近似并检查元素数= 4。在某种程度上可以检测到很少的正方形,尤其是深色的正方形。
我要做的下一步是预测。即这种安排是固定的。因此,如果获得一些,我可以预测剩余的。它还可以进一步扩展。但是准确度很差。

但是我觉得这里的预测不是一个好方法,它并不总是提供第一步给出的准确答案。需要:

1)还有其他更好的方法可以更准确地检测这些正方形吗?还是多种方法?

重要的一点是,时间在这里不是问题。算法可能很慢,没关系。但是准确性是主要标准。

有时,图像可能会更加模糊。

我面临的主要问题之一是某些正方形的颜色与背景颜色几乎相似(请检查第3列的第一和第二个正方形)。

在此先感谢

UPDATE:

以下是我得到的最大准确结果:



当然,结果图像的大小会稍作调整。

UPDATE 2: / a / 7526/818

评论

你的背景总是发白吗?

我的想法是计算饱和度并为饱和度img设置阈值,但使用您的示例效果不佳(将饱和度计算为max(RG,RB,GB)。如果所有图像都具有相同的图案(白色长条纹旁边有正方形),则应考虑查找最简单的位(例如彩色正方形或白色条纹),以推断出其他图像的可能位置方块并...找到一种方法来检查它们是否真的存在。坚韧而有趣!您能提供更多图像吗?

好吧,我认为这不应该移动。

您可以提供更多图片吗?还有,这是什么东西?

OP需要回答一些问题。也许不需要白色背景。那光怎么了?会那么糟糕吗?这些对我来说似乎只是不必要的复杂性。

#1 楼

首次尝试使用Matlab:

im = imread('squares.jpg');
im2 = rgb2gray(im);

se = strel('disk', 15);

for i = 1:16;
    t = 60+i*5; % try out a range of bw thresholds to see what works best
    labelled = bwlabel(im2>t); % label regions in the BW image
    closed = imclose(labelled, se); % close small regions
    cleared = imclearborder(~closed,4); % clear regions touching the border
    subplot(4,4,i); 
    imshow(cleared); 
    title(['T = ' num2str(t)]);
end


在以下区域产生结果:



,选择导致最高区域数(T = 120)的阈值将已经给出7个正确位置,一些合并位置,一个假阳性和两个假阴性。

这是一个相当简单的尝试但我认为这表明该方法可行。添加一些东西来分解拉长的区域,或者分别对每个颜色通道进行此操作只是您可以在此方面进行改进的几件事。测试图像。

#2 楼

我尝试了其他方法来改善相关结果。下面的解决方案是基于始终在步骤1中检测到第一个正方形(橙色)的假设。由于与背景相比具有较高的对比色,因此它是实用的。甚至我所讨论的结果也能正确检测到它

步骤1:找到尽可能多的正方形

我将图像拆分为R,G,B,H,S, V平面并将图像阈值设置为不同的阈值(例如25的倍数)。对于每个图像,我都在其中找到了正方形,并将它们放在“蒙版图像”上。我还找到了正方形的平均高度和宽度。

遮罩图像(共检测到7/12个正方形):



步骤2:形成正方形网格

接下来,我在蒙版图像中找到了这些正方形的质心。对它们进行排序,找到第一个正方形(橙色)的质心。通过仔细分析,我们可以看到两个正方形之间的间隙在水平和垂直方向上都是正方形。因此,这样,我像下面那样制作了一个正方形网格,并将其命名为Ideal_squares(这只是一个名称,并不意味着这是我需要的输出):

ideal_squares:



步骤3:重新映射ideal_image

现在我们有了ideal_squares重心和原始重心。我从ideal_centroids中找到了每个原始质心的正确匹配项(通过计算它们之间的欧几里得距离)。然后,我使用Scipy interpolate.griddata进行插值,并根据质心值重新映射了Ideal_image(这与在这些Q&A中所做的变形几乎相同:如何消除数独正方形中的凸度缺陷和OpenCV中的图像变换)。所以下面是我得到的输出:

输出: />


现在您可以看到所有正方形都被检测到,但是存在以下提到的问题:

问题:

查看步骤3的输出,即正方形网格的重新映射图像。除两个中心正方形外,所有其他正方形均被裁剪。这是与此重新映射相关的问题。我不确定scipy.interpolate.griddata()或cv2.remap()是哪里出了问题。我以为整个形象会变形,但事实并非如此。它仅扭曲我们给出的质心内的图像。如果我可以纠正这一点,输出将正常。

所以,如果有人知道一个好主意,那就欢迎您!!!!

#3 楼

注意:此方法将非常慢。

生成看起来像理想对象轮廓的蒙版。与此类似:



然后将遮罩滑动(定位,缩放,旋转)在图像上,并将其与真实图像的轮廓匹配(也许有些模糊为了获得更柔和的响应)以计算它们之间的相似度,具有最高相似响应的(位置,比例,旋转)应为真实对象的(位置,比例,旋转)。

该方法因为它考虑了整个对象,所以不介意将正方形混合到对象的背景或什至部分遮挡中。

我个人已经成功地使用了这种方法来跟踪鼠标的鼻子和胡须,但是我有一些推测,例如它接近最近的已知位置等。但是我认为您可以降低搜索空间通过应用一些假设,例如:相机中物体的可能大小,距中心的距离或旋转角度小于10度等。

#4 楼

步骤1:无论您在B,G,R,H,S,V平面中进行分析得到的最终最终二进制图像是什么,在该图像中都要进行斑点计数算法。

步骤2:找到最大的斑点根据面积或轮廓长度。由于您的斑点主要是平行四边形类型,因此面积或轮廓都可以。

步骤3:使用最大的斑点(因为最大的斑点是类似于您的现实世界方块的最佳斑点),请尝试查找斑点的方向...这可以通过拟合最合适的矩形获得,也可以得到角点...获得连接它们的直线的斜率(水平和垂直方向)。

第4步:一旦获得两个斜率,就绘制了一条穿过Blob轴的直线。对于轴,您可以平均拐角点,也可以使用质心(质心)...我会计算拐角点的平均值...

步骤5:由于在每个水平和垂直方向方向,间距是相等的(理想情况下,水平间距和垂直间距也应相等,因为它来自您理想的方形图片,但我们不会假设它。。)只需要找到其他平行四边形的可能质心底线:如果可以完美地检测到任何一个正方形,则可以制作整个网格。沿最大斑点的水平轴保持标记中心的间隔为2H(H =最大斑点的水平宽度),沿垂直于斑点的垂直轴的间隔为2V(V =最大斑点的垂直高度)。

一些图片要支持




评论


$ \ begingroup $
+1-如果可以实现,那就太好了。
$ \ endgroup $
– Abid Rahman K
2013年1月15日19:29

$ \ begingroup $
@AbidRahmanK这不是StackExchange的目的。问题->答案。否则,这最终将成为招聘会。
$ \ endgroup $
– JanKrüger
16年7月4日在7:28

#5 楼


这种安排是固定的


我真的不知道您以前做过哪种预测,但是您是否尝试过将白色长条作为根源。然后(如果3列正方形大小相等),则可以检测正方形的高度(两个条带之间的距离),并且可以检测图像中的最大和最小面积(高度和宽度)。

然后,尝试检测整个正方形内最常见的颜色并将其设置为“非正方形”区域。其余的应该是您要寻找的正方形。

评论


$ \ begingroup $
我用轮廓法发现了3-4个正方形。然后得到每个正方形的高度和宽度。然后检查检测到的正方形之间的间隙,并假设它们之间的间隙是否大到足以容纳另一个正方形。那是我所做的预测。
$ \ endgroup $
– Abid Rahman K
2012年10月4日上午10:05

$ \ begingroup $
一些正方形的颜色与背景颜色几乎相似。因此,按照您的方法,它们也将被视为非正方形区域。
$ \ endgroup $
– Abid Rahman K
2012年10月4日10:06

$ \ begingroup $
也许您可以尝试在每列上绘制一条曲线,其中x轴为图像中的高度(以像素为单位),y轴为强度。然后,您可以尝试使用导数形式找到一些切削刃。
$ \ endgroup $
– Antonin Duroy
2012年10月4日上午10:25

$ \ begingroup $
就是边缘检测本身,对不对?我试过了,但是没有得到很好的结果。
$ \ endgroup $
– Abid Rahman K
2012年10月4日上午10:27

$ \ begingroup $
是的,但是您可以亲自了解失败的原因,并可能隔离出图中一些有趣的区域。顺便说一句,如果您找到解决问题的有用技巧,请发布它们。祝您研究顺利
$ \ endgroup $
– Antonin Duroy
2012年10月4日,11:36

#6 楼

我建议使用霍夫变换,这是一种用于查找简单参数形状的非常强大的算法,例如线条,圆圈等。检测线条最适合您的情况。至少可以找到白色长条的侧面。然后,使用任何角点提取器算法(Harris甚至SIFT或SURF),您都可以沿着这些直线找到角点,即使使用正方形的等距间距也是如此。

#7 楼

我使用opencv,python尝试了此问题。
方法涉及根据颜色对图像进行遮罩,然后找到合适的轮廓。

代码: https://github.com/rbhambriiit/computer_vision / blob / master / find_color_box

[缺少1个框,但是应该通过调整遮罩功能来实现]