简单介绍

  1.   本篇解说使用opencv来測试,表示camera gamma參数的灰阶卡图片指标:YA BlockDynamicRangeGray Scale

详细实现

实现代码

  1. #include <math.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <opencv2/core/core.hpp>
  6. #include <opencv2/highgui/highgui.hpp>
  7. #include <opencv/cv.h>
  8. #include "opencv2/imgproc/imgproc.hpp"
  9.  
  10. #define barPic "barPic"
  11. #define Pic_windosw "src"
  12.  
  13. using namespace cv;
  14. char pic_name[20];
  15. char pic_tmp[20] = "tmp.jpg";
  16. char pic_windows[20] = "src";
  17. Mat src, src2;
  18. int src2_width = 400, src2_height = 400;
  19. int width, height, roi_width, roi_height;
  20. int rect[4];
  21. bool mouse_flag = false, ROI_flag = false;
  22. Mat imageROI;
  23. double white=0, black=0, graySum = 0;
  24. CvFont font;
  25. double hScale=1;
  26. double vScale=1;
  27. int lineWidth=1;
  28. char showWhite[20] = "White:0", showBlack[20]="Black:0", grayNumber[20]="grayNumber:0";
  29.  
  30. void doGammaForA_black(Mat image){
  31. int i, j, k;
  32. IplImage pI_1, pI_2;
  33. CvScalar s;
  34. roi_width = image.rows;
  35. roi_height = image.cols;
  36. Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
  37. white = 0;
  38. black = 0;
  39.  
  40. pI_1 = image;
  41. pI_2 = src;
  42. cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
  43.  
  44. for(i=0; i<roi_width; i++){
  45. for(j=0; j<10; j++){
  46. s = cvGet2D(&pI_2, i, j);
  47. if(white==0){
  48. white = s.val[0];
  49. }else{
  50. white = (white + s.val[0]) / 2;
  51. }
  52. }
  53. for(k=roi_height-10; k< roi_height; k++){
  54. s = cvGet2D(&pI_2, i, k);
  55. if(black==0){
  56. black = s.val[0];
  57. }else{
  58. black = (black + s.val[0]) / 2;
  59. }
  60. }
  61. }
  62. sprintf(showWhite, "White:%d", (int)white);
  63. sprintf(showBlack, "Black:%d", (int)black);
  64. }
  65.  
  66. void doGammaForGrayNumber(Mat image){
  67. int i, j, k, num=0;
  68. double tmp=0, cur_tmp=0;
  69. IplImage pI_1, pI_2;
  70. CvScalar s;
  71. roi_width = image.rows;
  72. roi_height = image.cols;
  73. Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
  74. graySum = 0;
  75.  
  76. pI_1 = image;
  77. pI_2 = src;
  78. cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
  79.  
  80. for(j=0; j<roi_height; j++){
  81. for(i=0; i<roi_width; i++){
  82. s = cvGet2D(&pI_2, i, j);
  83. if(cur_tmp==0){
  84. cur_tmp=s.val[0];
  85. }else{
  86. cur_tmp=(cur_tmp + s.val[0]) / 2;
  87. }
  88. }
  89. if(num >= 3){
  90. if(tmp - cur_tmp > 8){
  91. graySum += 1;
  92. }
  93. tmp = cur_tmp;
  94. cur_tmp = 0;
  95. num = 0;
  96. }
  97. num += 1;
  98. }
  99. sprintf(grayNumber, "grayNumber:%d", (int)graySum);
  100. }
  101.  
  102. void on_mouse( int event, int x, int y, int flags, void* ustc) {
  103. switch(event){
  104. case CV_EVENT_LBUTTONDOWN:
  105. mouse_flag = true;
  106. rect[0] = x;
  107. rect[1] = y;
  108. rect[2] = 0;
  109. rect[3] = 0;
  110. break;
  111. case CV_EVENT_LBUTTONUP:
  112. src = imread(pic_name, 1);
  113. mouse_flag = false;
  114. rect[2] = x;
  115. rect[3] = y;
  116. rectangle(src, Point(rect[0], rect[1]), Point(rect[2], rect[3]), Scalar(0,255,0), 2);
  117. src = imread(pic_name, 1);
  118. imageROI = src(cv::Rect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]));
  119. ROI_flag = true;
  120. break;
  121. case CV_EVENT_MOUSEMOVE:
  122. if(mouse_flag){
  123. src = imread(pic_name, 1);
  124. rectangle(src, Point(rect[0], rect[1]), Point(x, y), Scalar(0,255,0), 2);
  125. cv::imshow(Pic_windosw, src);
  126. }
  127. break;
  128. default:
  129. break;
  130. }
  131. }
  132.  
  133. int main(int agrc, char* argv[]){
  134. bool exit = false;
  135. char c;
  136. IplImage pI_barPic;
  137.  
  138. memcpy(pic_name,argv[1],sizeof(argv[1]));
  139.  
  140. src=cv::imread(pic_name,1);
  141. width = src.rows;
  142. height = src.cols;
  143. src2 = cv::Mat(src2_width, src2_height, CV_8UC3, 1);
  144. pI_barPic = src2;
  145. cv::imshow(Pic_windosw, src);
  146.  
  147. cvInitFont(&font, CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);
  148. cvPutText(&pI_barPic, showWhite ,cvPoint(10, 15),&font,CV_RGB(255,0,0));
  149. cvPutText(&pI_barPic, showBlack ,cvPoint(10, 30),&font,CV_RGB(255,0,0));
  150. cvPutText(&pI_barPic, grayNumber ,cvPoint(10,45),&font,CV_RGB(255,0,0));
  151. cv::imshow(barPic, src2);
  152. cvSetMouseCallback(Pic_windosw, on_mouse, NULL);
  153. while(!exit){
  154. c = cv::waitKey(100);
  155. if(c == 'q'){
  156. exit = true;
  157. }
  158. if(ROI_flag){
  159. cv::imshow("test", imageROI);
  160. doGammaForA_black(imageROI); //A块亮度,动态范围
  161. doGammaForGrayNumber(imageROI);//Gray Scale
  162. cvZero(&pI_barPic);
  163. cvPutText(&pI_barPic, showWhite ,cvPoint(10, 15),&font,CV_RGB(255,0,0));
  164. cvPutText(&pI_barPic, showBlack ,cvPoint(10, 30),&font,CV_RGB(255,0,0));
  165. cvPutText(&pI_barPic, grayNumber ,cvPoint(10,45),&font,CV_RGB(255,0,0));
  166. cv::imshow(barPic, src2);
  167. ROI_flag = false;
  168. }
  169.  
  170. }
  171. cvDestroyAllWindows();
  172.  
  173. return 0;
  174. }

