opencv实现gamma灰阶检測

简单介绍

  本篇解说使用opencv来測试,表示camera gamma參数的灰阶卡图片指标:YA Block、DynamicRange、Gray Scale。

详细实现

实现代码

#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.h>
#include "opencv2/imgproc/imgproc.hpp"
 
#define barPic "barPic"
#define Pic_windosw "src"
 
using namespace cv;
char pic_name[20];
char pic_tmp[20] = "tmp.jpg";
char pic_windows[20] = "src";
Mat src, src2;
int src2_width = 400, src2_height = 400;
int width, height, roi_width, roi_height;
int rect[4];
bool mouse_flag = false, ROI_flag = false;
Mat imageROI;
double white=0, black=0, graySum = 0;
CvFont font;
double hScale=1;
double vScale=1;
int lineWidth=1;
char showWhite[20] = "White:0", showBlack[20]="Black:0", grayNumber[20]="grayNumber:0";
 
void doGammaForA_black(Mat image){
	int i, j, k;
	IplImage pI_1, pI_2;
	CvScalar s;
	roi_width = image.rows;
	roi_height = image.cols;
	Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
	white = 0;
	black = 0;
 
	pI_1 = image;
	pI_2 = src;
	cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
 
	for(i=0; i<roi_width; i++){
		for(j=0; j<10; j++){
			s = cvGet2D(&pI_2, i, j);
			if(white==0){
				white = s.val[0];
			}else{
				white = (white + s.val[0]) / 2;
			}
		}
		for(k=roi_height-10; k< roi_height; k++){
			s = cvGet2D(&pI_2, i, k);
			if(black==0){
				black = s.val[0];
			}else{
				black = (black + s.val[0]) / 2;
			}
		}
	}
	sprintf(showWhite, "White:%d", (int)white);
	sprintf(showBlack, "Black:%d", (int)black);
}
 
void doGammaForGrayNumber(Mat image){
	int i, j, k, num=0;
	double tmp=0, cur_tmp=0;
	IplImage pI_1, pI_2;
	CvScalar s;
	roi_width = image.rows;
	roi_height = image.cols;
	Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
	graySum = 0;
 
	pI_1 = image;
	pI_2 = src;
	cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
 
	for(j=0; j<roi_height; j++){
		for(i=0; i<roi_width; i++){
			s = cvGet2D(&pI_2, i, j);
			if(cur_tmp==0){
				cur_tmp=s.val[0];
			}else{
				cur_tmp=(cur_tmp + s.val[0]) / 2;
			}
		}
		if(num >= 3){
			if(tmp - cur_tmp > 8){
				graySum += 1;
			}
			tmp = cur_tmp;
			cur_tmp = 0;
			num = 0;
		}
		num += 1;
	}
	sprintf(grayNumber, "grayNumber:%d", (int)graySum);
}
 
void on_mouse( int event, int x, int y, int flags, void* ustc)  {
	switch(event){
		case CV_EVENT_LBUTTONDOWN:
			mouse_flag = true;
			rect[0] = x;
			rect[1] = y;
			rect[2] = 0;
			rect[3] = 0;
			break;
		case CV_EVENT_LBUTTONUP:
			src = imread(pic_name, 1);
			mouse_flag = false;
			rect[2] = x;
			rect[3] = y;
			rectangle(src, Point(rect[0], rect[1]), Point(rect[2], rect[3]), Scalar(0,255,0), 2);
			src = imread(pic_name, 1);
			imageROI = src(cv::Rect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]));
			ROI_flag = true;
			break;
		case CV_EVENT_MOUSEMOVE:
			if(mouse_flag){
				src = imread(pic_name, 1);
				rectangle(src, Point(rect[0], rect[1]), Point(x, y), Scalar(0,255,0), 2);
				cv::imshow(Pic_windosw, src);
			}
			break;
		default:
			break;
	}
}
 
