#include <highgui.h>
#include <cv.h>
#include "opencv_libs.h" /*
*《学习OpenCV》第四章第三题b
* 完成时间:1:36 3/31 星期日 2013
*/ /* 矩形框 */
CvRect rect; bool draw = false; // 标记是否在画 IplImage* img;
IplImage * temp;
IplImage * original; bool draw_hist = false; IplImage* getHistImage(IplImage* image, CvHistogram* image_hist,
CvSize image_size, CvScalar value)
{
// 计算直方图
cvCalcHist( &image, image_hist, , NULL );
// 新建一幅3通道的图像
IplImage* dst = cvCreateImage(image_size, IPL_DEPTH_8U, ); cvSet( dst, cvScalarAll() ); float max_value = ;
cvGetMinMaxHistValue( image_hist, NULL, &max_value, NULL, NULL );
double bin_width = (double)dst->width/;
double bin_unith = (double)dst->height/max_value; // 高度比例 for(int i = ; i < ; i++)
{
// 获得矩形左上角和右下角坐标
CvPoint p0 = cvPoint( i + bin_width, dst->height );
CvPoint p1 = cvPoint( (i+) * bin_width,
dst->height - cvGetReal1D(image_hist->bins, i) * bin_unith );
// 画实心矩形
cvRectangle( dst, p0, p1, value, -, , );
} return dst;
} void draw_rect(IplImage* img, CvRect rect)
{
cvRectangle( img,
cvPoint( rect.x, rect.y ),
cvPoint( rect.x + rect.width, rect.y + rect.height),
cvScalar( 0x00, 0x00, 0xff) );
printf("draw\n"); // 在这里处理直方图
// 设置感兴趣区域
cvSetImageROI( img, rect);
IplImage* src_rect = cvCreateImage (
cvSize( rect.width, rect.height ),
img->depth, img->nChannels );
cvCopy(img, src_rect );
cvResetImageROI( img ); IplImage* r_img = cvCreateImage( cvGetSize( src_rect),
src_rect->depth, );
IplImage* g_img = cvCreateImage( cvGetSize( src_rect),
src_rect->depth, );
IplImage* b_img = cvCreateImage( cvGetSize( src_rect),
src_rect->depth, );
IplImage* gray_img = cvCreateImage( cvGetSize( src_rect),
src_rect->depth, ); // 分离RGB分量
cvSplit( src_rect, r_img, g_img, b_img, NULL);
cvShowImage( "red", r_img);
cvShowImage( "green", g_img);
cvShowImage( "blue", b_img); // 灰度转换
cvCvtColor( src_rect, gray_img, CV_BGR2GRAY);
int size = ;
float range[] = {, };
float* ranges[] = {range};
// 创建直方图
CvHistogram * r_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
CvHistogram * g_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
CvHistogram * b_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, );
CvHistogram * gray_hist = cvCreateHist( , &size, CV_HIST_ARRAY, ranges, ); // 直方图尺寸
CvSize image_size = cvSize( , ); IplImage* r_dst = getHistImage(r_img, r_hist, image_size, cvScalar(0x00, 0x00, 0xff));
IplImage* g_dst = getHistImage(g_img, g_hist, image_size, cvScalar(0x00, 0xff, 0x00));
IplImage* b_dst = getHistImage(b_img, b_hist, image_size, cvScalar(0xff, 0x00, 0x00));
IplImage* gray_dst = getHistImage( gray_img, gray_hist, image_size, cvScalar() ); // 把四个直方图在一幅图片上显示出来
IplImage* dst = cvCreateImage( cvSize( image_size.width * , image_size.height * ), , );
cvSetZero( dst );
// 拷贝红色分量直方图
CvRect r_rect = cvRect( , , image_size.width, image_size.height);
cvSetImageROI(dst, r_rect);
cvCopy( r_dst, dst);
// 拷贝绿色分量直方图
CvRect g_rect = cvRect(image_size.width, , image_size.width, image_size.height );
cvSetImageROI( dst, g_rect);
cvCopy( g_dst, dst);
// 蓝色分量
CvRect b_rect = cvRect(, image_size.height, image_size.width, image_size.height );
cvSetImageROI(dst, b_rect);
cvCopy( b_dst, dst );
// 灰度分量
CvRect gray_rect = cvRect( image_size.width, image_size.height,
image_size.width, image_size.height );
cvSetImageROI( dst, gray_rect);
cvCopy( gray_dst, dst); cvResetImageROI( dst ); cvShowImage( "src", src_rect);
cvShowImage( "dst", dst ); cvWaitKey(); cvDestroyAllWindows();
cvReleaseImage( &r_img );
cvReleaseImage(&g_img);
cvReleaseImage(&b_img);
cvReleaseImage(&gray_img);
cvReleaseImage(&r_dst);
cvReleaseImage(&g_dst);
cvReleaseImage(&b_dst);
cvReleaseImage(&gray_dst);
cvReleaseImage(&src_rect);
cvReleaseImage(&dst);
} // 鼠标回调函数
void my_mouse_callback( int event, int x, int y, int flags, void* param)
{
IplImage* image = (IplImage*) param; switch( event )
{
case CV_EVENT_MOUSEMOVE:
{
if(draw)
{
rect.width = x - rect.x;
rect.height = y - rect.y;
} draw_hist = false;
}
break;
case CV_EVENT_LBUTTONDOWN:
{
draw = true;
rect = cvRect( x, y, , );
draw_hist = false;
}
break;
case CV_EVENT_LBUTTONUP:
{
draw = false;
draw_hist = true;
if(rect.width < )
{
rect.x += rect.width;
rect.width *= -;
}
if(rect.height < )
{
rect.y += rect.height;
rect.height *= -;
}
// draw
draw_rect(image, rect);
}
break;
// 在右键按下时清除
case CV_EVENT_RBUTTONDOWN:
cvCopyImage(original, img);
printf("clear.\n");
break;
}
} int main()
{
img = cvLoadImage( "lena.bmp", ); rect = cvRect( -, -, , ); // 副本
temp = cvCloneImage( img );
original = cvCloneImage(img); cvNamedWindow("draw rect");
cvSetMouseCallback("draw rect", my_mouse_callback, (void*)img); while()
{
cvCopyImage(img, temp); if(draw_hist)
{
draw_rect( temp , rect );
} cvShowImage( "draw rect", temp); if(cvWaitKey() == )
break;
}
cvReleaseImage(&img);
cvReleaseImage(&temp);
cvDestroyAllWindows(); return ;
}

