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);
}
效果演示
相应的效果演演示样例如以下:
![]()
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTYzMDQ1OA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
opencv实现gamma灰阶检測的更多相关文章
- 利用opencv中的级联分类器进行人脸检測-opencv学习(1)
OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外 ...
- C++开发人脸性别识别教程(10)——加入图片的人脸检測程序
现在我们的MFC框架已经初具规模,能够读取并显示目录下的图片.在这篇博文中我们将向当中加入人脸检測的程序. 一.人脸检測算法 这里我们使用OpenCv封装的Adaboost方法来进行人脸检測,參见:C ...
- 【从零学习openCV】IOS7下的人脸检測
前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...
- 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...
- 基于QT和OpenCV的人脸检測识别系统(2)
紧接着上一篇博客的讲 第二步是识别部分 人脸识别 把上一阶段检測处理得到的人脸图像与数据库中的已知 人脸进行比对,判定人脸相应的人是谁(此处以白色文本显示). 人脸预处理 如今你已经得到一张人脸,你能 ...
- 【OpenCV新手教程之十七】OpenCV重映射 & SURF特征点检測合辑
本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨) ...
- 图像边缘检測--OpenCV之cvCanny函数
图像边缘检測--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...
- Python下opencv使用笔记(七)(图像梯度与边缘检測)
梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(无论是横向的.纵向的.斜方向的等等),所须要的无非也是一个核模板.模板的不同结果也不同.所以能够看到,全部的这些个算子函数,归结究竟都能够用 ...
- opencv对图像进行边缘及角点检測
opencv对图像进行边缘及角点检測 先看结果: 代码: // ConsoleApplication1_812.cpp : Defines the entry point for the consol ...
随机推荐
- 最好的PHP博客系统
1.Wordpress http://www.wordpress.org/ B2基础上开发而来,这是国内用户比较喜欢而且用户较多的一个php博客程序,缘由是因为Wordpress提供大量插件和模板,让 ...
- yield的使用
参考: http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ http://blog.csdn.net/alvine0 ...
- Unity知识结构总结
前言 本篇以知识结构图的形式对Unity引擎的常用基础知识内容进行了总结和梳理. 如果你学了一点关于Unity引擎的知识,又觉得太杂乱,那么希望本篇会给你一些帮助. 对应引擎版本:Unity 4.6 ...
- DevExpress Components16.2.6 Source Code 编译
DevExpress 是一个比较有名的界面控件套件,提供了一系列优秀的界面控件.这篇文章将展示如何在拥有源代码的情况下,对 DevExpress 的程序集进行重新编译. 特别提示:重编译后,已安装好的 ...
- Selenium2+python自动化47-判断弹出框存在(alert_is_present)
前言 系统弹窗这个是很常见的场景,有时候它不弹出来去操作的话,会抛异常.那么又不知道它啥时候会出来,那么久需要去判断弹窗是否弹出了. 本篇接着Selenium2+python自动化42-判断元素(ex ...
- Ladda 应用提交表单的时候显示loading载入中 包含不同位置,不同效果
Ladda 应用提交表单的时候显示loading载入中 包含不同位置,不同效果 不同大小.位置,效果,进度条等 演示 XML/HTML Code <article class="exa ...
- Spring与web MVC的整合——Spring的应用上下文管理
问题1 如何让web容器加载你的web MVC框架 对于基于servlet的web容器来说,遵循的是servlet规范,入口配置文件是web.xml.这类web容器会在启动的时候会而且仅会加载如下三种 ...
- CVPR14 图像检索papers
CVPR14年关于图像检索方面的papers,汇总成一个list,方便阅读. 图像检索 Triangulation embedding and democratic aggregation for i ...
- python垃圾回收杂谈
当创建对象时Python立即向操作系统请求内存.每当对象的引用数减为0,Python垃圾回收器立刻挺身而出,立即将其释放,把内存还给操作系统.在Python中,每个对象都保存了一个称为引用计数的整数值 ...
- [Linux]在终端启动程序关闭终端不退出的方法
一般情况下关闭终端时,那么在这个终端中启动的后台程序也会终止,要使终端关闭后,后台程序保持执行,使用这个指令: nohup 命令 & 如:nohup test.sh & 回车,然后提示 ...