int main(int agrc, char* argv[]){
	bool exit = false;
	char c;
	IplImage pI_barPic;
 
	memcpy(pic_name,argv[1],sizeof(argv[1]));
 
	src=cv::imread(pic_name,1);
	width = src.rows;
	height = src.cols;
	src2 = cv::Mat(src2_width, src2_height, CV_8UC3, 1);
	pI_barPic = src2;
	cv::imshow(Pic_windosw, src);
 
	cvInitFont(&font,  CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);
	cvPutText(&pI_barPic, showWhite ,cvPoint(10, 15),&font,CV_RGB(255,0,0));
	cvPutText(&pI_barPic, showBlack ,cvPoint(10, 30),&font,CV_RGB(255,0,0));
	cvPutText(&pI_barPic, grayNumber ,cvPoint(10,45),&font,CV_RGB(255,0,0));
	cv::imshow(barPic, src2);
	cvSetMouseCallback(Pic_windosw, on_mouse, NULL);
	while(!exit){
		c = cv::waitKey(100);
		if(c == ‘q‘){
			exit = true;
		}
		if(ROI_flag){
			cv::imshow("test", imageROI);
			doGammaForA_black(imageROI);  //A块亮度,动态范围
			doGammaForGrayNumber(imageROI);//Gray Scale
			cvZero(&pI_barPic);
			cvPutText(&pI_barPic, showWhite ,cvPoint(10, 15),&font,CV_RGB(255,0,0));
			cvPutText(&pI_barPic, showBlack ,cvPoint(10, 30),&font,CV_RGB(255,0,0));
			cvPutText(&pI_barPic, grayNumber ,cvPoint(10,45),&font,CV_RGB(255,0,0));
			cv::imshow(barPic, src2);
			ROI_flag = false;
		}
 
	}
	cvDestroyAllWindows();
 
	return 0;
}

代码解说

  1、首先也是进行各类初始化。导入了须要处理的灰阶卡照片src。生成一张空白照片src2用来显示结果。接着用cvInitFont初始化字体显示。
依次的三个cvPutText,将YA Block、DynamicRange、Gray Scale的显示。初始化到src2相应位置。然后给src显示窗体,绑定鼠标响应函数。最后是
一个循环,在循环中,首先等待键值,假设输入键值‘q‘,就直接退出程序。接着推断ROI_flag是否为true,是的话就进入相应操作。不是就直接跳过。
src=cv::imread(pic_name,1);
	width = src.rows;
	height = src.cols;
	src2 = cv::Mat(src2_width, src2_height, CV_8UC3, 1);
	pI_barPic = src2;
	cv::imshow(Pic_windosw, src);
 
	cvInitFont(&font,  CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);
	cvPutText(&pI_barPic, showWhite ,cvPoint(10, 15),&font,CV_RGB(255,0,0));
	cvPutText(&pI_barPic, showBlack ,cvPoint(10, 30),&font,CV_RGB(255,0,0));
	cvPutText(&pI_barPic, grayNumber ,cvPoint(10,45),&font,CV_RGB(255,0,0));
	cv::imshow(barPic, src2);
	cvSetMouseCallback(Pic_windosw, on_mouse, NULL);
	while(!exit){
		c = cv::waitKey(100);
		if(c == ‘q‘){
			exit = true;
		}
		if(ROI_flag){
		     .............
                     .............
                     .............
		}
 
	}
}
  2、在鼠标响应函数中,操作非常easy,就是让用户框选中灰阶卡所在的位子。

当用户左键按下的时候,随着鼠标的拖动,会出现一个绿色的矩形框。
当鼠标左键抬起之后,当前矩形框的位置,就被觉得是灰阶卡所在的位置。

