简体   繁体   English

如何在黑色区域OpenCV中找到矩形(C ++)

[英]How to find rectangle in black region opencv (C++)

I'm newbie OpenCV. 我是新手OpenCV。 I am using opencv for find position attach a stamp in image. 我正在使用opencv查找位置在图像中附加图章。 The stamp can't overlap with other object in image. 印章不能与图像中的其他对象重叠。

Example binary image with white region is object on image, black region is none object Example image 示例白色区域的二进制图像是图像上的对象,黑色区域是无对象的图像

Result : Find rect in black region (in white circle) can attach stamp Result imagge 结果:在黑色区域(白色圆圈)中找到矩形可以附加印章结果图像

Please help me find rect in black region same blue rect. 请帮助我在黑色区域找到与蓝色矩形相同的矩形。 Thank you! 谢谢!

If you know about rectangles count then it can use kmeans for clusterization points. 如果您知道矩形数,则可以使用kmeans作为聚类点。 First get only blue points and binarization they: 首先只获得蓝点并将其二值化:

cv::Mat img = cv::imread("NQdmi.png", cv::IMREAD_COLOR);

std::vector<cv::Mat> chans;
cv::split(img, chans);

cv::Mat diff;
cv::absdiff(chans[2], chans[1], diff);

cv::threshold(diff, diff, 1, 255, cv::THRESH_BINARY);

cv::imshow("diff", diff);

Only blue points: 仅蓝点:

二值化结果

Clusterization points and find rotated rectangles: 聚类点并找到旋转的矩形:

std::vector<cv::Point2f> points;
for (int y = 0; y < diff.rows; ++y)
{
    for (int x = 0; x < diff.cols; ++x)
    {
        if (diff.at<uchar>(y, x))
        {
            points.emplace_back(x, y);
        }
    }
}

cv::Mat pointsKmeans(points.size(), 1, CV_32FC2, &points[0]);
cv::Mat labels;
int clusterCount = 2;
cv::Mat centers;

cv::kmeans(pointsKmeans, clusterCount, labels,
    cv::TermCriteria(cv::TermCriteria::EPS+cv::TermCriteria::COUNT, 100, 1.0),
       3, cv::KMEANS_PP_CENTERS, centers);

std::vector<cv::Point2f> points1;
std::vector<cv::Point2f> points2;

cv::Mat draw = img.clone();
for (size_t i = 0; i < points.size(); ++i)
{
    int clusterIdx = labels.at<int>(i);
    if (clusterIdx > 0)
    {
        cv::circle(draw, points[i], 2, cv::Scalar(255, 0, 0), cv::FILLED, cv::LINE_AA);
        points1.push_back(points[i]);
    }
    else
    {
        cv::circle(draw, points[i], 2, cv::Scalar(0, 0, 255), cv::FILLED, cv::LINE_AA);
        points2.push_back(points[i]);
    }
}

auto DrawRRect = [draw](const std::vector<cv::Point2f>& pp)
{
    cv::RotatedRect rr = cv::minAreaRect(pp);
    cv::Point2f corners[4];
    rr.points(corners);
    cv::line(draw, corners[0], corners[1], cv::Scalar(0, 255, 0), 2);
    cv::line(draw, corners[1], corners[2], cv::Scalar(0, 255, 0), 2);
    cv::line(draw, corners[2], corners[3], cv::Scalar(0, 255, 0), 2);
    cv::line(draw, corners[3], corners[0], cv::Scalar(0, 255, 0), 2);
};
DrawRRect(points1);
DrawRRect(points2);

cv::imshow("draw", draw);

Result: 结果:

结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM