问题
我想计算属于在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行)?
答案 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();
}
通常,在处理图像时,只能直观地看到中间步骤。