数字图像的直方图均衡化(CC++源代码)
基于CCS的数字图像直方图均衡化的设计

基于CCS的数字图像直方图均衡化的设计作者:杨宏来源:《现代电子技术》2010年第08期摘要:直方图均衡化是最常用的图像增强方法之一,目前大多是用Matlab软件仿真,不利于硬件实现。
为了克服这一不足,这里给出了直方图均衡化算法以及程序设计流程,并在CCS v3.1的软件仿真环境下进行仿真实验。
结果表明,对图像进行直方图均衡化达到了增强的效果。
这为图像处理提供了一种硬件实现的方法。
关键词:CCS; 直方图均衡化; 数字图像; Matlab中图分类号:TP311文献标识码:B文章编号:1004-373X(2010)08-0111-02Design of Digital Image Histogram Equalization Based on CCSYANG Hong(College of Electronic Engineering, Xi’an University of Post and Telecommunications,Xi’an710061, C hina)Abstract:Histogram equalization is one of the image enhancement methods in common use.At present,the usage of Matlab software simulation is not benefit for hardware implementation. In order to overcome this shortfall, a histogram equalization algorithm and program design process are given, and the simulation is done in the CCS v3.1 software simulation environment. The results show that the histogram equalization on images achieves an enhanced effect. The method ofhardware implementation is provided for the image processing.Keywords:CCS; histogram equalization; digital image; Matlab图像增强处理技术一直是图像处理领域中一类非常重要的基本处理技术[1-2]。
基于CCS的数字图像直方图均衡化的设计

0 引 言图像增强处理技术一直是图像处理领域中一类非常重要的基本处理技术[1-2]。
通过采用适当的增强处理技术,可以将原本模糊不清甚至根本无法分辨的原始图片,处理成清楚、明晰的富含大量有用信息的可使用图像,因此此类图像处理技术在医学、遥感、微生物、刑侦以及军事等诸多领域得到了广泛应用。
灰度直方图[3-4]是数字图像处理中一个最简单、最有用的工具,它描述了一副图像的灰度级内容。
直方图均衡化[5-7]是最常用的图像增强方法之一。
1 直方图均衡化算法直方图均衡化算法将原图像的直方图改变为在整个灰度范围内基本均匀地分布的形式,由此扩大了像素灰度的动态范围,从而增强了图像的对比度。
直方图均衡化算法步骤为:1) 给出原始图像的所有灰度级k S (k=0,1,…,L-1)。
2) 统计原始图像各灰度级的像素数k n 。
3) 根据原图像,计算灰度直方图:()kk n P S n=(k=0,1,…,L-1)(1)式中,n 为总像素数,k n 为灰度级k S 的像素数。
4) 计算原始图像的累积直方图:00()()k k i E k s i i i n t EH S P S n =====∑∑ (01k S ≤≤,k=0,1,…,L-1) (2)5) 取整计算:int[(1)]k k k U N t N=-+ (3) 6) 确定映射关系:k k S U →7) 统计新直方图各灰度级k U 的像素数目k n 。
8) 计算新的直方图:()k k n P t n= (4)2 基于CCS 的数字图像直方图均衡化的设计CCS v3.1(Code Composer Studio IDE v3.1)是TI 公司推出的集成可视化DSP 软件开发工具。
它是一种针对TMS320系列DSP 的集成开发环境,在Windows 操作系统下,采用图形接口界面,提供环境配置、源文件编辑、程序调试、跟踪和分析等工具[8-10]。
CCS 有两种工24作模式,即软件仿真器模式和硬件在线编程模式。
python数字图像处理实现直方图与均衡化

python数字图像处理实现直⽅图与均衡化在图像处理中,直⽅图是⾮常重要,也是⾮常有⽤的⼀个处理要素。
在skimage库中对直⽅图的处理,是放在exposure这个模块中。
1、计算直⽅图函数:skimage.exposure.histogram(image,nbins=256)在numpy包中,也提供了⼀个计算直⽅图的函数histogram(),两者⼤同⼩义。
返回⼀个tuple(hist, bins_center), 前⼀个数组是直⽅图的统计量,后⼀个数组是每个bin的中间值import numpy as npfrom skimage import exposure,dataimage =data.camera()*1.0hist1=np.histogram(image, bins=2) #⽤numpy包计算直⽅图hist2=exposure.histogram(image, nbins=2) #⽤skimage计算直⽅图print(hist1)print(hist2)输出:(array([107432, 154712], dtype=int64), array([ 0. , 127.5, 255. ]))(array([107432, 154712], dtype=int64), array([ 63.75, 191.25]))分成两个bin,每个bin的统计量是⼀样的,但numpy返回的是每个bin的两端的范围值,⽽skimage返回的是每个bin的中间值2、绘制直⽅图绘图都可以调⽤matplotlib.pyplot库来进⾏,其中的hist函数可以直接绘制直⽅图。
调⽤⽅式:复制代码代码如下:n, bins, patches = plt.hist(arr, bins=10, normed=0, facecolor='black', edgecolor='black',alpha=1,histtype='bar')hist的参数⾮常多,但常⽤的就这六个,只有第⼀个是必须的,后⾯四个可选arr: 需要计算直⽅图的⼀维数组bins: 直⽅图的柱数,可选项,默认为10normed: 是否将得到的直⽅图向量归⼀化。
数字图像处理均衡化 C#编写

