Opencv 学习 - 自封装函数

绘制直方图

  • 作用:统计灰度图各像素出现次数
  • 函数:CvDrawHist
Mat CvDrawHist(Mat * pMat, char * szWndName = "HistFig", BOOL bShowHist = TRUE)
{
	// 封装原接口
	Mat matHist;
	const int  idxChannel[1] = { 0 };
	const int  bins[1] = { 256 };
	float iRange[2] = { 0, 255 };
	const float * range[1] = { iRange };
	calcHist(pMat, 1, idxChannel, Mat(), matHist, 1, bins, range);

	// 设置直方图画布大小
	int hist_w = 512;
	int hist_h = 400;
	int widthHist = 4;
	Mat bkMat = Mat::zeros(hist_h, hist_w, CV_8UC3);

	// 归一化图片,并绘制在窗口中
	Mat matHistNor;
	normalize(matHist, matHistNor, 1, 0, NORM_INF, -1, Mat());
	for (int i = 1; i <= matHistNor.rows; i++)
	{
		int iHight = cvRound(hist_h * matHistNor.at<float>(i - 1));
		cv::rectangle(bkMat,
			Point(widthHist * (i - 1), hist_h - 1),
			Point(widthHist * i - 1, hist_h - iHight - 1),
			Scalar(255, 255, 255),
			-1);
	}
	
	// 按需选择是否显示
	if (bShowHist)
	{
		imshow(szWndName, bkMat);
	}

	return matHist;
}

火焰判断函数

摘自:coldplayplay

Mat CheckColor(Mat &inImg, int red_ThresHold = 50, int sat_ThresHold = 5)
{
	//int red_ThresHold = 50;
	//int sat_ThresHold = 5;

	Mat fireImg;
	fireImg.create(inImg.size(), CV_8UC1);
	Mat multiRGB[3];
	int a = inImg.channels();
	split(inImg, multiRGB); //将图片拆分成R,G,B,三通道的颜色  

	for (int i = 0; i < inImg.rows; i++)
	{
		for (int j = 0; j < inImg.cols; j++)
		{
			float B, G, R;
			B = multiRGB[0].at<uchar>(i, j); //每个像素的R,G,B值,动态地址计算法  
			G = multiRGB[1].at<uchar>(i, j);
			R = multiRGB[2].at<uchar>(i, j);

			float maxValue = max(max(B, G), R);
			float minValue = min(min(B, G), R);
			//与HSI中S分量的计算公式
			double S = (1 - 3.0*minValue / (R + G + B));

			//R > RT  R>=G>=B  S>=((255-R)*ST/RT)  
			if (R > red_ThresHold &&R >= G && G >= B && S > ((255 - R) * sat_ThresHold / red_ThresHold))
			{
				fireImg.at<uchar>(i, j) = 255;
			}
			else
			{
				fireImg.at<uchar>(i, j) = 0;
			}
		}
	}

	//erode(fireImg, fireImg, Mat(3, 3, CV_8UC1));
	//GaussianBlur(fireImg, fireImg, Size(5, 5), 0, 0);
	medianBlur(fireImg, fireImg, 5);
	dilate(fireImg, fireImg, Mat(5, 5, CV_8UC1));

	return fireImg;
}

火焰识别基本流程

	// 1. 变量定义
	Mat frame_color;			// 原始图像
	Mat frame_gray;				// 灰度图像数据
	Mat frame_binary_org;		// 二值化图像数据
	Mat frame_binary_fix1;		// 二值化图像数据
	
	// 2. 读取原图
	frame_color = imread("../TestPic/test1.PNG");
	if (frame_color.empty())
	{
		MessageBox(NULL,_T("读取图片失败"), NULL, MB_OK);
		return 0;
	}

	// 3. 彩色图 》 灰度图
	cvtColor(frame_color, frame_gray, COLOR_BGR2GRAY);

	/*
		中间插入滤波、平滑、等处理
	*/
	
	// 4. 二值化灰度图
	threshold(frame_gray, frame_binary_org, 240, 255, THRESH_BINARY | THRESH_OTSU);
	//adaptiveThreshold(frame_gray, frame_binary_org, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0);
	//adaptiveThreshold(frame_gray, frame_binary_org, 255, ADAPTIVE_THRESH_MEAN_C,     THRESH_BINARY, 51, -3);

	// 5. 对原始的二值化图像进行形态学操作(修图)
	{
		Mat tempMat;
		Mat kernal_OpenClose = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));					// 获得结构元素
		morphologyEx(frame_binary_org,  tempMat, CV_MOP_OPEN,  kernal_OpenClose, Point(-1, -1), 3);	// 开运算:消除小火焰
		morphologyEx(tempMat, frame_binary_fix1, CV_MOP_CLOSE, kernal_OpenClose, Point(-1, -1), 3);	// 闭运算:填充小空洞
	}
	
	// 6. 识别二值化图的轮廓(边缘检测)
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(frame_binary_fix1, contours, hierarchy, RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);// 边缘检测

	// 7. 绘制轮廓图
	Mat dstImage = Mat::zeros(frame_binary_fix1.size(), CV_8UC3);
	for (int i = 0; i < (int)contours.size(); i++)
	{
		Scalar color = Scalar(rand() % 255, rand() % 255, rand() % 255);
		drawContours(frame_color, contours, i, color, 8);
	}
	imshow("轮廓图", dstImage);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值