使用掩模和放大器计算轮廓内点的图像像素值(例如平均值)。 OpenCV的投资回报率

时间:2012-12-05 12:18:28

标签: c++ image-processing opencv

问题
我想计算属于在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行)?

1 个答案:

答案 0 :(得分:3)

我猜你的错误是在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();
}

通常,在处理图像时,只能直观地看到中间步骤。