代码解说

  1.   1、首先也是进行各类初始化。导入了须要处理的灰阶卡照片src。生成一张空白照片src2用来显示结果。接着用cvInitFont初始化字体显示。
  2. 依次的三个cvPutText,将YA BlockDynamicRangeGray Scale的显示。初始化到src2相应位置。然后给src显示窗体,绑定鼠标响应函数。最后是
  3. 一个循环,在循环中,首先等待键值,假设输入键值'q',就直接退出程序。接着推断ROI_flag是否为true,是的话就进入相应操作。不是就直接跳过。
  1. src=cv::imread(pic_name,1);
  2. width = src.rows;
  3. height = src.cols;
  4. src2 = cv::Mat(src2_width, src2_height, CV_8UC3, 1);
  5. pI_barPic = src2;
  6. cv::imshow(Pic_windosw, src);
  7.  
  8. cvInitFont(&font, CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);
  9. cvPutText(&pI_barPic, showWhite ,cvPoint(10, 15),&font,CV_RGB(255,0,0));
  10. cvPutText(&pI_barPic, showBlack ,cvPoint(10, 30),&font,CV_RGB(255,0,0));
  11. cvPutText(&pI_barPic, grayNumber ,cvPoint(10,45),&font,CV_RGB(255,0,0));
  12. cv::imshow(barPic, src2);
  13. cvSetMouseCallback(Pic_windosw, on_mouse, NULL);
  14. while(!exit){
  15. c = cv::waitKey(100);
  16. if(c == 'q'){
  17. exit = true;
  18. }
  19. if(ROI_flag){
  20. .............
  21. .............
  22. .............
  23. }
  24.  
  25. }
  26. }
  1.   2、在鼠标响应函数中,操作非常easy,就是让用户框选中灰阶卡所在的位子。
  2.  
  3. 当用户左键按下的时候,随着鼠标的拖动,会出现一个绿色的矩形框。
  4. 当鼠标左键抬起之后,当前矩形框的位置,就被觉得是灰阶卡所在的位置。
  5.  
  6. 同一时候将标志位ROI_flag设置为true
  1. void on_mouse( int event, int x, int y, int flags, void* ustc) {
  2. switch(event){
  3. case CV_EVENT_LBUTTONDOWN:
  4. mouse_flag = true;
  5. rect[0] = x;
  6. rect[1] = y;
  7. rect[2] = 0;
  8. rect[3] = 0;
  9. break;
  10. case CV_EVENT_LBUTTONUP:
  11. src = imread(pic_name, 1);
  12. mouse_flag = false;
  13. rect[2] = x;
  14. rect[3] = y;
  15. rectangle(src, Point(rect[0], rect[1]), Point(rect[2], rect[3]), Scalar(0,255,0), 2);
  16. src = imread(pic_name, 1);
  17. imageROI = src(cv::Rect(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]));
  18. ROI_flag = true;
  19. break;
  20. case CV_EVENT_MOUSEMOVE:
  21. if(mouse_flag){
  22. src = imread(pic_name, 1);
  23. rectangle(src, Point(rect[0], rect[1]), Point(x, y), Scalar(0,255,0), 2);
  24. cv::imshow(Pic_windosw, src);
  25. }
  26. break;
  27. default:
  28. break;
  29. }
  30. }
  1.   3、之前有提到,当ROI_flag置为true之后。就会进入相应处理函数中,首先是使用doGammaForA_black(imageROI);对框选出来的灰阶卡进行
  2. YA BlockDynamicRange的检測。
  3. 检測的方式是,首先将灰阶卡图片灰阶化,然后分别取出图片最左边的10列,计算它平均亮度作为YA Block;取出图片最右边10列,也是计算它们的
  4. 平均亮度最为最暗处亮度,当左边平均亮度减去右边平均亮度。得到的就是DynamicRange
  1. void doGammaForA_black(Mat image){
  2. int i, j, k;
  3. IplImage pI_1, pI_2;
  4. CvScalar s;
  5. roi_width = image.rows;
  6. roi_height = image.cols;
  7. Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
  8. white = 0;
  9. black = 0;
  10.  
  11. pI_1 = image;
  12. pI_2 = src;
  13. cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
  14.  
  15. for(i=0; i<roi_width; i++){
  16. for(j=0; j<10; j++){
  17. s = cvGet2D(&pI_2, i, j);
  18. if(white==0){
  19. white = s.val[0];
  20. }else{
  21. white = (white + s.val[0]) / 2;
  22. }
  23. }
  24. for(k=roi_height-10; k< roi_height; k++){
  25. s = cvGet2D(&pI_2, i, k);
  26. if(black==0){
  27. black = s.val[0];
  28. }else{
  29. black = (black + s.val[0]) / 2;
  30. }
  31. }
  32. }
  33. sprintf(showWhite, "White:%d", (int)white);
  34. sprintf(showBlack, "Black:%d", (int)black);
  35. }
  1.   4、最后是使用doGammaForGrayNumber(imageROI),进行Gray Scale的计算。计算的方式是:首先将灰阶卡图片灰阶化,然后从左往右遍历整个图片。
  2. 3列为一组的计算出它们的平均亮度。当相邻两块的亮度差值大于8的时候,表示Gray Scale1.
  1. void doGammaForGrayNumber(Mat image){
  2. int i, j, k, num=0;
  3. double tmp=0, cur_tmp=0;
  4. IplImage pI_1, pI_2;
  5. CvScalar s;
  6. roi_width = image.rows;
  7. roi_height = image.cols;
  8. Mat src = Mat(roi_width, roi_height, CV_8UC1, 1);
  9. graySum = 0;
  10.  
  11. pI_1 = image;
  12. pI_2 = src;
  13. cvCvtColor(&pI_1, &pI_2, CV_BGR2GRAY);
  14.  
  15. for(j=0; j<roi_height; j++){
  16. for(i=0; i<roi_width; i++){
  17. s = cvGet2D(&pI_2, i, j);
  18. if(cur_tmp==0){
  19. cur_tmp=s.val[0];
  20. }else{
  21. cur_tmp=(cur_tmp + s.val[0]) / 2;
  22. }
  23. }
  24. if(num >= 3){
  25. if(tmp - cur_tmp > 8){
  26. graySum += 1;
  27. }
  28. tmp = cur_tmp;
  29. cur_tmp = 0;
  30. num = 0;
  31. }
  32. num += 1;
  33. }
  34. sprintf(grayNumber, "grayNumber:%d", (int)graySum);
  35. }

