我正在开发一个项目,通过使用OpenCV 3.3来处理下面的大理石平板图像 .
我正在研究的几个具有不同大理石纹理和尺寸的样品可以在https://1drv.ms/f/s!AjoScZ1lKToFheM6wmamv45R7zHwaQ找到
要求是:
-
将大理石板与背景分开并移除背景(填充白色),这样只显示平板 .
-
计算板坯的面积(从相机到大理石板的距离以及镜头的参数已知)
我使用的策略是:1)找到大理石板的轮廓,2)去除不在轮廓内的部分,3)获得轮廓的面积大小,4)计算其物理面积 .
板坯的轮廓如下图所示为红色(这是手工完成的) .
我尝试了几种方法来找到图像中的板坯轮廓,但由于复杂的背景和大理石的丰富质感,未能获得令人满意的结果 .
我正在使用的处理逻辑是:将图像转换为灰色并模糊它并使用Canny查找边缘,然后使用findContours查找轮廓,以下是代码:
Mat img = imread('test2.jpg', 1);
Mat gray, edge;
cvtColor(img, gray, COLOR_BGR2GRAY);
blur(gray, gray, Size(3, 3));
Canny(gray, edge, 50, 200, 3);
vector<vector<Point> > contours;
vector<Vec4i> lines;
findContours(edge, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
cout << "Number of contours detected: " << contours.size() << endl;
vector<Vec4i> hierarchy;
for (int i = 0; i < contours.size(); i++)
{
drawContours(img, contours, i, Scalar(0, 0, 255), 1, 8, hierarchy, 0, Point());
}
imshow("Output", img);
我试图调整模糊和Canny参数的几十种组合,但仍然失败 . 我还尝试使用HoughLinesP来找到具有几组不同参数的板坯边缘,但也可以这样做 .
我是计算机视觉的新手,我现在的问题是:
-
我是否采用错误的方式或策略来寻找板坯轮廓?可以有更好的算法或组合吗?或者我是否需要专注于调整Canny / findContours / HoughLinesP算法的参数?
-
由于背景复杂,这种图像真的难以处理吗?
我愿意接受任何有助于我完成目标的建议 . 先感谢您 .
1 回答
你可以考虑的技巧
模板匹配,您可能需要为不同的大理石准备大量模板(光照条件,旋转等)
训练分类器区域提议,只有在其他解决方案失败时才采用此解决方案(此解决方案可能是最强大的解决方案,但也是最冗长的解决方案)
由于你只有10~20种大理石板,我认为解决方案1是一个良好的开端 .
}
}
您将需要为此解决方案准备10~20张图像,更喜欢存在大多数匹配点的图像来定位您的大理石板 . 如果性能是一个问题,降低图像的分辨率,您不需要大图像来获得结果 .
完整代码放在github .
ps:我不知道你项目的细节,如果只有10~20种大理石板,它们都有很好的追踪功能,你不需要3个月就可以解决它(但你可以告诉你的老板/客户你需要3个月:),有时更好的表现只会导致更多的家务,但不是更多的钱) .