gpt4 book ai didi

c++ - 如何有效计算每个多边形区域内的所有非零像素?

转载 作者:行者123 更新时间:2023-12-03 07:02:03 26 4
gpt4 key购买 nike

我想有效地计算每个多边形区域内所有白色像素的数量。
给出一些过程:

// some codes for reading gray image
// cv::Mat gray = cv::imread("gray.jpg");

// given polygons
// vector< vector<cv::Point> > polygons;

cv::Mat cropped;
cv::Mat mask = cv::Mat::zeros(gray.size(), CV_8UC1);
cv::fillPoly(mask, polygons, cv::Scalar(255));
cv::bitwise_and(gray, gray, cropped, mask);

cv::Mat binary;
cv::threshold(cropped, binary, 20, 255, CV_THRESH_BINARY);
因此,到目前为止,我们可以获得具有多个多边形区域(例如,我们有3个区域)的图像,这些区域具有白色(值为255)像素。然后,经过一些操作,我们期望得到一个像这样的 vector :
// some efficient operations
// ...

vector<int> pixelNums;
pixelNums的大小应与多边形相同(此处为3)。如果我们打印它们,我们可能会得到一些输出(值基本上取决于预处理):
index: 0; value: 120
index: 1; value: 1389
index: 2; value: 0
这是我的想法。在 cv::countNonZero的帮助下对每个多边形区域中的每个像素进行计数,但是我需要在一个循环中调用它,我认为这不是一种有效的方法,不是吗?
vector<int> pixelNums;
for(auto polygon : polygons)
{
vector< vector<cv::Point> > temp_polygons;
temp_polygons.push_back(polygon);

cv::Mat cropped;
cv::Mat mask = cv::Mat::zeros(gray.size(), CV_8UC1);
cv::fillPoly(mask, temp_polygons, cv::Scalar(255));
cv::bitwise_and(gray, gray, cropped, mask);

cv::Mat binary;
cv::threshold(cropped, binary, 20, 255, CV_THRESH_BINARY);

pixelNums.push_back(cv::countNonZero(binary));
}
如果您有更好的方法,请回答此帖子。在这里我说 better way仅在cpu环境中消耗的时间最少。

最佳答案

可以做一些小的改进,但是所有这些改进都可以提供不错的加速效果。

  • 仅计算一次阈值
  • 使用多边形的边界框获取感兴趣的区域,以对较小的图像进行大多数操作
  • 避免在for循环中使用不需要的副本,请使用const auto&

  • 示例代码:
    #include <vector>
    #include <opencv2/opencv.hpp>

    int main()
    {
    // Your image
    cv::Mat1b gray = cv::imread("path/to/image", cv::IMREAD_GRAYSCALE);

    // Your polygons
    std::vector<std::vector<cv::Point>> polygons
    {
    { {15,120}, {45,200}, {160,160}, {140, 60} },
    { {10,10}, {15,30}, {50,25}, {40, 15} },
    // etc...
    };

    // Compute the threshold just once
    cv::Mat1b thresholded = gray > 20;

    std::vector<int> pixelNums;
    for (const auto& polygon : polygons)
    {
    // Get bbox of polygon
    cv::Rect bbox = cv::boundingRect(polygon);

    // Make a new (small) mask
    cv::Mat1b mask(bbox.height, bbox.width, uchar(0));
    cv::fillPoly(mask, std::vector<std::vector<cv::Point>>{polygon}, cv::Scalar(255), 8, 0, -bbox.tl());

    // Get crop
    cv::Mat1b cropped = thresholded(bbox) & mask;

    // Compute the number of white pixels only on the crop
    pixelNums.push_back(cv::countNonZero(cropped));
    }

    return 0;
    }

    关于c++ - 如何有效计算每个多边形区域内的所有非零像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64656045/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com