问题
我想计算属于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行)?最佳答案:
我猜你的错误是在等高线偏移量的代数符号上让我向您展示一下,生成以下输出的示例代码的含义: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();
}
一般来说,在处理图像时,最好直观地看到中间步骤。