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

Jig*_*ekh 16 iphone android 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);

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

我正在寻找解决方案,除了opencviPhone和Android 之外,应该是可能的

样本图片

编辑

我可以使用以下步骤在下面的图像中获得一些结果

cvCvtColor(image, gray, CV_BGR2GRAY);   
cvSmooth(gray,smooth,CV_GAUSSIAN,7,7,0,0);
cvCanny(smooth, canny, 10, 250, 5);
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

Tho*_*hom 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 );
 }
Run Code Online (Sandbox Code Playgroud)

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

您可能必须更改"findContours" 链接中的不同参数.您还需要在轮廓检测之前平滑输入图像,以避免对细节或纹理感到烦恼.

希望有所帮助,托马斯

  • 我认为首先进行Canny边缘检测然后将其用作findContours的输入是一个好主意,但无论如何它都可能有用. (2认同)

Tho*_*hom 8

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

流域只有短线关键点

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

更好的轮廓

还有TADA!:

相当不错的结果;)

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

希望有所帮助!