主要思想是允许用户重新着色到基于特定墙的用户选择。
目前我已经使用cvFloodFill
实现了此功能(有助于准备掩码图像),这可以帮助我更改墙的相对HSV
值,以便我可以保留边缘。但这个解决方案的问题在于它适用于颜色,所有墙壁都重新粉刷而不是用户选择的单墙。
我也尝试过canny边缘检测,但它只能检测边缘但无法将其转换为区域。
请在下面找到我目前用于重绘功能的代码
准备面具
cvFloodFill(mask, new CvPoint(295, 75), new CvScalar(255, 255, 255,0), cvScalarAll(1), cvScalarAll(1), null, 4, null);
拆分频道
cvSplit(hsvImage, hChannel, sChannel, vChannel, null);
更改颜色
cvAddS(vChannel, new CvScalar(255*(0.76-0.40),0,0,0), vChannel, mask);
我们如何从图像中检测边缘和相应区域。
我正在寻找除opencv
之外的解决方案,但iPhone和Android应该是可行的
修改
我可以使用以下步骤
获得如下图所示的结果cvCvtColor(image, gray, CV_BGR2GRAY);
cvSmooth(gray,smooth,CV_GAUSSIAN,7,7,0,0);
cvCanny(smooth, canny, 10, 250, 5);
这个输出有两个问题,不知道如何解决它们 靠近边缘靠近 2.删除小边
答案 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的示例文件,只需运行它就可以得到这个结果:
您可以让用户在屏幕上绘图以区分每面墙。 然后,如果你想要更精确的东西,你可以勾勒出这些区域(不要触及其他线条):
TADA! :
通过一些工作,您可以使用户友好(取消最后一行,连接区域等...)
希望有所帮助!
答案 2 :(得分:3)
我认为您可以使用Canny Edge Detection
算法来查找边缘差异。一些链接
我希望这可以帮到你。感谢。
答案 3 :(得分:2)
这是一些OpenCV4Android代码,用于查找名为Mat
的{{1}}中的最大轮廓,我们假设它位于RGBA颜色空间中。要查找轮廓,首先需要对图像进行阈值或二值化(转换为黑白)。在阈值处理之前在图像上使用高斯模糊减少了产生的小轮廓的数量。模糊和阈值的大小参数必须是奇数;你可以玩,找到哪个值给出最好的结果(这里,我已经使用了7)。
image
答案 4 :(得分:0)
此输出有两个问题,不确定如何解决它们1.靠近边缘近距离2.删除小边
您可以使用形态学操作来闭合边缘。寻找扩张和关闭运营商。
您可以通过标记来删除小边。计算每个区域中的像素数(连接的白色像素)。删除像素数小于某个阈值的任何区域。我不使用opencv,但是大多数库都有一个标签功能,可以创建一个图像,其中单个颜色的每组触摸像素在输出图像中被赋予唯一的颜色。