简单介绍

  本篇解说使用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灰阶检測的更多相关文章

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

    OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外 ...

  2. C++开发人脸性别识别教程(10)——加入图片的人脸检測程序

    现在我们的MFC框架已经初具规模,能够读取并显示目录下的图片.在这篇博文中我们将向当中加入人脸检測的程序. 一.人脸检測算法 这里我们使用OpenCv封装的Adaboost方法来进行人脸检測,參见:C ...

  3. 【从零学习openCV】IOS7下的人脸检測

    前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...

  4. 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

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

    紧接着上一篇博客的讲 第二步是识别部分 人脸识别 把上一阶段检測处理得到的人脸图像与数据库中的已知 人脸进行比对,判定人脸相应的人是谁(此处以白色文本显示). 人脸预处理 如今你已经得到一张人脸,你能 ...

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

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨)  ...

  7. 图像边缘检測--OpenCV之cvCanny函数

    图像边缘检測--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...

  8. Python下opencv使用笔记(七)(图像梯度与边缘检測)

    梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(无论是横向的.纵向的.斜方向的等等),所须要的无非也是一个核模板.模板的不同结果也不同.所以能够看到,全部的这些个算子函数,归结究竟都能够用 ...

  9. opencv对图像进行边缘及角点检測

    opencv对图像进行边缘及角点检測 先看结果: 代码: // ConsoleApplication1_812.cpp : Defines the entry point for the consol ...

随机推荐

  1. jquery的closest方法和parents方法的区别

    今天第一次看到closest方法,以前也从来没用过. 该方法从元素本身开始往上查找,返回最近的匹配的祖先元素. 1.closest查找开始于自身,parents开始于元素父级 2.closest向上查 ...

  2. Android APP分享功能实现

    [Android应用开发详解]第01期:第三方授权认证(一)实现第三方授权登录.分享以及获取用户资料   由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折, ...

  3. CMMI5级——原因分析及解决方案(Causal Analysis and Resolution)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010825142/article/details/15338085 聪明的人在出现问题的时候,除了 ...

  4. 页面中基于JSTL标签调用函数--之${fn:}内置函数

    调用这样一个头文件<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions " ...

  5. Windows和Linux下如何查看端口被哪个进程占用

    Windows: C:/Users/ewanbao>netstat -aon|findstr "123"  TCP    127.0.0.1:55123        0.0 ...

  6. [Android Pro] Swift 3.0多线程

    本文只介绍Grand Central Dispath(GCD) 中央调度 个人认为一个GCD就够用了,可能是改版或是其他的在找之前写的多线程方法时发现不能用了,看文档之后发现改了,现在看上去更加简单易 ...

  7. 500 OOPS: vsftpd: cannot locate user specified in 'chown_username':whoever

    错误:500 OOPS: vsftpd: cannot locate user specified in 'chown_username':whoever解决方案:在vsftpd.conf中修改如下两 ...

  8. 版本号控制-git(二)

    上次文章给大家介绍了Git的一些基本知识(http://www.cnblogs.com/jerehedu/p/4582398.html).并介绍了使用git init初始化化版本号库.使用git ad ...

  9. ubuntu下mongodb常用命令

    1. 启动脚本 #!/bin/bash mongod --dbpath /usr/local/mongodb/data1 chmod +x run-mongodb 2. 关闭数据库服务 官方文档说可以 ...

  10. iOS开发-DatePicker控件

    时间控件不管是Android还是iOS中都是必然存在的一个控件,具体的效果大同小异,显示日期,时间,iOS中有四种方式可以选择,Time, Date,Date and Time  , Count Do ...