#include "cv.h"
#include "highgui.h"
//*****************************************************
//画直方图函数:根据输入图像,显示HSV二维直方图
//src :指向输入图像的指针
//h_bins :H分量(hue色调)在直方图里划分的等级
//s_bins :S分量(saturation饱和度)在直方图里划分的等级
//scale :直方图每个矩形的宽度
//width :直方图的宽度
//height :直方图的高度
//srcname[] :用于储存载入源图像窗口的名字
//histname[] :用于储存显示直方图图像的窗口的名字
//返回值hist :指向生成的直方图的指针
//*****************************************************
CvHistogram* myHSVHistogram( IplImage* src, int h_bins, int s_bins, int scale, int width, int height, const char srcname[], const char histname[] )
{
if (src==NULL || src->nChannels!=3)
{
return NULL;
}
/*hsv图像初始化*/
IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 );
IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* planes[] = { h_plane, s_plane };
/*H分量(hue色调)划分等级,S分量(saturation饱和度)划分等级*/
int hist_size[] = { h_bins, s_bins };
/*H分量、S分量的变化范围*/
float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };
/*输入图像转换到HSV颜色空间,并将h、s、v分别分割到各自的单通道图像上*/
cvCvtColor( src, hsv, CV_BGR2HSV );
cvSplit( hsv, h_plane, s_plane, v_plane, 0 );
/*创建直方图,二维, 每个维度上均分*/
CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
/*根据H、S两个平面数据统计planes图像的直方图*/
cvCalcHist( planes, hist, 0, 0 );
/*获取直方图统计的最大值,用于动态显示直方图*/
float max_value;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
/*设置直方图显示图像的高度、宽度*/
IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );
cvZero( hist_img );
/*用来进行HSV到RGB颜色转换的临时单位图像*/
IplImage* hsv_color = cvCreateImage(cvSize(1,1),8,3); //单位图像,相当于一个8bit、3通道的像素点
IplImage* rgb_color = cvCreateImage(cvSize(1,1),8,3);
/*for循环显示矩形*/
for (int h=0; h<h_bins; h++) //循环画色调直方图
{
for (int s=0; s<s_bins; s++) //在每个画色调直方图循环中,循环画饱和度直方图
{
int i = h*s_bins+s; //直方图中某一矩形的序号(从左到右,由大到小,从0开始)
float bin_val = cvQueryHistValue_2D( hist, h, s ); //获得某一直方图矩形的数值,即统计数值
int intensity = cvRound( bin_val*height/max_value ); //四舍五入,计算显示在图像中的矩形高度
cvSet2D( hsv_color, 0, 0, cvScalar( h*180.f/h_bins, s*255.f/s_bins, 255, 0));
cvCvtColor( hsv_color, rgb_color, CV_HSV2BGR ); //为hsv像素点设置颜色(颜色设置使用了归一化),并转换为rgb格式
CvScalar color = cvGet2D( rgb_color, 0, 0 );
cvRectangle( //画矩形
hist_img,
cvPoint( i*scale, height ), //起点横坐标为第i个矩形乘以每个矩形宽度,纵坐标为图像高度,即图像底部
cvPoint( (i+1)*scale, height-intensity ), //终点横坐标为矩形宽度,纵坐标为图像底减去矩形高度,令矩形显示在底部
color,
CV_FILLED, //填充矩形
8,
0 );
}
}
/*显示源图像与直方图*/
cvNamedWindow( srcname, CV_WINDOW_NORMAL );
cvShowImage( srcname, src );
cvNamedWindow( histname, CV_WINDOW_AUTOSIZE );
cvShowImage( histname, hist_img );
return hist;
}
//*****************************************************
//主函数
//*****************************************************
int main()
{
/*载入图像并检测*/
IplImage* image = cvLoadImage( "E:\\...\\hand_1.jpg", CV_LOAD_IMAGE_COLOR );
assert(image != NULL);
/*显示直方图的变量初始化*/
int h_bins = 18; //180平均分成18份
int s_bins = 8; //256平均分成8份
int scale = 8; //每个矩形宽度为8
int width = (h_bins*s_bins)*scale;
int height = 300;
/*创建图像的直方图,并调用我的直方图画图函数画出直方图*/
CvHistogram* hist;
hist = myHSVHistogram( image, h_bins, s_bins, scale, width, height, "hand_1", "hist_image_1" );
/*将图像1分割成3幅单通道的BGR图像*/
IplImage* b_plane = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );
IplImage* g_plane = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );
IplImage* r_plane = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );
cvSplit( image, b_plane, g_plane, r_plane, 0 );
IplImage* planes[] = { g_plane, r_plane };
IplImage* backProject = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );
/*根据源图像每个像素的坐标(i,j)与在直方图中的值bin(hij,sij),重新组成一幅图像backProject*/
cvCalcBackProject( planes, backProject, hist );
/*通过腐蚀运算,输出显示图像*/
cvErode( backProject, backProject );
cvNamedWindow( "backProject", CV_WINDOW_NORMAL );
cvShowImage( "backProject", backProject );
cvWaitKey(0);
cvReleaseImage( &image );
cvReleaseImage( &b_plane );
cvReleaseImage( &g_plane );
cvReleaseImage( &r_plane );
cvReleaseImage( &backProject );
cvReleaseHist( &hist );
cvDestroyAllWindows();
return 0;
}
《学习OpenCV》练习7-6
最新推荐文章于 2024-09-06 22:13:45 发布