【问题标题】:Calculating image pixel values (e.g. the mean) of Contour-inliers using mask & ROI in OpenCV在 OpenCV 中使用掩码和 ROI 计算轮廓内点的图像像素值(例如平均值)
【发布时间】:2013-10-28 23:37:38
【问题描述】:

问题
我想计算属于在 OpenCV 中作为点向量给出的轮廓的像素值的平均值。与轮廓相比,图像相当大,所以我想先设置一个与轮廓边界框一样大的 ROI,然后再进行遮罩。然而,这并没有真正起作用,我得到零作为平均值计算的结果。

带行号的代码

1)  Mat crop = Mat(*img, bounding_box); //img is the original image (may be 1024*1024)  
2)  Mat mask = Mat::zeros(crop.rows, crop.cols, CV_8UC1); //the mask with the size of cropped image  
3)  vector<vector<Point> > contours;  
4)  contours.push_back(*cv_contour);   
5)  drawContours(mask, contours, -1, Scalar(255), CV_FILLED, CV_AA, noArray(), 1, bounding_box.tl());   
6)  double mean_ = sum(mean(crop, mask))[0]; // returns wrong results (0)

顺便说一句:如果我只想绘制一个轮廓,有没有办法避免为drawContours 创建一个新数组(第 3 行和第 4 行)?

【问题讨论】:

    标签: c++ image-processing opencv


    【解决方案1】:

    我猜你的错误是在 drawContours 的偏移量中的代数符号。让我告诉你,我的意思是这个示例代码产生以下输出:http://daiw.de/share/Forum/stackoverflow_calculating-image-pixel-values-e-g-the-mean-of-contour-inliers-using-mask-r_001.png

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <algorithm>
    #include <iterator>
    
    int main()
    {
        // Create a small image with a circle in it.
        cv::Mat image(256, 256, CV_8UC3, cv::Scalar(0, 0, 0));
        cv::circle(image, cv::Point(80, 110), 42, cv::Scalar(255, 127, 63), -1);
    
        // Create random Contour
        typedef cv::vector<cv::Point> TContour;
        TContour contour;
        contour.push_back(cv::Point(20, 30));
        contour.push_back(cv::Point(40, 110));
        contour.push_back(cv::Point(140, 140));
        contour.push_back(cv::Point(160, 50));
    
        // The conversion to cv::vector<cv::vector<cv::Point>> is unavoidable,
        // but can easily be achieved with a temporary instance.
        cv::Mat imageWithContour(image.clone());
        typedef cv::vector<TContour> TContours;
        cv::drawContours(imageWithContour, TContours(1, contour), -1, cv::Scalar(255, 255, 255));
    
        // Show the contour.
        cv::imshow("image with contour", imageWithContour);
    
        // Get ROI image.
        cv::Rect roi(cv::boundingRect(contour));
        cv::Mat crop(image, roi);
    
        // Calculate ROI mean.
        cv::Mat mask(cv::Mat::zeros(crop.rows, crop.cols, CV_8UC1)); //the mask with the size of cropped image
        // The offset for drawContours has to be *minus* roi.tl();
        cv::drawContours(mask, TContours(1, contour), -1, cv::Scalar(255), CV_FILLED, CV_AA, cv::noArray(), 1, -roi.tl());
        //auto mean(cv::sum(cv::mean(crop, mask)));
        auto mean(cv::mean(crop, mask));
        auto sum(cv::sum(mean));
    
        // Show crop and mask.
        cv::imshow("crop", crop);
        cv::imshow("mask", mask);
    
        // Print mean.
        std::cout << "mean: " << mean[0] << ", " << mean[1] << ", " << mean[2] << std::endl;
        std::cout << "sum: " << sum[0] << std::endl;
    
        // Wait for user input.
        cv::waitKey();
    }
    

    一般来说,在处理图像时,最好只直观地查看中间步骤。

    【讨论】:

    • 是的,这确实是问题所在。只是 .tl() 前面的标志。非常感谢!
    猜你喜欢
    • 2021-05-20
    • 2020-02-19
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2014-06-15
    相关资源
    最近更新 更多