以下程序是在C#环境下编写的数字图像处理程序,主要是负责图像均衡化这一部分功能该段程序以测试通过,适用于灰度图像以及彩色图像的均衡化,原理挺简单的。
学习数字图像处理的同学们,请参考:原图像较暗饱和度低均衡化后图像效果明显原图像直方图均衡化后的图像分布较均匀private void equalizationItem_Click(object sender, EventArgs e){Color color; //新建一个Color对象;int[] countPixel_R = new int[256]; //应用于计算彩色或灰度图像素的数组int[] countPixel_G = new int[256];int[] countPixel_B = new int[256];int[] tempArray_R = new int[256]; //用来计算灰度的概率分布int[] tempArray_G = new int[256];int[] tempArray_B = new int[256];byte[] pixelMap_R = new byte[256]; //存放新的灰度映射byte[] pixelMap_G = new byte[256];byte[] pixelMap_B = new byte[256];int width = filteredImage.Width;int height = filteredImage.Height;Bitmap temp = new Bitmap(width, height);tempImage = filteredImage;if (tempImage.PixelFormat != PixelFormat.Format24bppRgb){filteredImage =AForge.Imaging.Image.Clone(tempImage,PixelFormat.Format24bppRgb);//适用于彩色图像或者灰度图像的均衡化}//逐个像素点地计算R、G、B channel的灰度分布,如果是灰度图恒有R=G=B;for (int h = 0; h < height; h++){for (int w = 0; w < width; w++){color = filteredImage.GetPixel(w, h);countPixel_R[color.R]++;countPixel_G[color.G]++;countPixel_B[color.B]++;}}for (int i = 0; i < 256; i++){if (i != 0){//计算灰度的累计分布tempArray_R[i] = countPixel_R[i] + tempArray_R[i - 1];tempArray_G[i] = countPixel_G[i] + tempArray_G[i - 1];tempArray_B[i] = countPixel_B[i] + tempArray_B[i - 1];}else if (i == 0){tempArray_R[i] = countPixel_R[0];tempArray_G[i] = countPixel_G[0];empArray_B[i] = countPixel_B[0];}//归一化,计算累计概率函数,也就是灰度变换函数pixelMap_R[i] = (byte)(255.0 * tempArray_R[i] / (width * height) + 0.5);pixelMap_G[i] = (byte)(255.0 * tempArray_G[i] / (width * height) + 0.5);pixelMap_B[i] = (byte)(255.0 * tempArray_B[i] / (width * height) + 0.5);}for (int h = 0; h < height; h++){for (int w = 0; w < width; w++){color = filteredImage.GetPixel(w, h); //像素点原来的灰度值color = Color.FromArgb(pixelMap_R[color.R], pixelMap_G[color.G], pixelMap_B[color.B]); //利用灰度映射,得到新的灰度值temp.SetPixel(w, h, color); //实现灰度值均衡化}}ClearCurrentImage();pictureBox.Image = temp;filteredImage = temp;undoItem.Enabled = true;undoallItem.Enabled = true;equalizationItem.Checked = true;displayHistogram(filteredImage);}。
C语言数字图像处理之直方图均衡化

C语⾔数字图像处理之直⽅图均衡化本⽂实例为⼤家分享了C语⾔直⽅图均衡化的具体代码,供⼤家参考,具体内容如下原理直⽅图均衡化(Histogram Equalization) ⼜称直⽅图平坦化,实质上是对图像进⾏⾮线性拉伸,重新分配图像象元值,使⼀定灰度范围内象元值的数量⼤致相等。
这样,原来直⽅图中间的峰顶部分对⽐度得到增强,⽽两侧的⾕底部分对⽐度降低,输出图像的直⽅图是⼀个较平的分段直⽅图:如果输出数据分段值较⼩的话,会产⽣粗略分类的视觉效果。
直⽅图是表⽰数字图像中每⼀灰度出现频率的统计关系。
直⽅图能给出图像灰度范围、每个灰度的频度和灰度的分布、整幅图像的平均明暗和对⽐度等概貌性描述。
灰度直⽅图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数, 其横坐标是灰度级r, 纵坐标是该灰度级出现的频率( 即像素的个数) pr( r) , 整个坐标系描述的是图像灰度级的分布情况, 由此可以看出图像的灰度分布特性, 即若⼤部分像素集中在低灰度区域, 图像呈现暗的特性; 若像素集中在⾼灰度区域, 图像呈现亮的特性。
灰度数字图像是每个像素只有⼀个采样颜⾊的图像。
这类图像通常显⽰为从最暗⿊⾊到最亮的⽩⾊的灰度。
灰度图像与⿊⽩图像不同,在计算机图像领域中⿊⽩图像只有⿊⽩实现流程:1)统计每个灰度级像素点的个数2)计算灰度分布密度3)计算累计直⽅图分布4)累计分布取整,保存计算出来的灰度映射关系处理图⽚规格800*600 8位灰度单通道原图直⽅图均衡化分析:本次实验中,我故意把原图调暗,进⾏直⽅图均衡化后可以明显感受到整幅图像亮度增⼤了,⽽且某些细节⽅⾯更加突出。
出现问题最初进⾏直⽅图均衡化时,输出结果如下:经分析,是没有对数组初始化置零导致的。
Hist数组是进⾏⼀个统计像素点个数的数组,最初倘若不置零,结果必然毫⽆意义。
故⽽添加数组内存置零的操作:经测试,问题解决。
附代码#include <stdio.h>#include <stdlib.h>#include <memory.h>#define height 600#define width 800typedef unsigned char BYTE; // 定义BYTE类型,占1个字节int main(void){FILE *fp = NULL;//BYTE Pic[height][width];BYTE *ptr;BYTE **Pic = new BYTE *[height];for (int i = 0; i != height; ++i){Pic[i] = new BYTE[width];}fp = fopen("weiminglake_huidu.raw", "rb");ptr = (BYTE*)malloc(width * height * sizeof(BYTE));//创建内存for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){fread(ptr, 1, 1, fp);Pic[i][j] = *ptr; // 把图像输⼊到2维数组中,变成矩阵型式ptr++;}}fclose(fp);int hist[256];float fpHist[256];float eqHistTemp[256];int eqHist[256];int size = height *width;int i, j;memset(&hist, 0x00, sizeof(int) * 256);memset(&fpHist, 0x00, sizeof(float) * 256);memset(&eqHistTemp, 0x00, sizeof(float) * 256);for (i = 0; i < height; i++) //计算差分矩阵直⽅图直⽅图统计每个灰度级像素点的个数{for (j = 0; j < width; j++){unsigned char GrayIndex = Pic[i][j];hist[GrayIndex] ++;}}for (i = 0; i< 256; i++) // 计算灰度分布密度{fpHist[i] = (float)hist[i] / (float)size;}for (i = 0; i< 256; i++) // 计算累计直⽅图分布{if (i == 0){eqHistTemp[i] = fpHist[i];}else{eqHistTemp[i] = eqHistTemp[i - 1] + fpHist[i];}}//累计分布取整,保存计算出来的灰度映射关系for (i = 0; i< 256; i++){eqHist[i] = (int)(255.0 * eqHistTemp[i] + 0.5);}for (i = 0; i < height; i++) //进⾏灰度映射均衡化{for (j = 0; j < width; j++){unsigned char GrayIndex = Pic[i][j];Pic[i][j] = eqHist[GrayIndex];}}fp = fopen("output.raw", "wb");for (i = 0; i < height; i++){for (j = 0; j < width; j++){fwrite(&Pic[i][j], 1, 1, fp);}}fclose(fp);return 0;}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
数字图像的直方图均衡化(CC++源代码)

数字图像的直方图均衡化(C/C++源代码)2008-11-02 00:40数字图像的直方图均衡化是常用的图像增强方法,因为均衡化是自动完成的,无需人工干预,而且常常得到比较满意的结果。
下面的程序是利用OPENCV提供的函数,实现这个功能。
需要OPENCV B4.0的支持,在VC6下编译通过。
//// perform histgram equalization for single channel image// AssureDigit Sample code//#include "cv.h"#include "highgui.h"#define HDIM 256 // bin of HIST, default = 256int 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 imagereturn -1;cvNamedWindow( "source", 1 );cvNamedWindow( "result", 1 );// calculate histgram 计算直方图hist = cvCreateHist( 1, &n, CV_HIST_ARRAY, 0, 1 );cvCalcHist( &src, hist, 0, 0 );// Create Accumulative Distribute Function of histgramval = 0;for ( x = 0; x < n; x++){val = val + cvGetReal1D (hist->bins, x);nn[x] = val;}// Compute intensity transformation 计算变换函数的离散形式 sum = src->height * src->width;for( x = 0; x < n; x++ ){T[x] = (uchar) (255 * nn[x] / sum); // range is [0,255] }// Do intensity transform for source imagedst = cvCloneImage( src );T_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );cvSetData( T_mat, T, 0 );// directly use look-up-table function 直接调用内部函数完成look-up-table 的过程cvLUT( src, dst, T_mat );cvShowImage( "source", src );cvShowImage( "result", dst );cvWaitKey(0);cvDestroyWindow("source");cvDestroyWindow("result");cvReleaseImage( &src );cvReleaseImage( &dst );cvReleaseHist ( &hist );return 0;}。
直方图均衡化算法代码

