如何检测墙的长边准备面具和重新着色

时间:2013-04-19 08:47:50

标签: android iphone opencv image-processing edge-detection

主要思想是允许用户重新着色到基于特定墙的用户选择。 目前我已经使用cvFloodFill实现了此功能(有助于准备掩码图像),这可以帮助我更改墙的相对HSV值,以便我可以保留边缘。但这个解决方案的问题在于它适用于颜色,所有墙壁都重新粉刷而不是用户选择的单墙。

我也尝试过canny边缘检测,但它只能检测边缘但无法将其转换为区域。

请在下面找到我目前用于重绘功能的代码

  1. 准备面具

    cvFloodFill(mask, new CvPoint(295, 75), new CvScalar(255, 255, 255,0), cvScalarAll(1), cvScalarAll(1), null, 4, null);

  2. 拆分频道

    cvSplit(hsvImage, hChannel, sChannel, vChannel, null);

  3. 更改颜色

    cvAddS(vChannel, new CvScalar(255*(0.76-0.40),0,0,0), vChannel, mask);

  4. 我们如何从图像中检测边缘和相应区域。

    我正在寻找除opencv之外的解决方案,但iPhone和Android应该是可行的

    Sample image

    修改

    我可以使用以下步骤

    获得如下图所示的结果
    cvCvtColor(image, gray, CV_BGR2GRAY);   
    cvSmooth(gray,smooth,CV_GAUSSIAN,7,7,0,0);
    cvCanny(smooth, canny, 10, 250, 5);
    

    这个输出有两个问题,不知道如何解决它们 靠近边缘靠近 2.删除小边

    enter image description here

5 个答案:

答案 0 :(得分:10)

您可以尝试以下方式:

 Mat imageOut = Mat::zeros(imageIn.rows, imageIn.cols, CV_8UC3);

 vector<vector<Point> > contours;
 vector<Vec4i> hierarchy;    

 findContours( imageIn, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
 for( int idx = 0; idx >= 0; idx = hierarchy[idx][0] )
 {
     Scalar color( rand()&255, rand()&255, rand()&255 );
     drawContours( imageOut, contours, idx, color, CV_FILLED, 8, hierarchy );
 }

它应该以不同的颜色绘制墙壁。如果它有效,这意味着在“层次结构”中,每个墙都被识别为轮廓,然后您必须找出用户在触摸屏上选择的那个并进行颜色调整处理。

您可能需要更改“findContours”link中的不同参数。 您还需要在轮廓检测之前平滑输入图像,以避免对细节或纹理感到恼火。

希望有所帮助, 托马斯

答案 1 :(得分:8)

我想我可能会为你找到解决方案! 在OpenCV中有一个名为watershed.cpp的示例文件,只需运行它就可以得到这个结果:

Watershed with only short line keypoints

您可以让用户在屏幕上绘图以区分每面墙。 然后,如果你想要更精确的东西,你可以勾勒出这些区域(不要触及其他线条):

Better outline

TADA! :

Pretty good result ;)

通过一些工作,您可以使用户友好(取消最后一行,连接区域等...)

希望有所帮助!

答案 2 :(得分:3)

我认为您可以使用Canny Edge Detection算法来查找边缘差异。一些链接

  1. StackOverFlow
  2. StackOverFlow
  3. OpenCV QA
  4. OpenCV
  5. Native Tutorial
  6. 我希望这可以帮到你。感谢。

答案 3 :(得分:2)

这是一些OpenCV4Android代码,用于查找名为Mat的{​​{1}}中的最大轮廓,我们假设它位于RGBA颜色空间中。要查找轮廓,首先需要对图像进行阈值或二值化(转换为黑白)。在阈值处理之前在图像上使用高斯模糊减少了产生的小轮廓的数量。模糊和阈值的大小参数必须是奇数;你可以玩,找到哪个值给出最好的结果(这里,我已经使用了7)。

image

答案 4 :(得分:0)

  

此输出有两个问题,不确定如何解决它们1.靠近边缘近距离2.删除小边

  1. 您可以使用形态学操作来闭合边缘。寻找扩张和关闭运营商。

  2. 您可以通过标记来删除小边。计算每个区域中的像素数(连接的白色像素)。删除像素数小于某个阈值的任何区域。我不使用opencv,但是大多数库都有一个标签功能,可以创建一个图像,其中单个颜色的每组触摸像素在输出图像中被赋予唯一的颜色。