同一时候将标志位ROI_flag设置为true。
void on_mouse( int event, int x, int y, int flags, void* ustc)  {
	switch(event){
		case CV_EVENT_LBUTTONDOWN:
			mouse_flag = true;
			rect[0] = x;
			rect[1] = y;
			rect[2] = 0;
			rect[3] = 0;
			break;
		case CV_EVENT_LBUTTONUP:
			src = imread(pic_name, 1);
			mouse_flag = false;
			rect[2] = x;
			rect[3] = y;
			rectangle(src, Point(rect[0], rect[1]), Point(rect[2], rect[3]), Scalar(0,255,0), 2);
			src = imread(pic_name, 1);
			imageROI = src(cv::Rect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]));
			ROI_flag = true;
			break;
		case CV_EVENT_MOUSEMOVE:
			if(mouse_flag){
				src = imread(pic_name, 1);
				rectangle(src, Point(rect[0], rect[1]), Point(x, y), Scalar(0,255,0), 2);
				cv::imshow(Pic_windosw, src);
			}
			break;
		default:
			break;
	}
}
  3、之前有提到,当ROI_flag置为true之后。就会进入相应处理函数中,首先是使用doGammaForA_black(imageROI);对框选出来的灰阶卡进行
YA Block、DynamicRange的检測。
    检測的方式是,首先将灰阶卡图片灰阶化,然后分别取出图片最左边的10列,计算它平均亮度作为YA Block;取出图片最右边10列,也是计算它们的
平均亮度最为最暗处亮度,当左边平均亮度减去右边平均亮度。得到的就是DynamicRange。
void doGammaForA_black(Mat image){
	int i, j, k;
	IplImage pI_1, pI_2;
	CvScalar s;
	roi_width = image.rows;
	roi_height = image.cols;
	Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
	white = 0;
	black = 0;
 
	pI_1 = image;
	pI_2 = src;
	cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
 
	for(i=0; i<roi_width; i++){
		for(j=0; j<10; j++){
			s = cvGet2D(&pI_2, i, j);
			if(white==0){
				white = s.val[0];
			}else{
				white = (white + s.val[0]) / 2;
			}
		}
		for(k=roi_height-10; k< roi_height; k++){
			s = cvGet2D(&pI_2, i, k);
			if(black==0){
				black = s.val[0];
			}else{
				black = (black + s.val[0]) / 2;
			}
		}
	}
	sprintf(showWhite, "White:%d", (int)white);
	sprintf(showBlack, "Black:%d", (int)black);
}
  4、最后是使用doGammaForGrayNumber(imageROI),进行Gray Scale的计算。计算的方式是:首先将灰阶卡图片灰阶化,然后从左往右遍历整个图片。
以3列为一组的计算出它们的平均亮度。当相邻两块的亮度差值大于8的时候,表示Gray Scale加1.
void doGammaForGrayNumber(Mat image){
	int i, j, k, num=0;
	double tmp=0, cur_tmp=0;
	IplImage pI_1, pI_2;
	CvScalar s;
	roi_width = image.rows;
	roi_height = image.cols;
	Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
	graySum = 0;
 
	pI_1 = image;
	pI_2 = src;
	cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
 
	for(j=0; j<roi_height; j++){
		for(i=0; i<roi_width; i++){
			s = cvGet2D(&pI_2, i, j);
			if(cur_tmp==0){
				cur_tmp=s.val[0];
			}else{
				cur_tmp=(cur_tmp + s.val[0]) / 2;
			}
		}
		if(num >= 3){
			if(tmp - cur_tmp > 8){
				graySum += 1;
			}
			tmp = cur_tmp;
			cur_tmp = 0;
			num = 0;
		}
		num += 1;
	}
	sprintf(grayNumber, "grayNumber:%d", (int)graySum);
}

效果演示

 相应的效果演演示样例如以下:
        
        
        
时间: 2024-10-07 08:42:16

opencv实现gamma灰阶检測的相关文章

opencv实现gamma灰阶检测

简介 本篇讲解使用opencv来测试,表示camera gamma参数的灰阶卡图片指标:YA Block.DynamicRange.Gray Scale. 具体实现 实现代码 #include <math.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <opencv2/core/core.hpp> #include <opencv2/highgu

