OpenCV入门指南 第十篇 彩色直方图均衡化
2014-08-13 11:45
239 查看
上一篇《OpenCV第十篇灰度直方图均衡化》介绍了灰度图像的直方图均衡化,实际生活中,肯定还是彩色图像用的最多,因此本篇介绍对彩色图像进行直方图均衡化。这样可以让大家直方图均衡化对图像增强的效果有个直观的印象。
在OpenCV中,彩色的图像其实是用一个多通道数组来存储的,每个单通道数组中的元素的取值范围都是0到255。这与灰度图中像素的变化范围是相同的。因此对彩色图像进行直方图均衡化只要先将彩色图像分解成若干通道,然后这些通道分别进行直方图均衡化,最后合并所有通道即可。下面介绍下二个主要函数cvSplit()和cvMerge()。
一.cvSplit
函数功能:分割多通道数组成几个单通道数组或者从数组中提取一个通道。
函数原型:
/* Splits a multi-channel array into the set of single-channel arrays or
extracts particular [color] plane */
CVAPI(void)
cvSplit(
const
CvArr* src,
CvArr*
dst0,
CvArr*
dst1,
CvArr*
dst2,
CvArr*
dst3
);
参数说明:
第一个参数表示输入的多通道数组即输入图像。
第二,三,四,五个参数分别表示输出的单通道数组。
二.cvMerge
函数功能:分割多通道数组成几个单通道数组或者从数组中提取一个通道。
函数原型:
/* Merges a set of single-channel arrays into the single multi-channel array
or inserts one particular [color] plane to the array */
CVAPI(void)
cvMerge(
const
CvArr* src0,
const
CvArr* src1,
const
CvArr* src2,
const
CvArr* src3,
CvArr*
dst
);
参数说明:
第一,二,三,四个参数表示输入的单通道数组。
第五个参数分别表示合并后的多通道数组即输出图像。
下面给出完整的代码:
[cpp]
view plaincopy
//图像增强- 彩色直方图均衡化
//By MoreWindows (http://blog.csdn.net/MoreWindows)
#include <opencv2/opencv.hpp>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//彩色图像的直方图均衡化
IplImage* EqualizeHistColorImage(IplImage *pImage)
{
IplImage *pEquaImage = cvCreateImage(cvGetSize(pImage), pImage->depth, 3);
// 原图像分成各通道后再均衡化,最后合并即彩色图像的直方图均衡化
const int MAX_CHANNEL = 4;
IplImage *pImageChannel[MAX_CHANNEL] = {NULL};
int i;
for (i = 0; i < pImage->nChannels; i++)
pImageChannel[i] = cvCreateImage(cvGetSize(pImage), pImage->depth, 1);
cvSplit(pImage, pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3]);
for (i = 0; i < pImage->nChannels; i++)
cvEqualizeHist(pImageChannel[i], pImageChannel[i]);
cvMerge(pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3], pEquaImage);
for (i = 0; i < pImage->nChannels; i++)
cvReleaseImage(&pImageChannel[i]);
return pEquaImage;
}
int main( int argc, char** argv )
{
const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)";
const char *pstrWindowsHisEquaTitle = "直方图均衡化后(http://blog.csdn.net/MoreWindows)";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pHisEquaImage = EqualizeHistColorImage(pSrcImage);
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsHisEquaTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsSrcTitle, pSrcImage);
cvShowImage(pstrWindowsHisEquaTitle, pHisEquaImage);
cvWaitKey(0);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsHisEquaTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pHisEquaImage);
return 0;
}
运行结果如下所示:
![](http://img.my.csdn.net/uploads/201212/21/1356081232_8927.png)
呵呵,对比一下就知道直方图均衡化对图像增强的效果还不错,图像的对比度增加后,睫毛,头发等细小物体都要清晰多了。
在OpenCV中,彩色的图像其实是用一个多通道数组来存储的,每个单通道数组中的元素的取值范围都是0到255。这与灰度图中像素的变化范围是相同的。因此对彩色图像进行直方图均衡化只要先将彩色图像分解成若干通道,然后这些通道分别进行直方图均衡化,最后合并所有通道即可。下面介绍下二个主要函数cvSplit()和cvMerge()。
一.cvSplit
函数功能:分割多通道数组成几个单通道数组或者从数组中提取一个通道。
函数原型:
/* Splits a multi-channel array into the set of single-channel arrays or
extracts particular [color] plane */
CVAPI(void)
cvSplit(
const
CvArr* src,
CvArr*
dst0,
CvArr*
dst1,
CvArr*
dst2,
CvArr*
dst3
);
参数说明:
第一个参数表示输入的多通道数组即输入图像。
第二,三,四,五个参数分别表示输出的单通道数组。
二.cvMerge
函数功能:分割多通道数组成几个单通道数组或者从数组中提取一个通道。
函数原型:
/* Merges a set of single-channel arrays into the single multi-channel array
or inserts one particular [color] plane to the array */
CVAPI(void)
cvMerge(
const
CvArr* src0,
const
CvArr* src1,
const
CvArr* src2,
const
CvArr* src3,
CvArr*
dst
);
参数说明:
第一,二,三,四个参数表示输入的单通道数组。
第五个参数分别表示合并后的多通道数组即输出图像。
下面给出完整的代码:
[cpp]
view plaincopy
//图像增强- 彩色直方图均衡化
//By MoreWindows (http://blog.csdn.net/MoreWindows)
#include <opencv2/opencv.hpp>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//彩色图像的直方图均衡化
IplImage* EqualizeHistColorImage(IplImage *pImage)
{
IplImage *pEquaImage = cvCreateImage(cvGetSize(pImage), pImage->depth, 3);
// 原图像分成各通道后再均衡化,最后合并即彩色图像的直方图均衡化
const int MAX_CHANNEL = 4;
IplImage *pImageChannel[MAX_CHANNEL] = {NULL};
int i;
for (i = 0; i < pImage->nChannels; i++)
pImageChannel[i] = cvCreateImage(cvGetSize(pImage), pImage->depth, 1);
cvSplit(pImage, pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3]);
for (i = 0; i < pImage->nChannels; i++)
cvEqualizeHist(pImageChannel[i], pImageChannel[i]);
cvMerge(pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3], pEquaImage);
for (i = 0; i < pImage->nChannels; i++)
cvReleaseImage(&pImageChannel[i]);
return pEquaImage;
}
int main( int argc, char** argv )
{
const char *pstrWindowsSrcTitle = "原图(http://blog.csdn.net/MoreWindows)";
const char *pstrWindowsHisEquaTitle = "直方图均衡化后(http://blog.csdn.net/MoreWindows)";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pHisEquaImage = EqualizeHistColorImage(pSrcImage);
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvNamedWindow(pstrWindowsHisEquaTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsSrcTitle, pSrcImage);
cvShowImage(pstrWindowsHisEquaTitle, pHisEquaImage);
cvWaitKey(0);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsHisEquaTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pHisEquaImage);
return 0;
}
运行结果如下所示:
![](http://img.my.csdn.net/uploads/201212/21/1356081232_8927.png)
呵呵,对比一下就知道直方图均衡化对图像增强的效果还不错,图像的对比度增加后,睫毛,头发等细小物体都要清晰多了。
相关文章推荐
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- 【OpenCV入门指南】第十篇 彩色直方图均衡化
- OpenCV入门(二十)-- 彩色图像的直方图均衡化
- 【OpenCV入门指南】第十三篇 人脸检测
- 【OpenCV入门指南】第七篇 线段检测与圆检测
- 【OpenCV入门指南】第十三篇 人脸检测
- 【OpenCV入门指南】第三篇Canny边缘检测
- 【OpenCV入门指南】第七篇 线段检测与圆检测
- 【OpenCV入门指南】第八篇 灰度直方图
- 【OpenCV入门指南】第四篇 图像的二值化
- 【OpenCV入门指南】第五篇 轮廓检测 上
- 【OpenCV入门指南】第四篇 图像的二值化
- 【OpenCV入门指南】第八篇 灰度直方图