运行结果:

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

《学习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. Java中什么时候使用构造方法

    JAVA是面向对象的语言,面向对象不是这么直接简单,它的设计思想就是要代码重用.即我以前干过类似的事,那么我找出以前可以用到的代码,完成一部分.以前没有的我重新写.这样就有了类.有了类,就是有了可以重 ...

  2. [CCF2015.09]题解

    201509-1 数列分段 水,记下前一个数,看看跟当前是否一样,不一样就ans+1 #include <algorithm> #include <iostream> #inc ...

  3. ASP.NET MVC3 实例(六) 增加、修改和删除操作(二)

    http://www.jquery001.com/asp.net-mvc3-instance-add-update-delete2.html 上篇我们在 ASP.NET MVC3 中实现了添加操作,由 ...

  4. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  5. 【笨嘴拙舌WINDOWS】计时器精度

    WINDOWS的大多数系统并非实时操作系统,所以不能规定计算机在某个精确到纳秒的时间让计算机做某项任务,如果规定了时间WINDOWS也将需要在完成了线程调度后,经行任务执行! 也就是说,如果你的应用程 ...

  6. LA 2678 Subsequence

    有一个正整数序列,求最短的子序列使得其和大于等于S,并输出最短的长度. 用数组b[i]存放序列的前i项和,所以b[i]是递增的. 遍历终点j,然后在区间[0, j)里二分查找满足b[j]-b[i]≥S ...

  7. C++实现日期类(Date类)

    #include<iostream>using namespace std;class Date{public:    Date(int year = 1900, int month = ...

  8. python执行mysqldump命令

    本文简单讲述如何利用python执行一些sql语句,例如执行mysqldump命令,进行数据库备份,备份成sql文件 #!/usr/bin/python#导入os模块import os#导入时间模块i ...

  9. LeetCode Binary Tree Maximum Path Sum 二叉树最大路径和(DFS)

    题意:给一棵二叉树,要求找出任意两个节点(也可以只是一个点)的最大路径和,至少1个节点,返回路径和.(点权有负的.) 思路:DFS解决,返回值是,经过从某后代节点上来到当前节点且路径和最大的值.要注意 ...

  10. int (*(*fp)(void *))[10]; 指向函数的指针类型

    <pre lang="c" escaped="true">int (*(*fp)(void *))[10]; //这个类型用typedef分解出来 ...