1. #include <highgui.h>
  2. #include <cv.h>
  3. #include "opencv_libs.h"
  4.  
  5. /*
  6. *《学习OpenCV》第四章第三题b
  7. * 完成时间:1:36 3/31 星期日 2013
  8. */
  9.  
  10. /* 矩形框 */
  11. CvRect rect;
  12.  
  13. bool draw = false; // 标记是否在画
  14.  
  15. IplImage* img;
  16. IplImage * temp;
  17. IplImage * original;
  18.  
  19. bool draw_hist = false;
  20.  
  21. IplImage* getHistImage(IplImage* image, CvHistogram* image_hist,
  22. CvSize image_size, CvScalar value)
  23. {
  24. // 计算直方图
  25. cvCalcHist( &image, image_hist, , NULL );
  26. // 新建一幅3通道的图像
  27. IplImage* dst = cvCreateImage(image_size, IPL_DEPTH_8U, );
  28.  
  29. cvSet( dst, cvScalarAll() );
  30.  
  31. float max_value = ;
  32. cvGetMinMaxHistValue( image_hist, NULL, &max_value, NULL, NULL );
  33. double bin_width = (double)dst->width/;
  34. double bin_unith = (double)dst->height/max_value; // 高度比例
  35.  
  36. for(int i = ; i < ; i++)
  37. {
  38. // 获得矩形左上角和右下角坐标
  39. CvPoint p0 = cvPoint( i + bin_width, dst->height );
  40. CvPoint p1 = cvPoint( (i+) * bin_width,
  41. dst->height - cvGetReal1D(image_hist->bins, i) * bin_unith );
  42. // 画实心矩形
  43. cvRectangle( dst, p0, p1, value, -, , );
  44. }
  45.  
  46. return dst;
  47. }
  48.  
  49. void draw_rect(IplImage* img, CvRect rect)
  50. {
  51. cvRectangle( img,
  52. cvPoint( rect.x, rect.y ),
  53. cvPoint( rect.x + rect.width, rect.y + rect.height),
  54. cvScalar( 0x00, 0x00, 0xff) );
  55. printf("draw\n");
  56.  
  57. // 在这里处理直方图
  58. // 设置感兴趣区域
  59. cvSetImageROI( img, rect);
  60. IplImage* src_rect = cvCreateImage (
  61. cvSize( rect.width, rect.height ),
  62. img->depth, img->nChannels );
  63. cvCopy(img, src_rect );
  64. cvResetImageROI( img );
  65.  
  66. IplImage* r_img = cvCreateImage( cvGetSize( src_rect),
  67. src_rect->depth, );
  68. IplImage* g_img = cvCreateImage( cvGetSize( src_rect),
  69. src_rect->depth, );
  70. IplImage* b_img = cvCreateImage( cvGetSize( src_rect),
  71. src_rect->depth, );
  72. IplImage* gray_img = cvCreateImage( cvGetSize( src_rect),
  73. src_rect->depth, );
  74.  
  75. // 分离RGB分量
  76. cvSplit( src_rect, r_img, g_img, b_img, NULL);
  77. cvShowImage( "red", r_img);
  78. cvShowImage( "green", g_img);
  79. cvShowImage( "blue", b_img);
  80.  
  81. // 灰度转换
  82. cvCvtColor( src_rect, gray_img, CV_BGR2GRAY);
  83. int size = ;
  84. float range[] = {, };
  85. float* ranges[] = {range};
  86. // 创建直方图
  87. CvHistogram * r_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
  88. CvHistogram * g_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
  89. CvHistogram * b_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
  90. CvHistogram * gray_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
  91.  
  92. // 直方图尺寸
  93. CvSize image_size = cvSize( , );
  94.  
  95. IplImage* r_dst = getHistImage(r_img, r_hist, image_size, cvScalar(0x00, 0x00, 0xff));
  96. IplImage* g_dst = getHistImage(g_img, g_hist, image_size, cvScalar(0x00, 0xff, 0x00));
  97. IplImage* b_dst = getHistImage(b_img, b_hist, image_size, cvScalar(0xff, 0x00, 0x00));
  98. IplImage* gray_dst = getHistImage( gray_img, gray_hist, image_size, cvScalar() );
  99.  
  100. // 把四个直方图在一幅图片上显示出来
  101. IplImage* dst = cvCreateImage( cvSize( image_size.width * , image_size.height * ), , );
  102. cvSetZero( dst );
  103. // 拷贝红色分量直方图
  104. CvRect r_rect = cvRect( , , image_size.width, image_size.height);
  105. cvSetImageROI(dst, r_rect);
  106. cvCopy( r_dst, dst);
  107. // 拷贝绿色分量直方图
  108. CvRect g_rect = cvRect(image_size.width, , image_size.width, image_size.height );
  109. cvSetImageROI( dst, g_rect);
  110. cvCopy( g_dst, dst);
  111. // 蓝色分量
  112. CvRect b_rect = cvRect(, image_size.height, image_size.width, image_size.height );
  113. cvSetImageROI(dst, b_rect);
  114. cvCopy( b_dst, dst );
  115. // 灰度分量
  116. CvRect gray_rect = cvRect( image_size.width, image_size.height,
  117. image_size.width, image_size.height );
  118. cvSetImageROI( dst, gray_rect);
  119. cvCopy( gray_dst, dst);
  120.  
  121. cvResetImageROI( dst );
  122.  
  123. cvShowImage( "src", src_rect);
  124. cvShowImage( "dst", dst );
  125.  
  126. cvWaitKey();
  127.  
  128. cvDestroyAllWindows();
  129. cvReleaseImage( &r_img );
  130. cvReleaseImage(&g_img);
  131. cvReleaseImage(&b_img);
  132. cvReleaseImage(&gray_img);
  133. cvReleaseImage(&r_dst);
  134. cvReleaseImage(&g_dst);
  135. cvReleaseImage(&b_dst);
  136. cvReleaseImage(&gray_dst);
  137. cvReleaseImage(&src_rect);
  138. cvReleaseImage(&dst);
  139. }
  140.  
  141. // 鼠标回调函数
  142. void my_mouse_callback( int event, int x, int y, int flags, void* param)
  143. {
  144. IplImage* image = (IplImage*) param;
  145.  
  146. switch( event )
  147. {
  148. case CV_EVENT_MOUSEMOVE:
  149. {
  150. if(draw)
  151. {
  152. rect.width = x - rect.x;
  153. rect.height = y - rect.y;
  154. }
  155.  
  156. draw_hist = false;
  157. }
  158. break;
  159. case CV_EVENT_LBUTTONDOWN:
  160. {
  161. draw = true;
  162. rect = cvRect( x, y, , );
  163. draw_hist = false;
  164. }
  165. break;
  166. case CV_EVENT_LBUTTONUP:
  167. {
  168. draw = false;
  169. draw_hist = true;
  170. if(rect.width < )
  171. {
  172. rect.x += rect.width;
  173. rect.width *= -;
  174. }
  175. if(rect.height < )
  176. {
  177. rect.y += rect.height;
  178. rect.height *= -;
  179. }
  180. // draw
  181. draw_rect(image, rect);
  182. }
  183. break;
  184. // 在右键按下时清除
  185. case CV_EVENT_RBUTTONDOWN:
  186. cvCopyImage(original, img);
  187. printf("clear.\n");
  188. break;
  189. }
  190. }
  191.  
  192. int main()
  193. {
  194. img = cvLoadImage( "lena.bmp", );
  195.  
  196. rect = cvRect( -, -, , );
  197.  
  198. // 副本
  199. temp = cvCloneImage( img );
  200. original = cvCloneImage(img);
  201.  
  202. cvNamedWindow("draw rect");
  203. cvSetMouseCallback("draw rect", my_mouse_callback, (void*)img);
  204.  
  205. while()
  206. {
  207. cvCopyImage(img, temp);
  208.  
  209. if(draw_hist)
  210. {
  211. draw_rect( temp , rect );
  212. }
  213.  
  214. cvShowImage( "draw rect", temp);
  215.  
  216. if(cvWaitKey() == )
  217. break;
  218. }
  219. cvReleaseImage(&img);
  220. cvReleaseImage(&temp);
  221. cvDestroyAllWindows();
  222.  
  223. return ;
  224. }

