彩色图像直方图均衡化及颜色直方图显示 opencv实现 完整代码及详细注释
2013-06-21 15:59
956 查看
结果预览:
原图片:
颜色直方图:
直方图均衡化后:
颜色直方图:
完整代码:
运行环境:Win7 64位 / opencv2.3 / vs2010
[cpp]
view plaincopyprint?
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <fstream>
#include <string>
#include <iostream>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace std;
void myShowHist(IplImage* image1,IplImage* image2);
IplImage* cvShowHist(IplImage* src);
int main()
{
//对彩色图像进行均衡化
IplImage * image= cvLoadImage("lena.jpg");
IplImage* eqlimage=cvCreateImage(cvGetSize(image),image->depth,3);
//信道分离
IplImage* redImage=cvCreateImage(cvGetSize(image),image->depth,1);
IplImage* greenImage=cvCreateImage(cvGetSize(image),image->depth,1);
IplImage* blueImage=cvCreateImage(cvGetSize(image),image->depth,1);
cvSplit(image,blueImage,greenImage,redImage,NULL);//用 cvSplit 函数分解图像到单个色彩通道上
/*
cvNamedWindow("red",CV_WINDOW_AUTOSIZE);
cvNamedWindow("green",CV_WINDOW_AUTOSIZE);
cvNamedWindow("blue",CV_WINDOW_AUTOSIZE);
cvShowImage("red",redImage);
cvShowImage("green",greenImage);
cvShowImage("blue",blueImage);
*/
//cvEqualizeHist()是适用于灰度图象直方图均衡化,所以必须先将图片分解到单通道上
//分别均衡化每个信道
cvEqualizeHist(redImage,redImage);
cvEqualizeHist(greenImage,greenImage);
cvEqualizeHist(blueImage,blueImage);
/*
cvNamedWindow("red2",CV_WINDOW_AUTOSIZE);
cvNamedWindow("green2",CV_WINDOW_AUTOSIZE);
cvNamedWindow("blue2",CV_WINDOW_AUTOSIZE);
cvShowImage("red2",redImage);
cvShowImage("green2",greenImage);
cvShowImage("blue2",blueImage);
*/
//信道合并
cvMerge(blueImage,greenImage,redImage,NULL,eqlimage);
//显示图片和直方图
cvNamedWindow( "source", 1 );
cvShowImage("source",image);
cvNamedWindow( "Equalized", 1 );
cvShowImage("Equalized",eqlimage);
cvSaveImage("equalized.jpg",eqlimage);
myShowHist(image,eqlimage);
cvWaitKey(0);
cvDestroyWindow("source");
cvDestroyWindow("result");
cvReleaseImage( &image );
cvReleaseImage( &eqlimage );
}
void myShowHist(IplImage* image1,IplImage* image2)
{
IplImage* hist_image1=cvShowHist(image1);
IplImage* hist_image2=cvShowHist(image2);
cvNamedWindow( "H-S Histogram1", 1 );
cvShowImage( "H-S Histogram1", hist_image1 );
cvNamedWindow( "H-S Histogram2", 1 );
cvShowImage( "H-S Histogram2", hist_image2 );
cvSaveImage("Histogram1.jpg",hist_image1);
cvSaveImage("Histogram2.jpg",hist_image2);
}
IplImage* cvShowHist(IplImage* src)
{
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 分量划分为16个等级,S分量划分为8个等级 */
int h_bins = 16, s_bins = 8;
int hist_size[] = {h_bins, s_bins};
/** H 分量的变化范围 */
float h_ranges[] = { 0, 180 };
/** S 分量的变化范围*/
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };
/** 输入图像转换到HSV颜色空间 */
cvCvtColor( src, hsv, CV_BGR2HSV );
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );
/** 创建直方图,二维, 每个维度上均分 */
CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
/** 根据H,S两个平面数据统计直方图 */
cvCalcHist( planes, hist, 0, 0 );
/** 获取直方图统计的最大值,用于动态显示直方图 */
float max_value;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
/** 设置直方图显示图像 */
int height = 240;
int width = (h_bins*s_bins*6);
IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );
cvZero( hist_img );
/** 用来进行HSV到RGB颜色转换的临时单位图像 */
IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3);
IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3);
int bin_w = width / (h_bins * s_bins);
for(int h = 0; h < h_bins; h++)
{
for(int s = 0; s < s_bins; s++)
{
int i = h*s_bins + s;
/** 获得直方图中的统计次数,计算显示在图像中的高度 */
float bin_val = cvQueryHistValue_2D( hist, h, s );
int intensity = cvRound(bin_val*height/max_value);
/** 获得当前直方图代表的颜色,转换成RGB用于绘制 */
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);
CvScalar color = cvGet2D(rgb_color,0,0);
cvRectangle( hist_img, cvPoint(i*bin_w,height),
cvPoint((i+1)*bin_w,height - intensity),
color, -1, 8, 0 );
}
}
return hist_img;
}
参考链接:
[1]http://blog.csdn.net/xiaowei_cqu/article/details/7606607
[2]http://www.opencv.org.cn/index.php/%E5%9B%BE%E5%83%8F%E9%A2%9C%E8%89%B2%E5%88%86%E5%B8%83%E7%9B%B4%E6%96%B9%E5%9B%BE
原图片:
颜色直方图:
直方图均衡化后:
颜色直方图:
完整代码:
运行环境:Win7 64位 / opencv2.3 / vs2010
[cpp]
view plaincopyprint?
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <fstream>
#include <string>
#include <iostream>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace std;
void myShowHist(IplImage* image1,IplImage* image2);
IplImage* cvShowHist(IplImage* src);
int main()
{
//对彩色图像进行均衡化
IplImage * image= cvLoadImage("lena.jpg");
IplImage* eqlimage=cvCreateImage(cvGetSize(image),image->depth,3);
//信道分离
IplImage* redImage=cvCreateImage(cvGetSize(image),image->depth,1);
IplImage* greenImage=cvCreateImage(cvGetSize(image),image->depth,1);
IplImage* blueImage=cvCreateImage(cvGetSize(image),image->depth,1);
cvSplit(image,blueImage,greenImage,redImage,NULL);//用 cvSplit 函数分解图像到单个色彩通道上
/*
cvNamedWindow("red",CV_WINDOW_AUTOSIZE);
cvNamedWindow("green",CV_WINDOW_AUTOSIZE);
cvNamedWindow("blue",CV_WINDOW_AUTOSIZE);
cvShowImage("red",redImage);
cvShowImage("green",greenImage);
cvShowImage("blue",blueImage);
*/
//cvEqualizeHist()是适用于灰度图象直方图均衡化,所以必须先将图片分解到单通道上
//分别均衡化每个信道
cvEqualizeHist(redImage,redImage);
cvEqualizeHist(greenImage,greenImage);
cvEqualizeHist(blueImage,blueImage);
/*
cvNamedWindow("red2",CV_WINDOW_AUTOSIZE);
cvNamedWindow("green2",CV_WINDOW_AUTOSIZE);
cvNamedWindow("blue2",CV_WINDOW_AUTOSIZE);
cvShowImage("red2",redImage);
cvShowImage("green2",greenImage);
cvShowImage("blue2",blueImage);
*/
//信道合并
cvMerge(blueImage,greenImage,redImage,NULL,eqlimage);
//显示图片和直方图
cvNamedWindow( "source", 1 );
cvShowImage("source",image);
cvNamedWindow( "Equalized", 1 );
cvShowImage("Equalized",eqlimage);
cvSaveImage("equalized.jpg",eqlimage);
myShowHist(image,eqlimage);
cvWaitKey(0);
cvDestroyWindow("source");
cvDestroyWindow("result");
cvReleaseImage( &image );
cvReleaseImage( &eqlimage );
}
void myShowHist(IplImage* image1,IplImage* image2)
{
IplImage* hist_image1=cvShowHist(image1);
IplImage* hist_image2=cvShowHist(image2);
cvNamedWindow( "H-S Histogram1", 1 );
cvShowImage( "H-S Histogram1", hist_image1 );
cvNamedWindow( "H-S Histogram2", 1 );
cvShowImage( "H-S Histogram2", hist_image2 );
cvSaveImage("Histogram1.jpg",hist_image1);
cvSaveImage("Histogram2.jpg",hist_image2);
}
IplImage* cvShowHist(IplImage* src)
{
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 分量划分为16个等级,S分量划分为8个等级 */
int h_bins = 16, s_bins = 8;
int hist_size[] = {h_bins, s_bins};
/** H 分量的变化范围 */
float h_ranges[] = { 0, 180 };
/** S 分量的变化范围*/
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };
/** 输入图像转换到HSV颜色空间 */
cvCvtColor( src, hsv, CV_BGR2HSV );
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );
/** 创建直方图,二维, 每个维度上均分 */
CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
/** 根据H,S两个平面数据统计直方图 */
cvCalcHist( planes, hist, 0, 0 );
/** 获取直方图统计的最大值,用于动态显示直方图 */
float max_value;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
/** 设置直方图显示图像 */
int height = 240;
int width = (h_bins*s_bins*6);
IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );
cvZero( hist_img );
/** 用来进行HSV到RGB颜色转换的临时单位图像 */
IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3);
IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3);
int bin_w = width / (h_bins * s_bins);
for(int h = 0; h < h_bins; h++)
{
for(int s = 0; s < s_bins; s++)
{
int i = h*s_bins + s;
/** 获得直方图中的统计次数,计算显示在图像中的高度 */
float bin_val = cvQueryHistValue_2D( hist, h, s );
int intensity = cvRound(bin_val*height/max_value);
/** 获得当前直方图代表的颜色,转换成RGB用于绘制 */
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);
CvScalar color = cvGet2D(rgb_color,0,0);
cvRectangle( hist_img, cvPoint(i*bin_w,height),
cvPoint((i+1)*bin_w,height - intensity),
color, -1, 8, 0 );
}
}
return hist_img;
}
#include <stdlib.h> #include <stdio.h> #include <math.h> #include <fstream> #include <string> #include <iostream> #include <opencv/cv.h> #include <opencv/highgui.h> using namespace std; void myShowHist(IplImage* image1,IplImage* image2); IplImage* cvShowHist(IplImage* src); int main() { //对彩色图像进行均衡化 IplImage * image= cvLoadImage("lena.jpg"); IplImage* eqlimage=cvCreateImage(cvGetSize(image),image->depth,3); //信道分离 IplImage* redImage=cvCreateImage(cvGetSize(image),image->depth,1); IplImage* greenImage=cvCreateImage(cvGetSize(image),image->depth,1); IplImage* blueImage=cvCreateImage(cvGetSize(image),image->depth,1); cvSplit(image,blueImage,greenImage,redImage,NULL);//用 cvSplit 函数分解图像到单个色彩通道上 /* cvNamedWindow("red",CV_WINDOW_AUTOSIZE); cvNamedWindow("green",CV_WINDOW_AUTOSIZE); cvNamedWindow("blue",CV_WINDOW_AUTOSIZE); cvShowImage("red",redImage); cvShowImage("green",greenImage); cvShowImage("blue",blueImage); */ //cvEqualizeHist()是适用于灰度图象直方图均衡化,所以必须先将图片分解到单通道上 //分别均衡化每个信道 cvEqualizeHist(redImage,redImage); cvEqualizeHist(greenImage,greenImage); cvEqualizeHist(blueImage,blueImage); /* cvNamedWindow("red2",CV_WINDOW_AUTOSIZE); cvNamedWindow("green2",CV_WINDOW_AUTOSIZE); cvNamedWindow("blue2",CV_WINDOW_AUTOSIZE); cvShowImage("red2",redImage); cvShowImage("green2",greenImage); cvShowImage("blue2",blueImage); */ //信道合并 cvMerge(blueImage,greenImage,redImage,NULL,eqlimage); //显示图片和直方图 cvNamedWindow( "source", 1 ); cvShowImage("source",image); cvNamedWindow( "Equalized", 1 ); cvShowImage("Equalized",eqlimage); cvSaveImage("equalized.jpg",eqlimage); myShowHist(image,eqlimage); cvWaitKey(0); cvDestroyWindow("source"); cvDestroyWindow("result"); cvReleaseImage( &image ); cvReleaseImage( &eqlimage ); } void myShowHist(IplImage* image1,IplImage* image2) { IplImage* hist_image1=cvShowHist(image1); IplImage* hist_image2=cvShowHist(image2); cvNamedWindow( "H-S Histogram1", 1 ); cvShowImage( "H-S Histogram1", hist_image1 ); cvNamedWindow( "H-S Histogram2", 1 ); cvShowImage( "H-S Histogram2", hist_image2 ); cvSaveImage("Histogram1.jpg",hist_image1); cvSaveImage("Histogram2.jpg",hist_image2); } IplImage* cvShowHist(IplImage* src) { 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 分量划分为16个等级,S分量划分为8个等级 */ int h_bins = 16, s_bins = 8; int hist_size[] = {h_bins, s_bins}; /** H 分量的变化范围 */ float h_ranges[] = { 0, 180 }; /** S 分量的变化范围*/ float s_ranges[] = { 0, 255 }; float* ranges[] = { h_ranges, s_ranges }; /** 输入图像转换到HSV颜色空间 */ cvCvtColor( src, hsv, CV_BGR2HSV ); cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 ); /** 创建直方图,二维, 每个维度上均分 */ CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); /** 根据H,S两个平面数据统计直方图 */ cvCalcHist( planes, hist, 0, 0 ); /** 获取直方图统计的最大值,用于动态显示直方图 */ float max_value; cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 ); /** 设置直方图显示图像 */ int height = 240; int width = (h_bins*s_bins*6); IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 ); cvZero( hist_img ); /** 用来进行HSV到RGB颜色转换的临时单位图像 */ IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3); IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3); int bin_w = width / (h_bins * s_bins); for(int h = 0; h < h_bins; h++) { for(int s = 0; s < s_bins; s++) { int i = h*s_bins + s; /** 获得直方图中的统计次数,计算显示在图像中的高度 */ float bin_val = cvQueryHistValue_2D( hist, h, s ); int intensity = cvRound(bin_val*height/max_value); /** 获得当前直方图代表的颜色,转换成RGB用于绘制 */ 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); CvScalar color = cvGet2D(rgb_color,0,0); cvRectangle( hist_img, cvPoint(i*bin_w,height), cvPoint((i+1)*bin_w,height - intensity), color, -1, 8, 0 ); } } return hist_img; }
参考链接:
[1]http://blog.csdn.net/xiaowei_cqu/article/details/7606607
[2]http://www.opencv.org.cn/index.php/%E5%9B%BE%E5%83%8F%E9%A2%9C%E8%89%B2%E5%88%86%E5%B8%83%E7%9B%B4%E6%96%B9%E5%9B%BE
相关文章推荐
- 彩色图像直方图均衡化及颜色直方图显示 opencv实现 完整代码及详细注释
- openCV实现多人脸检测,多眼部检测,完整代码和详细注释
- TensorFlow实现用于图像分类的卷积神经网络(代码详细注释)
- OPENCV图像直方图显示(代码)
- OpenCV(一)显示一幅图像代码详细讲解
- 基于内容的图像检索(颜色,直方图相交法,)java实现代码
- 图像细化算法 opencv实现 完整代码(附实验结果)
- matlab实现将彩色图像(R,G,B)色分量的直方图显示出
- 图像拼接实现镜面效果 opencv完整代码 实现(附实验结果)
- Opencv绘制灰度/彩色图像的直方图及直方图的均衡化实例及源代码
- OpenCV实现彩色图像轮廓 换背景颜色
- L0 范数图像平滑(L0 Smooth) 代码及详细注释 【OpenCV】
- RGB彩色图像与灰度图像转换 opencv实现 代码及分析
- 堆排序 完整代码与详细注释 C++语言实现
- 用opencv简单显示图像和视频(代码有注释)
- opencv实现灰度图像的直方图点计算以及灰度直方图显示
- 图像细化算法 opencv实现 完整代码(附实验结果)
- 新浪微博自动转发评论 源码 按键精灵实现 详细注释 几十行代码实现 涉及图像识别模拟键盘鼠标
- 自适应直方图均衡(CLAHE) 代码及详细注释【OpenCV】
- OV7670摄像采集图像在VGA上显示的分析和实现,精确到每个时钟,每行代码。