利用opencv中的级联分类器进行人脸检測-opencv学习(1)

OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外也能够使用LBP特征. 先介绍一下相关的结构,级联分类器的计算特征值的基础类FeatureEvaluator,功能包含读操作read.复制clone.获得特征类型getFeatureType,分配图片分配窗体的操作setImage.setWindow,计算有序特征calcOrd,计算绝对特征calc

图像边缘检測小结

边缘是图像中灰度发生急剧变化的区域边界. 图像灰度的变化情况能够用图像灰度分布的梯度来表示,数字图像中求导是利用差分近似微分来进行的,实际上经常使用空域微分算子通过卷积来完毕. 一阶导数算子 1)  Roberts算子 Roberts算子是一种斜向偏差分的梯度计算方法.梯度的大小代表边缘的强度.梯度的方向与边缘的走向垂直.Roberts操作实际上是求旋转 \pm" title="\pm" >45度两个方向上微分值的和. Roberts算子定位精度高,在水平和垂直方向的效

【OpenCV新手教程之十七】OpenCV重映射 &amp;amp; SURF特征点检測合辑

本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本号: 2.4.9 本篇文章中,我们一起探讨了OpenCV

OpenCV特征点检測------Surf(特征点篇)

Surf(Speed Up Robust Feature) Surf算法的原理                                                                           1.构建Hessian矩阵构造高斯金字塔尺度空间 事实上surf构造的金字塔图像与sift有非常大不同,就是由于这些不同才加快了其检測的速度. Sift採用的是DOG图像.而surf採用的是Hessian矩阵行列式近似值图像.Hessian矩阵是Surf算法的核心,为了方

OpenCV图像处理篇之边缘检測算子

3种边缘检測算子 灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性.沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈.因此,边缘上的变化能通过梯度计算出来. 一阶导数的梯度算子 对于二维的图像.梯度定义为一个向量. Gx对于x方向的梯度,Gy相应y方向的梯度,向量的幅值本来是 mag(f)?=?(Gx2?+?Gy2)1/2,为简化计算,一般用mag(f)=|Gx|+|Gy|近似,幅值同一时候包括了x而后y方向的梯度信息.梯度的方向为 α?=?arctan(Gx/Gy) . 因为

OpenCV人脸检測(完整源代码+思路)

本博文IDE为vs2013 OpenCV2.49 话不多说,先看视频演示(20S演示): 例如以下: https://v.youku.com/v_show/id_XMjYzMzkxMTYyMA==.html?spm=a2h0w.8278793.2736843.4#paction 程序截图例如以下: 怎样来用OpenCV来实现能. 以下给出OpenCV实现人脸检測的一般步骤: 1.载入人脸检測器 2.开启摄像头 3.对图片进行灰度处理(事实上能够不处理,上图中原图的标题栏就是未进行灰度处理进行的检

基于QT和OpenCV的人脸检測识别系统(1)

人脸识别分为两大步骤 1.人脸检測 这个是首要实现的.你得实现人脸显示的时候把人脸框出来,当然算法非常多,另一些人眼检測鼻子检測什么的 主要用的是这个 const char *faceCascadeFilename = "haarcascade_frontalface_alt.xml"; detect_and_draw(IplImageBuffer,storage,cascade); 这个函数就是检測人脸的并画框效果例如以下 watermark/2/text/aHR0cDovL2Jsb

目标检測的图像特征提取之(一)HOG特征

1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检測的特征描写叙述子.它通过计算和统计图像局部区域的梯度方向直方图来构成特征.Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检測中获得了极大的成功.须要提醒的是,HOG+SVM进行行人检測的方法是法国研究人员Dalal在2005的CVPR上提出的,而现在尽管有非常多行人检測算法不断提出,但基本都是以HOG+SVM的思路为主. (