Reputation: 691
I am trying to create a utility that will return the average pixel color within a given polygon using OpenCV
. The polygon will be defined via 4 points, but it is not necessarily a rectangle/square. For example, the following structures are to be expected:
A__________B A_______B
/ / \ \
/ / \ \
D/__________/C D\_______\C
Given a cv::Mat
image in OpenCV and a polygon defined by the points (A, B, C, D). I know points A, B, C, and D, but I want to calc the average pixel color within the polygon. I wanted to get some suggestions from the OpenCV community on how to do this most efficiently.
Another post on StackOverflow suggested drawing contours using the drawContours
function and then take the mean
of the bounding rectangle surrounding the contour. I would obviously have to modify the mean calculation so that it uses the polygons drawn by the fillPoly
function instead.
Suggestions/Concerns are much appreciated!
Upvotes: 8
Views: 13052
Reputation: 41765
You can simply use the mean function with a mask, where the mask is your filled polygon.
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
int main()
{
// Create a black image with a gray rectangle on top left
Mat1b img(300, 300, uchar(0));
rectangle(img, Rect(0, 0, 100, 100), Scalar(100), CV_FILLED);
// Define a polygon
Point pts[1][4];
pts[0][0] = Point(20, 20);
pts[0][1] = Point(40, 100);
pts[0][2] = Point(200, 60);
pts[0][3] = Point(150, 30);
const Point* points[1] = {pts[0]};
int npoints = 4;
// Create the mask with the polygon
Mat1b mask(img.rows, img.cols, uchar(0));
fillPoly(mask, points, &npoints, 1, Scalar(255));
// Compute the mean with the computed mask
Scalar average = mean(img, mask);
std::cout << average << std::endl;
return 0;
}
Upvotes: 14