直⽅图均衡化算法代码做了⼀天,都是⿊屏,最后发现,竟然是⼀个局部变量引起。
基本是分3步,这个是在灰度图像下实现均衡化直⽅图。
彩⾊下直接均衡化研究出来再补上。
第⼀步:计算初始直⽅图,即记录每⼀个像素出现次数。
for(int y =0; y < m_image->GetHeight(); y++){for(int x =0; x < m_image->GetWidth();x++){COLORREF rgb = m_image->GetPixel(x,y);int rValue = GetRValue(rgb); //记录每⼀个像素出现次数。
hist[rValue]++;}}第⼆步:由上⾯得到的初始直⽅图计算归⼀化直⽅图和累积直⽅图int hist[256]= {0};double phist[256];for (int i =0; i <=255 ;i++){phist [i]= (double) hist[i]/ (m_image->GetHeight() * m_image->GetWidth()); //归⼀化直⽅图即每个像素出现概率}double dSum[256]= {0.0};for(int i =0; i<=255;i++){if(i !=0){dSum[i]= dSum[i-1]+ phist[i];}else//累积直⽅图{dSum[i]= phist[i];}}第三步:求均衡化映射(旧图->新图)关系,并写⼊新图像for(int y =0; y < m_image->GetHeight(); y++){for(int x =0; x < m_image->GetWidth();x++){COLORREF rgb = m_image->GetPixel(x,y);int rValue = GetRValue(rgb);rValue = Mapping[rValue]; //根据映射关系实现均衡化rgb = RGB(rValue,rValue,rValue);m_image->SetPixel(x,y,rgb);}}。
统计图像直方图及图像均衡化

数字图像处理实验报告一、实验内容:1、统计图像直方图2、直方图的均衡化二、实验目的:1、学会在VC环境下使用opencv,能学会基本的图像导入与显示2、学会加载图像及图像各像素点的统计3、理解并掌握利用直方图均衡化图像的过程,并用程序加以实现三、实验代码:#include "cv.h"#include "highgui.h"#include<stdio.h>#include<math.h>int main( int argc, char** argv ){IplImage* plmg; //声明IplImage指针int height,width,step,channels;uchar *data;int i,j,k,r,count=0;int r0[256]={0};float pr[256]={0},sk[256]={0};//载入图像plmg = cvLoadImage("Tulips.jpg", 1);{cvNamedWindow( "Image", 1 );//创建窗口cvShowImage( "Image", plmg );//显示图像//统计图像各参数并赋值height=plmg->height;width=plmg->width;step=plmg->widthStep;channels=plmg->nChannels;data=(uchar *)plmg->imageData;printf("Processing a %d*%d with %d channels\n",height,width,channels);//反转图像/* for(i=0;i<height;i++)for(j=0;j<width;j++)for(k=0;k<channels;k++)data[i*step+j*channels+k]=255-data[i*step+j*channels+k];cvNamedWindow( "Image1", 1 );//创建窗口cvShowImage( "Image1", plmg );//显示图像*/for(i=0;i<height;i++) //统计直方图for(j=0;j<width;j++)for(k=0;k<channels;k++)//for(r=0;r<256;r++)r0[data[i*step+j*channels+k]]++;for(r=0;r<256;r++)count=count+r0[r];for(r=0;r<256;r++)printf("pixel %d is %d\n",r,r0[r]);printf("all pixels=%d\n",count);for(r=0;r<256;r++){pr[r]=r0[r]/(float)count; //像素点归一化printf("pixel %d 的个数及归一化:%d %f\n",r,r0[r],pr[r]);}sk[0]=255*pr[0]; //均衡化像素函数for(r=1;r<256;r++)sk[r]=sk[r-1]+pr[r]*255;for(r=0;r<256;r++){printf("pixel %d befor equilibria is %d ,after is %f \n",r,r0[r],sk[r]);}//映射到原图像,即像素值强制修改为均衡后的值for(i=0;i<height;i++)for(j=0;j<width;j++)for(k=0;k<channels;k++)data[i*step+j*channels+k]=sk[data[i*step+j*channels+k]];cvNamedWindow( "Image1", 1 );//创建窗口cvShowImage( "Image1", plmg );//显示图像*/cvWaitKey(0); //等待按键cvDestroyWindow( "Image" );//销毁窗口cvReleaseImage( &plmg ); //释放图像return 0;}return -1;}四、实验结果:五、实验心得:1、每建立一个将要使用opencv的VC Project ,都需要给它指定需要的lib文件2、需要加载的图像必须和所建工程的程序文件在同一个目录下3、对图像操作时,必须先把定义的图像参数赋值,否则将不能对图像进行修改4、初步掌握了opencv在VC环境下的运行与基本的opencv语句5、图像均衡化时,要注意归一时是除以所有像素点的总数,均衡时概率依次累加后乘以的是最大灰度级,同时要注意所用数组整型和浮点型的转换6、实验误区:各灰度级经过像素点的计算得到均衡化的结果是灰度数,而不再是像素点的个数7、数组赋值需用{}。
数字图像处理实验二(直方图均衡化)

数字图像处理实验二直方图均衡化(直方图均衡化实质上是减少图象的灰度级以换取对比度的加大)例如:假设原图的灰度分布级为126(最大为256,也就是从0到255的级上的灰度都有或多或少的出现),经过直方图均衡化后,灰度分布级别将会小于126。
编程的时候请按照直方图均衡化公式进行。
下面给出大致的编程思路和源代码:其中黑框部分需要自己编写源代码1)利用第一次实验课提供的dhc.h 和dhc.c文件以获取位图的高宽以及从文件头到实际的位图数据的偏移字节数,从而实现对位图实际数据的操作。
利用include命令#include <stdio.h>#include <stdlib.h>#include <memory.h>#include "hdr.h"思考问题:#include <*.h> 和#include "*.h"在程序运行中有什么差别?2)定义结构指针struct bmphdr *hdr;定义用于直方图变量unsigned char *bitmap, new_color[256];定义计算灰度分布,灰度累计分布的数组int count[256], acum[256];3)main()函数编写//定义整数i,j 用于函数循环时的,nr_pixels为图像中像素的个数int i, j, nr_pixels;//定义两个文件指针分别用于提取原图像的数据和生成直方图均衡化后的图像FILE *fp, *fpnew;//定义主函数的参数包括:输入的位图文件名和输出的位图文件名,此处内容可以不要,在DOS下执行命令的时候再临时输入也可,为了方便演示,我这里直接把函数的参数确定了。
argc=3;argv[1]="test.bmp";argv[2]="testzf.bmp";//参数输入出错显示if (argc != 3) {printf("please input the name of input and out bitmap files\n");exit(1);}// 获取位图文件相关信息hdr = get_header(argv[1]);if (!hdr) exit(1);//以二进制可读方式打开输入位图文件fp = fopen(argv[1], "rb");if (!fp) {printf("File open error!\n");exit(1);}// 文件指针指向数据区域fseek(fp, hdr->offset, SEEK_SET);//计算位图像素的个数nr_pixels = hdr->width * hdr->height;bitmap = malloc(nr_pixels);//读取位图数据到bitmap中fread(bitmap, nr_pixels, 1, fp);fclose(fp);memset(count, 0, sizeof(count));//计算每个灰度级上像素的个数结果存入count[]数组中memcpy(acum, count, sizeof(acum));//计算灰度的累计分布for (i = 1; i < 256; i++)acum[i] += acum[i-1];//灰度直方图的均衡化(核心程序部分,请仔细分析)为了方便大家编程实现,这里直接给出了源代码,本实验最核心的部分就在这里//}//对所有的像素灰度值按照均衡化得到的灰度对应规则进行转换,结果存入bitmap[]中//fpnew = fopen(argv[2], "wb+");//由于位图文件的头部信息并没有因直方图均衡化而改变,因此输出图像的头部信息从原位图文件中拷贝即可:fwrite(hdr->signature, 2, 1, fpnew);fwrite(&hdr->size, 4, 1, fpnew);fwrite(hdr->reserved, 4, 1, fpnew);fwrite(&hdr->offset, 4, 1, fpnew);fwrite(&hdr->hdr_size, 4, 1, fpnew);fwrite(&hdr->width, 4, 1, fpnew);fwrite(&hdr->height, 4, 1, fpnew);fwrite(&hdr->nr_planes, 2, 1, fpnew);fwrite(&hdr->bits_per_pixel, 2, 1, fpnew);fwrite(&hdr->compress_type, 4, 1, fpnew);fwrite(&hdr->data_size, 4, 1, fpnew);fwrite(&hdr->resol_hori, 4, 1, fpnew);fwrite(&hdr->resol_vert, 4, 1, fpnew);fwrite(&hdr->nr_colors, 4, 1, fpnew);fwrite(&hdr->important_color, 4, 1, fpnew);if (hdr->offset > 54)fwrite(hdr->info, (hdr->offset - 54), 1, fpnew);////关闭fclose(fpnew);//释放内存(优化程序必需)free(hdr);free(bitmap);return 0;}。
计算机视觉实验报告-直方图归一化和均衡化

