数字图像处理实验教程 V3.1
7. 预习内容
图像直方图的概念;直方图均衡化的计算方法。 8. 参考程序代码
/* 程序名:imadjust.cpp
功 能:读入图像,强制转换为灰度图,对其进行灰度变换 */
#include \
#include \/*
灰度变换函数ImageAdjust
其中,源图像src和目标图像dst均为8比特的灰度图像 默认的参数值有:
[low, high] = [0,1]; [bottom, top] = [0,1];
线性变换:将源灰度值的[low, high]区间线性变换到[bottom, top]区间 如果变换成功,返回0,否则返回非零值。 */
int ImageAdjust(IplImage* src, IplImage* dst, double low, double high, double bottom, double top) {
if( low<0 || low>1 || high <0 || high>1 || bottom<0 || bottom>1 || top<0 || top>1 || low>=high)
return -1;//输入参数值不符合函数要求,则返回失败值
//将输入参数缩放到8比特图像的灰度级别[0, 255]上 double low2 = low*255; double high2 = high*255;
double bottom2 = bottom*255; double top2 = top*255;
double k = (top2 - bottom2)/(high2 - low2);//计算直线斜率
int x,y; double val;
//对图像中的像素逐个进行灰度变换
for( y = 0; y < src->height; y++)//y为像素的纵坐标 {
for (x = 0; x < src->width; x++)//x为像素的横坐标 {
val= (uchar) src->imageData [ src->widthStep*y + x]; //得到源图像中像素点的灰度值
val = (val - low2)* k + bottom2;//计算变换后的灰度值 if(val>255) val=255;
26
数字图像处理实验教程 V3.1
if(val<0) val=0;//保证灰度值落在有效的灰度级别内
dst->imageData[ dst->widthStep*y + x] = val;//对目标图像的像素
点重新赋灰度值 } }
return 0; }
int main( int argc, char** argv ) {
IplImage *src = 0, *dst = 0;
if( argc != 2 || (src=cvLoadImage(argv[1], 0)) == NULL)//参数0表示强制转换为单通道灰度图像
return -1;//指定读取灰度图像,否则程序退出
cvNamedWindow( \ cvNamedWindow( \
//以下为图像增强过程 //先复制源图像
dst = cvCloneImage(src);
//输入参数 [0,0.5] 和 [0.5,1]进行灰度变换 if( ImageAdjust( src, dst, 0, 0.5, 0.5, 1)!=0) return -1;
cvShowImage( \ cvShowImage( \ cvWaitKey(0);
cvDestroyWindow(\ cvDestroyWindow(\ cvReleaseImage( &src ); cvReleaseImage( &dst );
return 0; }
9. OpenCV函数解释
cvCloneImage复制图像函数
语法:IplImage* cvCloneImage(const IplImage* image)
输入参数为源图像IplImage指针,返回值为目的IplImage指针。
27
数字图像处理实验教程 V3.1
实验5 直方图均衡化(验证性,3.3节)
1. 实验目的
(1)熟悉直方图均衡化处理的理论基础; (2)掌握直方图均衡化处理的实现方法; (3)学习VC++6.0和OpenCV的编程方法; (4)验证直方图均衡化处理理论; (5)观察直方图均衡化处理的结果。 2. 实验内容
(1) 使用VC++6.0编译OpenCV程序histeq.c的代码,使程序显示直方图均衡
化后的图像。观察并记录实验结果。
(2) OpenCV已经封装了对图像进行均衡化的算法(cvEqualizeHist函数),试
修改histeq.c的代码,直接使用函数cvEqualizeHist对图像进行均衡化。 (3) 选做实验:参考提供的代码imhist.c,建立相应工程,实现图像直方图的
显示。了解在OpenCV中画图形的方法。 3. 实验回答问题
简述图像直方图均衡化的计算步骤。 1.累积 2.取整 3,映射 4.计算 4. 练习
【基础练习】
(1) 熟练使用快捷键及C程序调试方法:F9加断点,F10单步执行,F5调试
等。
(2) 练习使用printf打印语句用来检测局部结果。 5. 实验报告要求
实验报告要求写明以下7方面内容: (1) 写明实验目的。
(2) 写明实验内容和步骤。
(3) 写出图像处理函数代码,并对算法程序部分加详细的注释。 (4) 描绘并解释实验结果,并对实验结果进行分析。 (5) 写明实验中存在的不足,以及改进的方法。 (6) 回答实验中涉及到的问题。 (7) 写出本次实验的体会。 6. 预习内容
预习空域滤波器的分类;平滑、锐化滤波器的实现方法。 7. 参考程序代码 /* 程序名:histeq.c
功 能:读入图像,实现直方图的均衡化并显示 */
#include \
#include \
#define HDIM 256 // bin of HIST, default = 256
28
数字图像处理实验教程 V3.1
int main( int argc, char** argv ) {
IplImage *src = 0, *dst = 0; CvHistogram *hist = 0;
int n = HDIM; double nn[HDIM]; uchar T[HDIM]; CvMat *T_mat;
int x;
int sum = 0; // sum of pixels of the source image 图像中像素点总数 double val = 0;
if( argc != 2 || (src=cvLoadImage(argv[1], 0)) == NULL) // force to gray image return -1;
cvNamedWindow( \ cvNamedWindow( \
// 计算直方图
hist = cvCreateHist( 1, &n, CV_HIST_ARRAY, 0, 1 ); cvCalcHist( &src, hist, 0, 0 );
// Create Accumulative Distribute Function of histgram val = 0;
for ( x = 0; x < n; x++) {
val = val + cvGetReal1D (hist->bins, x);//计算累积直方图 nn[x] = val; }
// 归一化直方图
sum = src->height * src->width; for( x = 0; x < n; x++ ) {
T[x] = (uchar) (255 * nn[x] / sum); // range is [0,255] 取整扩展 }
// Using look-up table to perform intensity transform for source image dst = cvCloneImage( src );
T_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );
cvSetData( T_mat, T, 0 ); //用取整扩展后的新的灰度值填充数组T_mat
29
数字图像处理实验教程 V3.1
// 直接调用内部函数完成 look-up-table 的过程 cvLUT( src, dst, T_mat ); //完成灰度映射
cvShowImage( \ cvShowImage( \ cvWaitKey(0);
cvDestroyWindow(\ cvDestroyWindow(\ cvReleaseImage( &src ); cvReleaseImage( &dst ); cvReleaseHist ( &hist );
return 0; }
/* 程序名:hist.c
功 能:读入图像,计算并显示直方图。 */
#include \
#include \#include
int main( int argc, char** argv ) {
IplImage *src = 0; IplImage *histimg = 0; CvHistogram *hist = 0;
int hdims = 50; // 划分HIST的个数,越高越精确 float hranges_arr[] = {0,255}; float* hranges = hranges_arr; int bin_w; float max_val; int i;
if( argc != 2 || (src=cvLoadImage(argv[1], 0)) == NULL) // force to gray image return -1;
cvNamedWindow( \ cvNamedWindow( \
hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); // 计算直
30