我之前曾问过一个问题Marking an interest point in an image using c++ 。我使用相同的解决方案并使用自适应阈值和Blob Detection Algorithm(增长区域)获得所需的点。我有原始的源图,我想检测中心的矩形区域
。但是在我使用算法之后,我得到了这样的结果(如果你在一个新标签中打开它,细节是可见的)
除了矩形区域外,还可以看到明亮的日光照射点。我使用了双边滤波但仍然无法检测到矩形区域。但是这个算法适用于夜间图像,背景比预期的更暗。
有人可以建议我使用一些修改的相同算法是否足够,或者是否有其他有效方法可供使用。
由于
答案 0 :(得分:4)
使用 blur &的简单组合 threshold 我设法得到了这个结果(调整大小以供查看):
之后,应用侵蚀& the squares.cpp technique(来自OpenCV的示例)输出:
这几乎是你要找的结果:成功检测到矩形的底部。您需要做的只是增加检测到的矩形(红色方块)的高度以适合您感兴趣的区域。
代码:
Mat img = imread(argv[1]);
// Blur
Mat new_img = img.clone();
medianBlur(new_img, new_img, 5);
// Perform threshold
double thres = 210;
double color = 255;
threshold(new_img, new_img, thres, color, CV_THRESH_BINARY);
imwrite("thres.png", new_img);
// Execute erosion to improve the detection
int erosion_size = 4;
Mat element = getStructuringElement(MORPH_CROSS,
Size(2 * erosion_size + 1, 2 * erosion_size + 1),
Point(erosion_size, erosion_size) );
erode(new_img, new_img, element);
imwrite("erode.png", new_img);
vector<vector<Point> > squares;
find_squares(new_img, squares);
std::cout << "squares: " << squares.size() << std::endl;
draw_squares(img, squares);
imwrite("area.png", img);
修改强>:
find_squares()
函数返回一个向量,其中包含图像中找到的所有方块。因为它在图像的每个通道上迭代,所以在您的示例中它成功检测到每个通道中的矩形区域,因此打印squares.size()
输出3
。
由于 square 可以看作是4(X,Y)坐标的向量,OpenCV将此概念表达为vector<Point>
,允许您访问坐标的X和Y部分。
现在,打印squares
会发现这些点是以逆时针方向检测到的:
1st ------ 4th
| |
| |
| |
2nd ------ 3rd
按照这个例子,很明显,如果你需要增加矩形的高度,你需要改变第1和第4点的Y:
for (int i = 0; i < squares.size(); i++)
{
for (int j = 0; j < squares[i].size(); j++)
{
// std::cout << "# " << i << " " << squares[i][j].x << ","<< squares[i][j].y << std::endl;
if (j == 0 || j == 3)
squares[i][j].y = 0;
}
}
答案 1 :(得分:1)
在上面显示的图像中,我建议
正常的阈值处理操作应该可以正常工作或
按行链式代码“计算”或
在直方图中找到渐变。
还有很多其他解决方案。 如果这是一致的话,我会考虑减去背景阴影。