1实验目的安装、配置、熟悉Python+Opencv开发环境图像读、写等的基本操作选取一张自己的生活照,实现:直方图归一化和均衡化(基础实现,如果实现了自适应,加分)快速傅里叶变换和高斯滤波(使用不同的sigma,分析sigma大小对图像清晰度的影响,至少使用三种不同的sigma)。
2实验过程Pycharm终端输入pip opencv后却不能编译有opencv函数的代码电脑上原来有个python环境,编译选项是原来的环境,但opencv库安装在conda 设置里把编译器改成conda2.1直方图归一化和均衡化归一化实验图片所用代码import cv2import numpy as npimport matplotlib.pyplot as pltdef hist_normalization(img, a=0, b=255):c = img.min()d = img.max()out = img.copy()# normalizationout = (b - a) / (d - c) * (out - c) + aout[out < a] = aout[out > b] = bout = out.astype(np.uint8)return outif __name__ == '__main__':img =cv2.imread('img/in.jpeg').astype(np.uint8)arr=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)shape=arr.shape# 因为手机拍摄照片灰度范围是0~255,直接归一化没有效果,所以修改像素灰度值来缩小灰度范围,使效果明显for i in range(0,shape[0]):for j in range(0,shape[1]):if arr[i,j]<50:arr[i,j]*=1.5elif arr[i,j]>200:arr[i,j]*=0.8out=hist_normalization(arr)plt.hist(out.ravel(),bins=255,rwidth=0.8,range=(0,255))plt.savefig('img/out3.png')cv2.imwrite("img/out.jpg",out)实验效果代码分析及现象直方图相比原来,被拉开的更散均衡化实验图片所用代码import cv2import numpy as npimport matplotlib.pyplot as pltif __name__ == '__main__':img =cv2.imread('img/in.jpeg').astype(np.uint8)img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)equalization = cv2.equalizeHist(img)cv2.imshow('Equalization', equalization)cv2.waitKey(0)实验效果代码分析及现象图片灰度变得更均匀2.2快速傅里叶变换和高斯低通滤波快速傅里叶变化实验图片所用代码import cv2import numpy as npif __name__ == '__main__':img =cv2.imread('img/in.jpeg',cv2.IMREAD_GRAYSCALE)# 2. 进行快速傅里叶变换,数据类型需转换为单精度fft = np.fft.fft2(np.float32(img))# 3. 频谱中心化fft_shift = np.fft.fftshift(fft)# 4. 灰度值缩放,便于显示fft_shift = 15 * np.log(np.abs(fft_shift))# 5. 数据类型转换fft_shift = fft_shift.astype(np.uint8)# 6. 显示结果cv2.imwrite('img/out.jpg', fft_shift)cv2.imshow('Image', img)cv2.imshow('FFT', fft_shift)cv2.waitKey(0)实验效果代码分析及现象原图变成了中间一个光源向四处发散的图像高斯低通滤波实验图片所用代码import numpy as npimport cv2import numpy.random as randomdef add_salt_noise(image, prob=0.1):output = np.zeros(image.shape, np.uint8)for i in range(image.shape[0]):for j in range(image.shape[1]):if random.random() < prob:if random.random() < 0.5:output[i, j] = 0else:output[i, j] = 255else:output[i, j] = image[i, j]return outputif __name__ == '__main__':# 1. 读取图像文件image_path = 'img/in.jpeg'image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)# 2. 添加椒盐噪声noise = add_salt_noise(image, prob=0.1)# 3. 高斯滤波kernel_size = 3gaussian = cv2.GaussianBlur(noise, (kernel_size, kernel_size), sigmaX=1)for i in range(0,9):gaussian = cv2.GaussianBlur(gaussian, (kernel_size, kernel_size), sigmaX=1)# 4. 显示图像cv2.imshow('Image', image)cv2.imshow('Noise', noise)cv2.imshow('Gaussian', gaussian)cv2.waitKey(0)实验效果Sigma=1Sigma=0.1Sigma=0.5代码分析及现象随着sigma增大,去噪效果增强,不过sigma在1之后继续增大时效果不明显3实验心得熟悉了opencv的基本操作,深入得理解了怎样对图片处理使其质量更好,对于其中出现的问题也能通过bing等搜索引擎找到答案。
直方图均衡化的C语言代码

