排除或跳过图像角落的轮廓

Excluding or skipping contrours in the corners of image

我在玻璃下安装了一个摄像头,使用红外线来检测物体。我可以找到轮廓并使用以下代码绘制它们(我只是在网上找到一些示例并根据需要进行了修改,所以我根本不是高手!)。

using namespace cv;

cvtColor(mat, mat, COLOR_BGR2GRAY);
blur(mat, mat, Size(3,3));

erode(mat, mat, NULL, Point(-1,-1), 2);
dilate(mat, mat, NULL, Point(-1,-1), 2);
Canny(mat, mat, 100, 200);

auto contours = std::vector<std::vector<Point>>();
auto hierarchy = std::vector<Vec4i>();
findContours(mat, contours, hierarchy, CV_RETR_TREE,
             CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

Mat drawing = Mat::zeros(mat.size(), CV_8UC3);
for( int i = 0; i< contours.size(); i++ ) {
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0,255),
                           rng.uniform(0,255));
    drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}

putText(mat,
        (QString("Blobs: %1").arg(contours.size())).toStdString(),
        Point(25,175), cv::FONT_HERSHEY_PLAIN, 10, CV_RGB(0, 0, 255), 2);

这段代码很好地找到了我非常满意的轮廓。除了我的 IR 灯以某种方式在图像的角落和底部制造伪影。

您可以看到我在搜索轮廓时使用了 gimp 来突出显示我想忽略的区域。在灰色阴影下,您会看到我的原始代码检测为轮廓的白色像素。这些区域有问题,我想将它们从等高线搜索或等高线绘图中排除(以更容易的为准!)

我正在考虑裁剪图像以获得投资回报率,但裁剪是一个矩形,而我(例如)可以检测到东西,即正好在最左边的区域。

我认为轮廓中应该有一些数据告诉我像素在哪里,但我还没弄清楚...

最简单的方法就是裁剪图像。图像的区域在 OpenCV 中称为 ROI,代表感兴趣区域。

所以,你可以简单地说

cv::Mat image_roi = image(cv::Rect(x, y, w, h));

这基本上是一个矩形裁剪,左上角为 x,y,宽度为 w,高度为 h

现在,您可能不想缩小图像的大小。下一个最简单的去除伪像的方法是将边界设置为 0。使用 ROI,当然:

image(cv::Rect(x, y, w, h)).setTo(cv::Scalar(0, 0, 0));

这会将一个矩形区域设置为黑色。然后,您必须在图像的边界上定义 4 个您想要变暗的矩形区域。

请注意,以上所有内容均基于手动调整和一些实验,只要您的系统是静态的,它就可以工作。