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、在鼠标响应函数中,操作很简单,就是让用户框选中灰阶卡所在的位子。当用户左键按下的时候,随着鼠标的拖动,会出现一个绿色的矩形框。
当鼠标左键抬起之后,当前矩形框的位置,就被认为是灰阶卡所在的位置。同时将标志位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-11-08 21:48:04

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/high

OpenCV脸部、眼睛检测

/* 功能:实现对眼睛.脸部的跟踪. 版本:1.0 时间:2014-4-27 */ #include <opencv2/objdetect/objdetect.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <iostream> #include

OpenCV例程实现人脸检测

前段时间看的OpenCV,其实有很多的例子程序,参考代码值得我们学习,对图像特征提取三大法宝:HOG特征,LBP特征,Haar特征有一定了解后. 对本文中的例子程序刚开始没有调通,今晚上调通了,试了试效果还可以,还需要深入理解.值得大家动手试试,还是很有成就感的,虽然是现成的例子....... 环境:OpenCV3.1+VS2013+WIN10 复制代码/*! * \file Capture.cpp * * \author ranjiewen * \date 十一月 2016 * * http:

SmileyFace——基于OpenCV的人脸人眼检测、面部识别程序

项目地址 https://github.com/guoyaohua/SmileyFace 开发环境 Visual Studio 2010 MFC + OpenCV 功能描述 静态图像人脸检测 视频人脸追踪检测 摄像头人脸检测 人脸切割显示 实时面部识别 样本自动采集 基于面部识别的程序锁 系统框图 人脸检测 人脸识别 系统截图 本程序以用户体验为中心,界面简洁.明了.易于操作.即使第一次使用该应用,也可以流利的操作. 1.主界面 2.人脸检测效果图--标准正脸 3.人脸检测效果图--人脸集 4.

Opencv:视频中人脸检测并保存人脸图片

# OpenCV版本的视频检测 import cv2 # 图片识别方法封装 def discern(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cap = cv2.CascadeClassifier( "C:\Python36\Lib\site-packages\opencv-master\data\haarcascades\haarcascade_frontalface_default.xml" ) faceRects = c

opencv学习---打开摄像头检测个人头像

opencv中具有检测人体各部分的级联分类器,在opencv文件夹里面的sources/data/haarcascades里面. 这里要选择的是能够检测人体头像的还有检测眼睛的级联分类器的文件. 它们分别是: 检测头像 haarcascade_frontalface_alt.xml或者haarcascade_frontalface_alt2.xml 检测眼睛 haarcascade_eye.xml或者haarcascade_eye_tree_eyeglasses.xml 检测用的函数是: cvH

opencv,关于物体检测

关于物体检测 环境:opencv 2.4.11+vs2013 参考: http://www.cnblogs.com/tornadomeet/archive/2012/06/02/2531705.html http://www.cnblogs.com/xinyuyuanm/archive/2013/04/29/3050750.html 1 #include <string> 2 #include <iostream> 3 #include <stdio.h> 4 #inc

OpenCV:Snake方法检测可变形体的轮廓

<span style="font-size:14px;">#include <iostream> #include <string.h> #include <opencv\cxcore.h> #include <opencv\cv.h> #include <opencv\highgui.h> #include <opencv\cvaux.h> #include <fstream> IplI

【OpenCV】角点检测:Harris角点及Shi-Tomasi角点检测

角点 特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系.点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(keypoint feature),或“兴趣点”(interest point),或“角点”(conrner). 关于角点的具体描述可以有几种: 一阶导数(即灰度的梯度)的局部最大所对应的像素点: 两条及两条以上边缘的交点: 图像中梯度值和梯度方向的变化速率都很高的点: 角点处的一阶导数最大,二阶导数