效果演示

  1.  相应的效果演演示样例如以下:
  1.  
  2. 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. sql 递归查询所有的下级

    --> 生成测试数据表: [tb] IF OBJECT_ID('[Users]') IS NOT NULL     DROP TABLE [Users] GO CREATE TABLE [Use ...

  2. java开发C语言编译器

    http://study.163.com/course/introduction.htm?courseId=1003169025 http://study.163.com/course/courseM ...

  3. 将数据处理逻辑集中到一处进行管理,逐步实现真正有效的 MVC 分层结构

    将数据处理逻辑集中到一处进行管理,逐步实现真正有效的 MVC 分层结构.

  4. 解决Ubuntu下的Eclipse打开Windows编写的java代码的中文乱码

    其实所有的中文乱码 问题都是编码不同所导致的.这里要想让eclipse能正常显示出汉字,就要修改它的字符编码 步骤如下: 1 ,点击菜单栏中的Window(窗口),选择Preferences(首选项) ...

  5. uva 10160 Servicing Stations(DFS+剪枝)

    Servicing stations A company offers personal computers for sale in N towns (3 <= N <= 35). The ...

  6. go语言之进阶篇面向对象编程

    1.面向对象编程 对于面向对象编程的支持Go 语言设计得非常简洁而优雅.因为, Go语言并没有沿袭传统面向对象编程中的诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继 ...

  7. C#读写txt文件的两种方法介绍[转]

    C#读写txt文件的两种方法介绍 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出 ...

  8. NGUI诡异的drawCall

    看了很多关于NGUI drawCall的文章,见得比较多的一个观点是:一个 Atlas 对应一个Drawcall. 好奇心下做了个demo,两个panel中只用到一个Atlas,却产生了10个draw ...

  9. (转)Unity3D Android手机开发环境配置,可真机发布调试

    此方法配置好,在可以在unity直接发布到手机上,并可以实时调试. 1.配置eclipse环境:首先在官网下载安装包:http://developer.android.com/sdk/index.ht ...

  10. new/malloc的差别

    1. malloc()函数 1.1 malloc的全称是memory allocation.中文叫动态内存分配. 原型:extern void *malloc(unsigned int num_byt ...