直⽅图均衡化的C语⾔代码直接PO代码:1 #include <stdio.h>2 #include <math.h>3 #include "graphics.h"45/*6功能: 在整型数组中找到最⼩值和最⼤值7输⼊: 整型数组;数组⼤⼩;接收最⼩值;接收最⼤值8结果: 得到数组中的最⼩值和最⼤值9*/10void GetMinMaxInt(int *arr, int n, int &min, int &max);11/*12功能: 在浮点型数组中找到最⼩值和最⼤值13输⼊: 浮点型数组;数组⼤⼩;接收最⼩值;接收最⼤值14结果: 得到数组中的最⼩值和最⼤值15*/16void GetMinMaxDouble(double *arr, int n, double &min, double &max);17/*18功能: 打印灰度图19输⼊: 存储灰度图的动态数组;宽;⾼20结果: 图像窗⼝显⽰灰度图21*/22void PrintGrayImage(double *gray_mtx, int w, int h);23/*24功能: 获取输⼊的彩⾊图像,并转为灰度图25输⼊: 图像完整⽂件名;存储图像灰度图的动态数组;宽;⾼;是否在窗⼝打印26结果: 相应图像灰度数据赋值到动态数组mx中(1打印 0不打印)27*/28void GetImageGray(char *file, double *mx, int w, int h, int mode);29/*30功能: 打印灰度直⽅图31输⼊: 存储灰度图的动态数组;宽;⾼32结果: 图像窗⼝打印灰度直⽅图33*/34void ShowHistogram(double *mx, int w, int h);35/*36功能: 直⽅图均衡化37输⼊: 原图像及其尺⼨;输出图像38结果: 对图像进⾏直⽅图均衡化处理39*/40void HistogramEqualization(double *mtx, int w, int h, double *out);4142int main() {43int w=640, h=640;44char file_name[] = "image.jpg";4546 initgraph(w, h, 0);47 setcaption("直⽅图均衡化");4849/* 获取输⼊图像灰度图 */50double *gray_mtx = (double *)malloc(w*h*sizeof(double));51 GetImageGray(file_name, gray_mtx, w, h, 0);5253/* 打印输⼊图像灰度直⽅图 */54// ShowHistogram(gray_mtx, w, h);555657/* 直⽅图均衡化 */58double *out_mtx = (double *)malloc(w*h*sizeof(double));59 HistogramEqualization(gray_mtx, w, h, out_mtx);606162/* 打印处理后的图像 */63 PrintGrayImage(out_mtx, w, h);6465/* 打印处理后图像灰度直⽅图 */66// ShowHistogram(out_mtx, w, h);6768 getch();69free(gray_mtx);70free(out_mtx);71 closegraph();72return0;73 }7475/* 在整型数组中找到最⼩值和最⼤值 */76void GetMinMaxInt(int *arr, int n, int &min, int &max) {77 min = 0x7fffffff;78 max = 0x80000000;79for(int i=0; i<n; i++) {80if(arr[i] > max) max = arr[i];81if(arr[i] < min) min = arr[i];82 }83 }84/* 在浮点型数组中找到最⼩值和最⼤值 */85void GetMinMaxDouble(double *arr, int n, double &min, double &max) {86 min = 1.7976931348623158e+308;87 max = 2.2250738585072014e-308;88for(int i=0; i<n; i++) {89if(arr[i] > max) max = arr[i];90if(arr[i] < min) min = arr[i];91 }92 }939495/* 打印灰度图 */96void PrintGrayImage(double *gray_mtx, int w, int h) {97int i, j, gray;98for(i=0; i<w; i++) {99for(j=0; j<h; j++) {100 gray = *(gray_mtx+h*i+j) * 255.0;101 putpixel(i, j, EGEGRAY(gray));102 }103 }104 }105/* 获取输⼊的彩⾊图像,并转为灰度图 */106void GetImageGray(char *file, double *mx, int w, int h, int mode) { 107 color_t color;108int i, j, red, green, blue, gray;109 PIMAGE pimg = newimage();110 getimage(pimg, file, w, h);111112for(i=0; i<w; i++) {113for(j=0; j<h; j++) {114 color = getpixel(i, j, pimg);115 red = EGEGET_R(color);116 green = EGEGET_G(color);117 blue = EGEGET_B(color);118// 转化为灰度图119 gray = (red*38 + green*75 + blue*15) >> 7;120 *(mx+h*i+j) = gray / 255.0;121// printf("(%d,%d) %lf\n", i, j, gray/255.0);122 }123 }124// 是否打印灰度图像125if(mode) {126 PrintGrayImage(mx, w, h);127 }128 delimage(pimg);129 }130/* 打印灰度直⽅图 */131void ShowHistogram(double *mx, int w, int h) {132int i, gray_level[256]={0}, gl;133for(i=0; i<w*h; i++) {134// 像素点的灰度级计数135 gl = floor(*(mx+i) * 255.0);136 gray_level[gl]++;137 }138// 左上⾓的坐标,坐标轴最⼤像素⾼度,间隔像素点139int dgx=0, dgy=0, dgh=600, ii=1;140int min, max;141 GetMinMaxInt(gray_level, 256, min, max);142int sX, sY, eX, eY;143for(i=0; i<256; i++) {144 sX = dgx + i*(ii+1);145 sY = dgy + dgh;146 eX = dgx + i*(ii+1);147 eY = dgy + dgh-dgh*gray_level[i]/max;148 line(sX, sY, eX, eY);149 }150 }151/* 直⽅图均衡化 */152void HistogramEqualization(double *mtx, int w, int h, double *out) { 153int i, j, sum;154/* 原图像灰度级像素点计数 */155int gray_level[256] = {0};156for(i=0; i<w*h; i++) {157// 像素点的灰度级计数158 gray_level[int(*(mtx+i) * 255.0 + 0.5)]++;159 }160161/* 图像的归⼀化灰度分布及概率 */162double sk=0.0, tmp; // 变换函数163double ia=0.0, ib=1.0/255.0, mid; // 定义两个变量,⽤于寻找最接近的灰度级164/* 像素映射关系(⽤于对图像的像素进⾏处理) */165double corresponding[256];166for(i=0; i<256; i++) {167 tmp = 1.0*gray_level[i]/(w*h);168 sk += tmp;169// 寻找最接近的灰度级170while(sk > ib) {171 ia += 1.0/255.0;172 ib += 1.0/255.0;173 }174 mid = (ia+ib)/2.0;175if(sk > mid) corresponding[i] = ib;176else corresponding[i] = ia;177 }178179/* 图像的直⽅图均衡化转换 */180for(i=0; i<w; i++) {181for(j=0; j<h; j++) {182 *(out+h*i+j) = corresponding[int(*(mtx+h*i+j) * 255.0 + 0.5)];183 }184 }185 }(1)原图:(2)处理前后灰度图对⽐:(3)处理前后灰度直⽅图对⽐:(4)处理前后变换函数图对⽐:。
C语言实现BMP图像处理(直方图均衡化)