运行结果:

不足:在源图像上用鼠标选择矩形区域的时候,无法实时地在图像上反映出来。

《学习OpenCV》练习题第四章第三题b的更多相关文章

  1. 《学习OpenCV》练习题第四章第三题a

    #include <highgui.h> #include <cv.h> #include "opencv_libs.h" #pragma comment ...

  2. 《学习OpenCV》练习题第四章第八题ab

    这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...

  3. 《学习OpenCV》练习题第四章第七题abc

    题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事.现在开始补上. 这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环 ...

  4. OpenCV实现的高斯滤波探究_1(《学习OpenCV》练习题第五章第三题ab部分)

    首先看下OpenCV 官方文档对于cvSmooth各个参数的解释: Smooths the image in one of several ways. C: void cvSmooth(const C ...

  5. 《学习OpenCV》 第四章 习题六

    实现的是一个图像标签编辑器,其间遇到了些问题还未解决或者可能解决方法上不是最优,若你有更好的思路可以提供给我,大恩不言谢啦!!☆⌒(*^-゜)v. #include "stdafx.h&qu ...

  6. 《学习OpenCV》练习题第四章第一题b&c

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  7. 《学习OpenCV》练习题第四章第二题

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  8. 《学习OpenCV》练习题第四章第一题a

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  9. 学习opencv中文版教程——第二章

    学习opencv中文版教程——第二章 所有案例,跑起来~~~然而并没有都跑起来...我只把我能跑的都尽量跑了,毕竟看书还是很生硬,能运行能出结果,才比较好. 越着急,心越慌,越是着急,越要慢,越是陌生 ...

随机推荐

  1. 谈谈map中的count方法

    map和set两种容器的底层结构都是红黑树,所以容器中不会出现相同的元素,因此count()的结果只能为0和1,可以以此来判断键值元素是否存在(当然也可以使用find()方法判断键值是否存在). 拿m ...

  2. Java NIO读书笔记

    一.Java IO与NIO区别: (1)Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO ...

  3. No resource found that matches the given name

    XML里面明显已经定义了ID,可是android:layout_toLeftOf="@id/text_seller"报错,说没有定义,原来这玩意要写在相对位置对象声明的下面,是有顺 ...

  4. hdu 4405 Aeroplane chess(简单概率dp 求期望)

    Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  5. eclipse中字母大小写转换快捷键

    ctrl+shift+x   转为大写 ctrl+shift+y   转为小写

  6. GUI for git|SourceTree|入门基础

    原文链接:http://www.jianshu.com/p/be9f0484af9d 目录 SourceTree简介 SourceTree基本使用 SourceTree&Git部分名词解释 相 ...

  7. PHP学习笔记02——简易计算器

    <!DOCTYPE html> <html> <head> <title>PHP简易计算器</title> </head> &l ...

  8. 长期演进技术(LTE,Long Term Evolution)

    /********************************************************************************* * 长期演进技术(LTE,Long ...

  9. hihoCoder #1174 : 拓扑排序·一 (判断循环图)

    G++ 261ms 13MB 题意: 给出n门课程的修读所需要的前置课程的关系,按理说应该是个拓扑图,但是因为某些原因导致了混乱,所以有可能不是一个拓扑图.现在的问题是,判断该图是否为一个拓扑图(即无 ...

  10. ios协议调起app

    function openIos(url, callback) { if (!url) { return; } var node = document.createElement('iframe'); ...