改进实例1——加一个进度条控制横坐标bin
#include <opencv2/opencv.hpp>#include <iostream> using namespace std; #define cvQueryHistValue_1D( hist, idx0 ) ((float)cvGetReal1D( (hist)->bins, (idx0)))int hist_size= 200; //直方图横坐标——binint hist_height= 300; ////直方图纵坐标——随意定void on_trackbar( int pos ) ;void main( ) { iplImage * src= cvLoadImage("b.jpg"); IplImage* gray_plane = cvCreateImage(cvGetSize(src),8,1); cvCvtColor(src,gray_plane,CV_BGR2GRAY); float range[] = {0,255}; //灰度级的范围 float* ranges[]={range}; //就是用指针指向这个数组, //然后这个指针就能访问和控制这个数组了。 cvNamedWindow( "H-S Histogram", CV_WINDOW_AUTOSIZE ); cvNamedWindow( "GraySource", CV_WINDOW_AUTOSIZE ); while(1) { cvCreateTrackbar( "position", "H-S Histogram",&hist_size,255, on_trackbar );//滑块位置的最大值为180.//on_trackbar(0);——本来有这句话,怎么运行都不成功,后来发现,根本不需要好不好。cvCreateTrackbar函数运行的时候自己就会调用on_trackbar()函数。 cout <<hist_size<< endl; CvHistogram* gray_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1); //计算灰度图像的一维直方图 cvCalcHist(&gray_plane,gray_hist,0,0); //归一化直方图 cvNormalizeHist(gray_hist,1.0); int scale = 3; //创建一张一维直方图的“图”,横坐标为bin IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale,hist_height),8,3); cvZero(hist_image); //统计直方图中的最大直方块 float max_value = 0; cvGetMinMaxHistValue(gray_hist, 0,&max_value,0,0); //分别将每个直方块的值绘制到图中 for(int i=0;i<hist_size;i++) { float bin_val = cvQueryHistValue_1D(gray_hist,i); int intensity = cvRound(bin_val*hist_height/max_value); //要绘制的高度 cvRectangle(hist_image, cvPoint(i*scale,hist_height-1), cvPoint((i+1)*scale - 1, hist_height - intensity), CV_RGB(255,255,255)); } cvShowImage("GraySource",gray_plane); cvShowImage( "H-S Histogram", hist_image ); if (cvWaitKey(0) == 27)break; } cvDestroyAllWindows();}void on_trackbar( int pos ) //定义一个回调函数——pos是形参,随便起一个名字{ hist_size=pos;}程序运行时的问题 运行这个程序的时候,发现怎么改变滑块的值,直方图根本不变化。后来才发现,按下滑块之后,还要按【回车】键,直方图才会变化。 ——不知道为什么,也没百度到答案。 while(1)是要有的,本来就是为了能够实时刷新显示直方图——结果还需要配合手动按回车键,呵呵。
改进实例2:进度条控制hsv格式的h通道的直方图 还是需要按下滑块之后,再按【回车】键,直方图才会变化。
#include <opencv2/opencv.hpp>#include <iostream> using namespace std; #define cvQueryHistValue_1D( hist, idx0 ) ((float)cvGetReal1D( (hist)->bins, (idx0)))int hist_size= 200; //直方图横坐标——binint hist_height= 300; //直方图纵坐标——随意定void on_trackbar( int pos ) ;int main(int argc, char** argv){ IplImage * src= cvLoadImage("b.jpg"); IplImage* hsv = cvCreateImage(cvGetSize(src), 8, 3); cvCvtColor(src, hsv, CV_BGR2HSV); IplImage* h_plane = cvCreateImage(cvGetSize(src), 8, 1); IplImage* s_plane = cvCreateImage(cvGetSize(src), 8, 1); IplImage* v_plane = cvCreateImage(cvGetSize(src), 8, 1); cvSplit(hsv, h_plane, s_plane, v_plane, 0); float range[] = {0,255}; //灰度级的范围 float* ranges[]={range}; //就是用指针指向这个数组,然后这个指针就能访问和控制这个数组了。 cvNamedWindow( "H-S Histogram", CV_WINDOW_AUTOSIZE ); cvNamedWindow( "GraySource", CV_WINDOW_AUTOSIZE ); while(1) { cvCreateTrackbar( "position", "H-S Histogram",&hist_size,255, on_trackbar );//滑块位置的最大值为180.// cout <<hist_size<< endl; CvHistogram* h_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1); //计算灰度图像的一维直方图 cvCalcHist(&h_plane,h_hist,0,0); //归一化直方图 cvNormalizeHist(h_hist,1.0); int scale = 3; IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale,hist_height),8,3); cvZero(hist_image); //统计直方图中的最大直方块 float max_value = 0; cvGetMinMaxHistValue(h_hist, 0,&max_value,0,0); //分别将每个直方块的值绘制到图中 for(int i=0;i<hist_size;i++) { float bin_val = cvQueryHistValue_1D(h_hist,i); //像素i的概率 int intensity = cvRound(bin_val*hist_height/max_value); //要绘制的高度 cvRectangle(hist_image, cvPoint(i*scale,hist_height-1), cvPoint((i+1)*scale - 1, hist_height - intensity), CV_RGB(255,255,255)); } cvShowImage("GraySource",h_plane); cvShowImage( "H-S Histogram", hist_image ); if (cvWaitKey(0) == 27)break; } cvDestroyAllWindows();} void on_trackbar( int pos ) //定义一个回调函数——pos是形参,随便起一个名字{ hist_size=pos;}新闻热点
疑难解答