C语⾔实现BMP图像处理(直⽅图均衡化)本⽂实例为⼤家分享了C语⾔实现BMP图像直⽅图均衡化处理的具体代码,供⼤家参考,具体内容如下计算步骤:1)统计各灰度值的概率;2)计算了累积概率直⽅图(CDF);3)取整扩展:Tk = int[ (L-1)*Tk];#include <Windows.h>#include <stdlib.h>#include <stdio.h>#include <math.h>int main(int* argc, char** argv){FILE* fp = fopen("./01.bmp", "rb");if (fp == 0)return 0;BITMAPFILEHEADER fileHead;fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);BITMAPINFOHEADER infoHead;fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp);int width = infoHead.biWidth;int height = infoHead.biHeight;int biCount = infoHead.biBitCount;int lineByte = (biCount*width / 8 + 3) / 4 * 4;RGBQUAD* pColorTable;pColorTable = new RGBQUAD[256];fread(pColorTable, sizeof(RGBQUAD), 256, fp);unsigned char* pBmpBuf;pBmpBuf = new unsigned char[lineByte*height];fread(pBmpBuf, lineByte*height, 1, fp);fclose(fp);// 统计概率double st[256] = { 0 };int st1[256] = { 0 };int t;for (int i = 0; i < height; ++i){for (int j = 0; j < width; ++j){t = *(pBmpBuf + i*lineByte + j);st[t]++;}}// 计算累加直⽅图并完成映射st[0] = st[0] / (width*height);st1[0] = round(double((256 - 1)*st[0]));for (int i = 1; i < 256; ++i){st[i] = st[i] / (width*height);st[i] = st[i] + st[i - 1];st1[i] = int(round(double((256 - 1)*st[i])));printf("st[i] = %d, st1[t] = %d\n", st[i], st1[i]);}// 新图像的像素填充unsigned char* pBmpBuf1;pBmpBuf1 = new unsigned char[lineByte*height];for (int i = 0; i < height; ++i){for (int j = 0; j < width; ++j){t = *(pBmpBuf + i*lineByte + j);*(pBmpBuf1 + i*lineByte + j) = st1[t];}}FILE* fop = fopen("./imhist.bmp", "wb");if (fop == 0)return 0;fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, fop);fwrite(&infoHead, sizeof(BITMAPINFOHEADER), 1, fop);fwrite(pColorTable, sizeof(RGBQUAD), 256, fop);fwrite(pBmpBuf1, lineByte*height, 1, fop);fclose(fop);system("pause");return 0;}实验结果:实验结果分析:对⽐原图与实验结果图,原图中,头发和⾐领处灰度值较低的地⽅在结果图中灰度值更低,⽽原图中,额头中间偏右处较亮,在结果图中更亮,灰度值更⼤。
C语言实现直方图均衡化

C语⾔实现直⽅图均衡化直⽅图均衡化部分是⽤c语⾔写的,最后⽤opencv显⽰原图像,处理后图像以及原图和处理后图的灰度直⽅图。
虽然做出来了,均衡化效果还可以,但不知道为什么处理后图像中有三条⽩线,真⼼搞不懂,有看出来问题的⼤神⿇烦留⾔告诉我,谢谢。
(终于知道哪出问题了,原来是每⾏字节数求错了,改为LineByte=(width*8/8+3)/4*4;即可。
)下⾯是代码:#include "stdafx.h"#include<stdio.h>#include<windows.h>#include<opencv2\highgui\highgui.hpp>#include<opencv2\core\core.hpp>#include<cv.h>int main(void){int width;//图像宽度int height;//图像⾼度RGBQUAD *pColorTable;unsigned char *pBmpBuf,*pBmpBuf1;BITMAPFILEHEADER bfhead;BITMAPINFOHEADER bihead;FILE *fp1=fopen("e:\\picture\\dog.bmp","rb");if(fp1==0)return 0;fread(&bfhead,14,1,fp1);fread(&bihead,40,1,fp1);width=bihead.biWidth;height=bihead.biHeight;pColorTable=new RGBQUAD[256];fread(pColorTable,4,256,fp1);int LineByte=0;LineByte=(width*1/4+1)*4;<span style="white-space:pre"> </span>//LineByte=(width*8/8+3)/4*4;pBmpBuf = new unsigned char[LineByte*height];fread(pBmpBuf,LineByte*height,1,fp1);fclose(fp1);pBmpBuf1=new unsigned char[LineByte*height]; //⽤于存储均值化后的图像数据//统计每个灰度级像素点的个数int N[256]={0};for(int i=0;i<height;i++)for(int j=0;j<width;j++){unsigned char *pb1,*pb2;pb1=pBmpBuf+i*LineByte+j;N[*pb1]++;pb2=pBmpBuf1+i*LineByte+j;*pb2=*pb1;}/*for(int i=0;i<256;i++ )printf("%d ",N[i]);*///统计最⼩与最⼤灰度值int minGrayValue=255;int maxGrayValue=0;for(int i=0;i<height;i++)for(int j=0;j<width;j++){unsigned char *pb;pb=pBmpBuf+i*LineByte+j;if(*pb>maxGrayValue)maxGrayValue=*pb;else if(*pb<minGrayValue)minGrayValue=*pb;}printf("%d ,%d\n",minGrayValue,maxGrayValue);//输出最⼤与最⼩灰度值int x=maxGrayValue-minGrayValue+1;float *p;p=new float[x];for(int i=0;i<x;i++){*(p+i)=(float)N[i]/(float)(width*height); //*(p+i)中存放的是灰度级为i的像素在整幅图像中出现//的概率(即*(p+i)i=0,1,2,3...中存放的就是这幅图像归⼀化后的直⽅图)}float *c;c=new float[x]; //定义c,⽤来存放累积的归⼀化直⽅图for(int i=0;i<x;i++) //对c进⾏初始化{*(c+i)=0;}for(int i=0;i<x;i++){for(int j=0;j<=i;j++){*(c+i)+=*(p+j);}}for(int i=0;i<height;i++)for(int j=0;j<width;j++){unsigned char *pb;pb=pBmpBuf1+i*LineByte+j;*pb=*(c+*pb)*(maxGrayValue-minGrayValue)+minGrayValue;}FILE *fp2=fopen("junhenghua.bmp","wb");fwrite(&bfhead,14,1,fp2);fwrite(&bihead,40,1,fp2);fwrite(pColorTable,4,256,fp2);fwrite(pBmpBuf1,LineByte*height,1,fp2);fclose(fp2);//显⽰原图与处理后的图像IplImage *src1=cvLoadImage("e:\\picture\\dog.bmp");IplImage *src2=cvLoadImage("junhenghua.bmp");cvNamedWindow("原图");cvNamedWindow("处理后图");cvShowImage("原图",src1);cvShowImage("处理后图",src2);//显⽰原图像与处理后图像的灰度直⽅图int size=256;float range[]={0,255};float *ranges[]={range};CvHistogram *hist1=cvCreateHist(1,&size, CV_HIST_ARRAY,ranges,1);//创建⼀维直⽅图,CvHistogram *hist2=cvCreateHist(1,&size, CV_HIST_ARRAY,ranges,1);IplImage* gray1=cvCreateImage(cvGetSize(src1),8,1);IplImage* gray2=cvCreateImage(cvGetSize(src2),8,1);cvCvtColor(src1,gray1,CV_BGR2GRAY);cvCvtColor(src2,gray2,CV_BGR2GRAY);//vCvtColor(...),是Opencv⾥的颜⾊空间转换函数,可以实现RGB颜⾊向HSV,HSI等颜⾊空间的转换,也可以转换为灰度图像。
OpenCV直方图均衡化的源代码

