获取图像任意4边形内的灰度平均值

时间:2022-04-12 15:12:44

      平时研究图像处理比较多,自然也少不了利用统计学的方法来查看图像的各种信息,最近手头写了一个用鼠标点击4个点,围成一个任意4边形,然后统计这个4边形内的灰度的平均值工具。(其实也不算什么工具,:-D)

实现思想:对一张图片A,建立一个掩膜,即:建立一个和图片大小一样的矩阵,让选择的那4个点内的数字为1,其他地方为0。之后再和图片A矩阵对应相乘,这样会只留下这个4边形内的像素值存在,其他地方的像素值都为0了。然后把这些像素值相加,再求平均就得出最终结果。

语言:c++

环境要求:Opencv(我用的是3.4版本)

      自然需要先为vs配置Opencv的环境,这个网上有很多教程:CSDN上面也有很多,回头我可以把一个超详细的链接放到这里,但是估计得先经过别人的同意,已经问过了,等待回复中。

下面贴代码:

#include <opencv2/highgui/highgui.hpp>  
#include<opencv2\opencv.hpp>
#include <opencv2/core/core.hpp>  
#include <iostream>
using namespace cv;
using namespace std;

//--定义几个全局变量,因为下面用到的onMouse没有返回值,所以只能通过全局变量来记录要获取的4个坐标的值。
Point pointCoo[4];
int clickNum = 0;

#define WINDOW "Pic"
void onMouse1(int event, int x, int y, int flag, void*) {
	if (event == EVENT_LBUTTONDOWN) {
		clickNum++;
		switch (clickNum) {
		case 1: pointCoo[0] = Point(x, y); break;
		case 2: pointCoo[1] = Point(x, y); break;
		case 3: pointCoo[2] = Point(x, y); break;
		case 4: pointCoo[3] = Point(x, y); break;
		default: break;
		}
		//点击一个坐标显示一次定义的全局变量pointCoo里面的值
		for (auto con : pointCoo)
			cout << con << endl;

	}

}


int avgGray(int(*p), Mat img) {

	//读入原图片,并获取长宽
	int length = img.rows;
	int width = img.cols;

	//建立一个全是0的图片掩膜
	Mat imgM(length, width, CV_8UC1, Scalar(0));

	Point points[1][4];
	points[0][0] = Point(p[0], p[1]);
	points[0][1] = Point(p[2], p[3]);
	points[0][2] = Point(p[4], p[5]);
	points[0][3] = Point(p[6], p[7]);

	//设定传入点的个数
	int npt[] = { 4 };

	//将四个点围成的区域像素变为1
	const Point *pt[1] = { points[0] };
	fillPoly(imgM, pt, npt, 1, Scalar(1));

	//将图片与掩膜对应相乘,得到只有区域部分非零的图像
	Mat reginImg = img.mul(imgM);

	namedWindow("image", WINDOW_AUTOSIZE);
	imshow("image", reginImg);
	waitKey(1000);
	//求出来四边形区域内这些像素值的总和。
	Scalar theSum = sum(reginImg);
	double theSumDouble = theSum.val[0]; //因为求和后是Scalar类型的数据,是含有一个4维数组的结构体,所以需要转化这个sum为double类型。
	int theNum = countNonZero(reginImg);   //求出这个四边形区域内有多少个像素值。
	int theAvg = theSumDouble / theNum;

	return theAvg;


}



int main() {
	Mat img = imread("X:/grayTest/QQ截图20180110154638.bmp", 0);
	namedWindow(WINDOW, WINDOW_AUTOSIZE);
	imshow(WINDOW, img);
	//waitKey(0);
	pointCoo[3].x = 0;
	setMouseCallback(WINDOW, onMouse1);
	
	//这个地方比较乱,因为我还没完全理解setMouseCallback怎么用,只能前面设定好pointCoo[3]中的x为0,然后在这里判断x是否已经被赋
	//新值来让图片刷新退出。比较low,忘见谅。
	while (int(pointCoo[3].x) == 0) {
		waitKey(2000);
	}
	int points[8] = { pointCoo[0].x, pointCoo[0].y, pointCoo[1].x, pointCoo[1].y,
		pointCoo[2].x, pointCoo[2].y, pointCoo[3].x, pointCoo[3].y };
	int theAvgGray = avgGray(points, img);    //定义theAvgGray来接收算出来的灰度平均值

	cout << "该区域的灰度平均值为:" << theAvgGray << endl;

	system("pause");
	return 0;
}


最后贴个图:

获取图像任意4边形内的灰度平均值