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!
Use the average() Function of NumPy to Find the Average Color of Images in Python. In mathematics, we can find the average of a vector by dividing the sum of all the elements in the vector by the total number of elements.
The typical approach to averaging RGB colors is to add up all the red, green, and blue values, and divide each by the number of pixels to get the components of the final color. There's a better way! Instead of summing up the components of the RGB color, sum their squares instead.
fillPoly() function of OpenCV is used to draw filled polygons like rectangle, triangle, pentagon over an image. This function takes inputs an image and endpoints of Polygon and color.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With