IplImage* image=cvLoadImage("D:\\1.jpg",1);//载入指定路径的图像文件强制彩色化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);//将彩色图像image的蓝色分量图像blueImage﹑//绿色分量图像greenImage和红色分量图像redImage提取出来cvEqualizeHist(redImage,redImage);//对红色分量图像进行直方图均衡化处理cvEqualizeHist(greenImage,greenImage); //对绿色分量图像进行直方图均衡化处理cvEqualizeHist(blueImage,blueImage); //对蓝色分量图像进行直方图均衡化处理cvMerge(blueImage,greenImage,redImage,NULL,image);//将经过直方图均衡化的蓝色﹑绿色﹑红色图像合并成彩色图像,存储在image中cvNamedWindow("1",CV_WINDOW_AUTOSIZE);//创建一个名称为1的窗口,用于显示图像cvShowImage("1",image);//在名称为1的窗口上显示图像imagecvReleaseImage(&image);//释放图像image的内存cvReleaseImage(&redImage); //释放图像redImage的内存cvReleaseImage(&greenImage); //释放图像greenImage的内存cvReleaseImage(&blueImage); //释放图像blueImage的内存cvWaitKey(0);cvDestroyWindow("1"); //销毁窗口资源效果对比图:。
直方图均衡化的C++实现(基于openCV)

直⽅图均衡化的C++实现(基于openCV)这是数字图像处理课的⼤作业,完成于 2013/06/17,需要调⽤ openCV 库,完整源码和报告如下:1 #include <cv.h>2 #include <highgui.h>3 #include <stdio.h>4 #include <stdlib.h>5 #include <math.h>6 #include <assert.h>7 #include <string>89/* 灰度级结点 */10 typedef struct {11int pixels; // 灰度级对应像素个数12float rate; // 像素⽐例13float accuRate; // 累计像素⽐例14int map; // 到均衡化后的灰度级的映射15 } levNode;1617void histeqGray(IplImage* pGray, int levels, int argc);18 IplImage* histImage(IplImage* pSrc, int histWidth, int histHeight, int nScale);1920int main(int argc, char* argv[])21 {22int levels;23 std::string imgName, inTmp;24if (argc == 3) {25 levels = atoi(argv[1]);26 imgName = argv[2];27 }28else if (argc == 2)29 imgName = argv[1];30else {31 printf("usage: histeq [levels] image_name \n");32return -1;33 }3435 IplImage* pSrc = cvLoadImage(imgName.c_str(), CV_LOAD_IMAGE_UNCHANGED);36int channel = pSrc->nChannels;3738 IplImage* pChnl[4] = { NULL };3940for (int i = 0; i < channel; ++i)41 pChnl[i] = cvCreateImage(cvGetSize(pSrc), pSrc->depth, 1);4243 cvSplit(pSrc, pChnl[0], pChnl[1], pChnl[2], pChnl[3]);4445for (int i = 0; i < channel; ++i)46 histeqGray(pChnl[i], levels, argc);4748 IplImage* pEql = cvCreateImage(cvGetSize(pSrc), pChnl[0]->depth, pSrc->nChannels);4950 cvMerge(pChnl[0], pChnl[1], pChnl[2], pChnl[3], pEql);5152 inTmp = imgName + "_Eql.jpg";53 cvSaveImage(inTmp.c_str(), pEql);5455//cvNamedWindow(imgName.c_str(), CV_WINDOW_AUTOSIZE);56 cvShowImage(imgName.c_str(), pSrc);57//cvNamedWindow(inTmp.c_str(), CV_WINDOW_AUTOSIZE);58 cvShowImage(inTmp.c_str(), pEql);5960 IplImage* pSrcGray = cvCreateImage(cvGetSize(pSrc), IPL_DEPTH_8U, 1);61if (pSrc->nChannels == 3)62 cvCvtColor(pSrc, pSrcGray, CV_BGR2GRAY);63else64 cvCopyImage(pSrc, pSrcGray);65 IplImage* pEqlGray = cvCreateImage(cvGetSize(pEql), IPL_DEPTH_8U, 1);66if (pSrc->nChannels == 3)67 cvCvtColor(pEql, pEqlGray, CV_BGR2GRAY);68else69 cvCopyImage(pEql, pEqlGray);70 imgName += "_Hist.jpg";71 inTmp += "_Hist.jpg";72int nScale = 2;73int histWidth = /*pSrc->width * nScale*/256 * nScale;74int histHeight = /*pSrc->height*/128;75 IplImage* pSrcGrayHist = histImage(pSrcGray, histWidth, histHeight, nScale);76 IplImage* pEqlGrayHist = histImage(pEqlGray, histWidth, histHeight, nScale);77 cvSaveImage(imgName.c_str(), pSrcGrayHist);78 cvSaveImage(inTmp.c_str(), pEqlGrayHist);79 cvShowImage(imgName.c_str(), pSrcGrayHist);80 cvShowImage(inTmp.c_str(), pEqlGrayHist);8182 cvWaitKey();8384 cvReleaseImage(&pEql);85 cvReleaseImage(&pEqlGray);86for (int i = 0; i < channel; ++i)87 cvReleaseImage(&pChnl[i]);88 cvReleaseImage(&pSrc);89 cvReleaseImage(&pSrcGray);9091return0;92 }9394/*95* 直⽅图均衡化函数96* pGray为输⼊的灰度图97* levels为均衡化的灰度级98*/99void histeqGray(IplImage* pGray, int levels, int argc)100 {101int depth = pGray->depth;102 printf("%d \n", depth);103int width = pGray->width;104int height = pGray->height;105int sumPixels = width * height; // 总像素数106 printf("%d \n", sumPixels);107int values = static_cast<int>(pow((float)2, depth)); // 根据图像深度计算像素取值范围108if (argc == 2) levels = values;109 printf("%d \n", levels);110111int outDepth;112/*if (levels <= 2)113 outDepth = 1;114 else*/if (levels <= 256)115 outDepth = 8;116else if (levels <= 65536)117 outDepth = 16;118119 assert(levels <= values);120int intervals = values / levels; // 根据像素取值范围和灰度级求每个灰度级的像素间隔121 levNode* levNodes = (levNode*)calloc(levels, sizeof(levNode)); // ⽣成灰度结点122//for (int lev = 0; lev < levels; ++lev) printf("%d \n", levNodes[lev].pixels);123//char* pValues = pGray->imageData;124125/* 统计每个灰度级的像素个数 */126for (int y = 0; y < height; ++y)127for (int x = 0; x < width; ++x) {128 CvScalar scal = cvGet2D(pGray, y, x);129int val = (int)scal.val[0];130//printf("%d \n", val);131for (int lev = 0; lev < levels; ++lev) {132if ( val >= intervals*lev && val < intervals*(lev+1)) {133 ++levNodes[lev].pixels; break;134 }135 }136 }137138int sum = 0;139for (int lev = 0; lev < levels; ++lev)140 sum += levNodes[lev].pixels;141 printf("%d \n", sum);142143/* 计算每个灰度级像素⽐例和累计⽐例 */144 levNodes[0].accuRate = levNodes[0].rate = levNodes[0].pixels / (float)sumPixels; 145 levNodes[0].map = (int)(levNodes[0].accuRate * (levels - 1) + 0.5);146 printf("%d \n", levNodes[0].pixels);147for (int lev = 1; lev < levels; ++lev) {148 levNodes[lev].rate = levNodes[lev].pixels / (float)sumPixels;149 levNodes[lev].accuRate = levNodes[lev-1].accuRate + levNodes[lev].rate;150 levNodes[lev].map = (int)(levNodes[lev].accuRate * (levels - 1) + 0.5);151 }152 printf("%f \n", levNodes[levels-1].accuRate);153154/* ⽣成均衡化后的图像 */155for (int y = 0; y < height; ++y)156for (int x = 0; x < width; ++x) {157 CvScalar scal = cvGet2D(pGray, y, x);158int val = (int)scal.val[0];159//printf("%d \n", val);160for (int lev = 0; lev < levels; ++lev) {161if (val >= intervals*lev && val < intervals*(lev+1)) {162 scal.val[0] = levNodes[lev].map;163//printf("%f \n", scal.val[0]);164 cvSet2D(pGray, y, x, scal);165break;166 }167 }168 }169 pGray->depth = outDepth;170171 free(levNodes);172 }173174/*175* 绘制直⽅图函数176*/177 IplImage* histImage(IplImage* pSrc, int histWidth, int histHeight, int nScale)178 {179int histSize = static_cast<int>(pow((float)2, pSrc->depth));180 CvHistogram* pHist = cvCreateHist(/*pSrc->nChannels*/1, &histSize, CV_HIST_ARRAY);181 cvCalcHist(&pSrc, pHist);182183 IplImage* pHistImg = cvCreateImage(cvSize(histWidth, histHeight), IPL_DEPTH_8U, 1);184 cvRectangle(pHistImg, cvPoint(0,0), cvPoint(pHistImg->width,pHistImg->height), CV_RGB(255,255,255), CV_FILLED);185186float histMaxVal = 0;187 cvGetMinMaxHistValue(pHist, 0, &histMaxVal);188189for(int i = 0; i < histSize; i++)190 {191float histValue= cvQueryHistValue_1D(pHist, i); // 像素为i的直⽅块⼤⼩192int nRealHeight = cvRound((histValue / histMaxVal) * histHeight); // 要绘制的⾼度193 cvRectangle(pHistImg,194 cvPoint(i*nScale, histHeight - 1),195 cvPoint((i + 1)*nScale - 1, histHeight - nRealHeight),196 cvScalar(i),197 CV_FILLED198 );199 }200//cvFillConvexPoly201202 cvReleaseHist(&pHist);203return pHistImg;204 }View Code⼀、直⽅图均衡化概述直⽅图均衡化是⼀种图像增强⽅法,其基本思想是把给定图像的直⽅图分布改造成均匀分布的直⽅图,从⽽增加象素灰度值的动态范围,达到增强图像整体对⽐度的效果。
图像处理实验三:直方图均衡化

