OPENCV中画图像直方图(带刻度并可以通过滚动条调节直方图中直方条的个数)
2015-12-14 17:15
323 查看
OPENCV中画图像直方图(带刻度并可以通过滚动条调节直方图中直方条的个数)
本文是在《OpenCV教程基础篇》例题5-11的基础上进行的修改。
本文亮点:
(1)可以通过调节滚动条,来实现调节直方图中输出直方条的个数;
(2)在输出的直方图中添加了横纵坐标刻度,并且这些刻度可以随着滚动条的调节自适应改变。
效果如下:
1.分成50条:
2.分成256条:
上面是老版本的代码,2.0版本的代码采用了Mat图像存储方式,新代码如下:
OPENCV中画图像直方图(带刻度并可以通过滚动条调节直方图中直方条的个数)
本文是在《OpenCV教程基础篇》例题5-11的基础上进行的修改。
本文亮点:
(1)可以通过调节滚动条,来实现调节直方图中输出直方条的个数;
(2)在输出的直方图中添加了横纵坐标刻度,并且这些刻度可以随着滚动条的调节自适应改变。
#include "cv.h" #include "highgui.h" #include <stdio.h> #include <ctype.h> using namespace std; using namespace cv; IplImage *src = 0; IplImage *histimg = 0; CvHistogram *hist = 0; int hdims = 50; // 划分HIST的初始个数,越高越精确 //滚动条函数 void HIST(int t) { float hranges_arr[] = {0,255}; float* hranges = hranges_arr; int bin_w; int bin_u; float max; int i; char string[10]; CvFont font; cvInitFont( &font, CV_FONT_HERSHEY_PLAIN,1, 1, 0, 1, 8);//字体结构初始化 if(hdims==0) { printf("直方图条数不能为零!\n"); } else { hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); // 创建直方图 histimg = cvCreateImage(cvSize(800,512),8,3); cvZero( histimg ); cvCalcHist( &src, hist, 0, 0 ); // 计算直方图 cvGetMinMaxHistValue(hist,NULL,&max,NULL,NULL);//寻找最大值及其位置 //printf("max_val:%f \n",max_val); cvZero( histimg ); double bin_w =(double) histimg->width / hdims; // hdims: 条的个数,则 bin_w 为条的宽度 double bin_u = (double)histimg->height/ max; //// max: 最高条的像素个数,则 bin_u 为单个像素的高度 // 画直方图 for(int i=0;i<hdims;i++) { CvPoint p0=cvPoint(i*bin_w,histimg->height); int val=cvGetReal1D(hist->bins,i); CvPoint p1=cvPoint((i+1)*bin_w,histimg->height-cvGetReal1D(hist->bins,i)*bin_u); cvRectangle(histimg,p0,p1,cvScalar(0,255),1,8,0); } //画纵坐标刻度(像素个数) int kedu=0; for(int i=1;kedu<max;i++) { kedu=i*max/10; itoa(kedu,string,10);//把一个整数转换为字符串 //在图像中显示文本字符串 cvPutText(histimg, string , cvPoint(0,histimg->height-kedu*bin_u), &font, CV_RGB(0,255,255)); } //画横坐标刻度(像素灰度值) kedu=0; for(int i=1;kedu<256;i++) { kedu=i*20; itoa(kedu,string,10);//把一个整数转换为字符串 //在图像中显示文本字符串 cvPutText(histimg, string , cvPoint(kedu*(histimg->width / 256),histimg->height), &font, CV_RGB(255,0,0)); } cvShowImage( "Histogram", histimg ); } } int main( int argc, char** argv ) { argc=2; argv[1]="lena.jpg"; if( argc != 2 || (src=cvLoadImage(argv[1], 0)) == NULL) // force to gray image return -1; cvNamedWindow( "src", 1); cvShowImage( "src", src); cvNamedWindow( "Histogram", 1 ); cvCreateTrackbar( "hdims", "src", &hdims, 256, HIST ); HIST(0); cvWaitKey(0); cvDestroyWindow("src"); cvDestroyWindow("Histogram"); cvReleaseImage( &src ); cvReleaseImage( &histimg ); cvReleaseHist ( &hist ); return 0; }
效果如下:
1.分成50条:
2.分成256条:
上面是老版本的代码,2.0版本的代码采用了Mat图像存储方式,新代码如下:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; /* 全局变量的声明及初始化 */ Mat srcImage; //读入的图片矩阵 Mat dstImage; //读入的图片矩阵 MatND dstHist; //直方图矩阵,对应老版本中的cvCreateHist() int g_hdims = 50; // 划分HIST的初始个数,越高越精确 /* 回调函数声明 */ void on_HIST(int t,void *); /* 主函数 */ int main( int argc, char** argv ) { srcImage=imread("lena.jpg",0);//"0"表示读入灰度图像 namedWindow( "原图", 1 );//对应老版本中的cvNamedWindow( ) imshow("原图",srcImage);//对应老版本中的 cvShowImage() createTrackbar( "hdims", "原图", &g_hdims, 256, on_HIST);//对应旧版本中的cvCreateTrackbar( ); on_HIST(0,0);//调用滚动条回调函数 cvWaitKey(0); return 0; } /* 滚动条回调函数 */ void on_HIST(int t,void *) { dstImage=Mat::zeros(512,800,CV_8UC3);//每次都要初始化 float hranges[]={0,255}; //灰度范围 const float *ranges[]={hranges};//灰度范围的指针 if(g_hdims==0) { printf("直方图条数不能为零!\n"); } else { /* srcImage:读入的矩阵 1:数组的个数为1 0:因为灰度图像就一个通道,所以选0号通道 Mat():表示不使用掩膜 dstHist:输出的目标直方图 1:需要计算的直方图的维度为1 g_hdims:划分HIST的个数 ranges:表示每一维度的数值范围 */ //int channels=0; calcHist( &srcImage,1,0, Mat(),dstHist,1,&g_hdims,ranges); // 计算直方图对应老版本的cvCalcHist /* 获取最大最小值 */ double max=0; minMaxLoc(dstHist,NULL,&max,0,0);// 寻找最大值及其位置,对应旧版本的cvGetMinMaxHistValue(); /* 绘出直方图 */ double bin_w =(double) dstImage.cols/g_hdims; // hdims: 条的个数,则 bin_w 为条的宽度 double bin_u = (double)dstImage.rows/ max; //// max: 最高条的像素个数,则 bin_u 为单个像素的高度 // 画直方图 for(int i=0;i<g_hdims;i++) { Point p0=Point(i*bin_w,dstImage.rows);//对应旧版本中的cvPoint() int val=dstHist.at<float>(i);//注意一点要用float类型,对应旧版本中的 cvGetReal1D(hist->bins,i); Point p1=Point((i+1)*bin_w,dstImage.rows-val*bin_u); rectangle(dstImage,p0,p1,cvScalar(0,255),1,8,0);//对应旧版中的cvRectangle(); } /* 画刻度 */ char string[12];//存放转换后十进制数,转化成十进制后的位数不超过12位,这个根据情况自己设定 //画纵坐标刻度(像素个数) int kedu=0; for(int i=1;kedu<max;i++) { kedu=i*max/10;//此处选择10个刻度 itoa(kedu,string,10);//把一个整数转换为字符串,这个当中的10指十进制 //在图像中显示文本字符串 putText(dstImage, string , Point(0,dstImage.rows-kedu*bin_u), 1,1,Scalar(0,255,255));//对应旧版中的cvPutText() } //画横坐标刻度(像素灰度值) kedu=0; for(int i=1;kedu<256;i++) { kedu=i*20;//此处选择间隔为20 itoa( 4000 kedu,string,10);//把一个整数转换为字符串 //在图像中显示文本字符串 putText(dstImage, string , cvPoint(kedu*(dstImage.cols / 256),dstImage.rows),1,1,Scalar(0,255,255)); } namedWindow( "Histogram", 1 ); imshow( "Histogram", dstImage ); } }
相关文章推荐
- CentOS 6.5 下 QT4 连接 mysql 数据库的步骤
- Linux中线程与CPU核的绑定
- cairo库网站
- linux 实现VLAN
- BeanUtils.copyProperties扩展--String转Date
- CAS (3) —— Mac下配置CAS客户端经代理访问Tomcat CAS
- tomcat配置文件server.xml详解
- 虚拟环境下搭建hadoop之一——搭建前的准备
- ubuntu nsight上链接OpenGL
- nginx反向代理docker registry报”blob upload unknown"解决办法
- 为什么margin-top不是作用于父元素
- CENTOS 6.5 配置YUM安装NGINX
- CentOS 6.5 下安装配置 mysql
- 弹出窗体PopupWindow的使用
- 在win7下查看linux的Ext2/3/4格式的分区
- 企业生产环境不同业务的Linux分区方案
- nginx 虚拟目录反向代理tomcat 应用程序
- 关于WOPI discovery内容的获取方法
- df、du、fdisk:Linux磁盘管理命令整理
- HDU 2577 dp 输入法切换最小次 两数组维护两种状态