c++ - 将更靠近的白色像素组合在一起并在 OpenCV 中围绕它们绘制一个矩形

标签 c++ opencv

我想将这些彼此靠近的白色像素分组,并使用 C++ 在 OpenCV 中围绕它们绘制一个矩形。

原始图片:

预期结果:

我是 OpenCV 的新手。任何帮助将不胜感激。

最佳答案

您可以使用 partition 根据给定的谓词对白色像素进行分组.在这种情况下,您的谓词可以是:将给定欧氏距离内的所有白色像素分组

然后您可以计算每个组的边界框,保留最大的框(下面的红色部分),并最终扩大它(下面的绿色部分):

enter image description here

代码:

#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>

using namespace std;
using namespace cv;

int main()
{
    // Load the image 
    Mat3b img = imread("path_to_image", IMREAD_COLOR);

    // Convert to grayscale
    Mat1b gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);

    // Get binary mask (remove jpeg artifacts)
    gray = gray > 200;

    // Get all non black points
    vector<Point> pts;
    findNonZero(gray, pts);

    // Define the radius tolerance
    int th_distance = 50; // radius tolerance

    // Apply partition 
    // All pixels within the radius tolerance distance will belong to the same class (same label)
    vector<int> labels;

    // With lambda function (require C++11)
    int th2 = th_distance * th_distance;
    int n_labels = partition(pts, labels, [th2](const Point& lhs, const Point& rhs) {
        return ((lhs.x - rhs.x)*(lhs.x - rhs.x) + (lhs.y - rhs.y)*(lhs.y - rhs.y)) < th2;
    });

    // You can save all points in the same class in a vector (one for each class), just like findContours
    vector<vector<Point>> contours(n_labels);
    for (int i = 0; i < pts.size(); ++i)
    {
        contours[labels[i]].push_back(pts[i]);
    }

    // Get bounding boxes
    vector<Rect> boxes;
    for (int i = 0; i < contours.size(); ++i)
    {
        Rect box = boundingRect(contours[i]);
        boxes.push_back(box);
    }

    // Get largest bounding box
    Rect largest_box = *max_element(boxes.begin(), boxes.end(), [](const Rect& lhs, const Rect& rhs) {
        return lhs.area() < rhs.area();
    });

    // Draw largest bounding box in RED
    Mat3b res = img.clone();
    rectangle(res, largest_box, Scalar(0, 0, 255));

    // Draw enlarged BOX in GREEN
    Rect enlarged_box = largest_box + Size(20,20);
    enlarged_box -= Point(10,10);

    rectangle(res, enlarged_box, Scalar(0, 255, 0));


    imshow("Result", res);
    waitKey();

    return 0;
}

关于c++ - 将更靠近的白色像素组合在一起并在 OpenCV 中围绕它们绘制一个矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34700070/

相关文章:

node.js - 使用 OpenCV 和 node.js 自动检测瞳孔

c++ - 继承和模板,一种奇怪的行为

python - 在 wx.panel : Show only small region of the video 中使用带有 python 和 wxPython 的 OpenCV 显示 VideoCapture

C++/CannyEdgeDetection.exe 已停止工作 Codeblocks/OpenCV 错误 : Assertion failed

c++ - OpenCV:从函数返回 Point 类型到 main

MATLAB - 捕获视频流(MJPEG、rtsp、mpeg)

c++ - 我如何强制 C++ 从全局命名空间中选择一个函数?

assert.h 中的 C++ 断言实现

c++ - HippoMocks - 使用 std::vector 的模拟方法无法编译

c++ - 如何减少只有一组有限字符的字符串使用的磁盘空间?