图像处理实验三:直方图均衡化最后完成时间:2010/10/30 基本原理(数学公式):归一化累计直方图程序源代码(附注释):HistogramEqualization.m%直方图均衡化HistogramEqualization%读取显示原图像I=imread('tire.tif');figure,subplot(2,2,1);imshow(I);title('原始图像');[m,n]=size(I);%原始图像灰度级for k=0:255s0(k+1)=length(find(I==k))/(m*n);end%原始直方图subplot(2,2,3);bar(0:255,m*n*s0,'g');title('原始图像直方图');%计算累计直方图各项tkt1=zeros(1,256);for x=1:256for y=1:xt1(x)=s0(y)+t1(x);endend%取整扩展t2=round(255*t1+0.5);%确定映射关系sk-tkfor x=1:256t3(x)=sum(s0(find(t2==x)));end%根据映射关系计算均衡化直方图subplot(2,2,4);bar(0:255,m*n*t3,'b');title('均衡化后直方图');图像处理实验三:直方图均衡化%显示均衡化后图像t=I;for x=0:255t(find(I==x))=t2(x+1);endsubplot(2,2,2);imshow(t);title('均衡化后图像');实验结果与分析:直方图均衡化增强了图像的对比度与动态范围2。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字图像的直方图均衡化(C/C++源代码)
2008-11-02 00:40
数字图像的直方图均衡化是常用的图像增强方法,因为均衡化是自动完成的,无需人工干预,而且常常得到比较满意的结果。
下面的程序是利用OPENCV提供的函数,实现这个功能。
需要OPENCV B4.0的支持,在VC6下编译通过。
//
// perform histgram equalization for single channel image
// AssureDigit Sample code
//
#include "cv.h"
#include "highgui.h"
#define HDIM 256 // bin of HIST, default = 256
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( "source", 1 );
cvNamedWindow( "result", 1 );
// calculate histgram 计算直方图
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;
}
// Compute intensity transformation 计算变换函数的离散形式 sum = src->height * src->width;
for( x = 0; x < n; x++ )
{
T[x] = (uchar) (255 * nn[x] / sum); // range is [0,255] }
// Do intensity transform for source image
dst = cvCloneImage( src );
T_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );
cvSetData( T_mat, T, 0 );
// directly use look-up-table function 直接调用内部函数完成look-up-table 的过程
cvLUT( src, dst, T_mat );
cvShowImage( "source", src );
cvShowImage( "result", dst );
cvWaitKey(0);
cvDestroyWindow("source");
cvDestroyWindow("result");
cvReleaseImage( &src );
cvReleaseImage( &dst );
cvReleaseHist ( &hist );
return 0;
}。