编程实现计算图像直方图、图像熵课件
- 格式:doc
- 大小:1.12 MB
- 文档页数:8
一:示例1:8位灰度图像的直方图统计/*输入参数:unsigned char *img 8位灰度图像位图数据首地址int count 图像像素个数输出参数:int hist[] 直方图数据的首地址,存储直方图数据功能:统计输入图像的直方图数据*/void GetHistogram(unsigned char *img, int count, int hist[]){memset(hist,0,256*4);int i;for(i = 0;i < count;i++)hist[*img++]++;}二:练习1:8位灰度图像的累积直方图统计/*输入参数:unsigned char *img 8位灰度图像位图数据首地址int count 图像像素个数输出参数:int cuHist[] 累积直方图数据的首地址,存储累积直方图数据功能:统计输入图像的累积直方图数据*/void GetCumulativeHistogram(unsigned char *img, int count, int cuHist[]){}2:GetAvgByHistogram/*输入参数:int hist[] 8位灰度图像的直方图数据的首地址,存储直方图数据返回值:图像像素平均值功能:由直方图数据求的像素平均值*/unsigned char GetAvgByHistogram(int hist[]){}3:GetMedianByHistogram/*输入参数:int hist[] 8位灰度图像的直方图数据的首地址,存储直方图数据返回值:图像像素的中值功能:由直方图数据求的像素中值*/unsigned char GetMedianByHistogram(int hist[]){}。
用Java使用OpenCV编写直方图处理程序:(一)计算一个图像的直方图import java.util.ArrayList;import org.opencv.core.Core;import org.opencv.core.CvType;import org.opencv.core.Mat;import org.opencv.core.MatOfFloat;import org.opencv.core.MatOfInt;import org.opencv.core.Scalar;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;public class MyHistograms {// 加载OpenCV 本地库static {System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); }public static void main(String[]args) {Mat image = Imgcodecs.imread("mylena.png"); Mat gray = new Mat(image.height(), image.width(), CvType.CV_8U, new Scalar(0));Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);Mat hist = new Mat(256, 1, CvType.CV_8U, new Scalar(0));ArrayList histsSource = new ArrayList();histsSource.add(gray);Imgproc.calcHist(histsSource, new MatOfInt(0), new Mat(), hist, new MatOfInt(256), new MatOfFloat(0f, 256f));System.out.println(hist);System.out.println(hist.dump());int pixAll = gray.rows() * gray.cols();Mat histNorm = new Mat(hist.rows(), hist.cols(), hist.type());Core.divide(hist, new Scalar(pixAll), histNorm);System.out.println(histNorm);System.out.println(histNorm.dump());}}直方图从统计学的角度表征图像,它可以反映图片的整体亮度和对比度:整体较暗的图片,直方图集中在灰度值较小的区域整体较亮的图片,直方图集中在灰度值较大的区域对比度较小的图片,直方图分布较集中对比度较大的图片,直方图分布较分散所有,直方图的应用包括亮度调整和对比度调整(二)图像的直方图均衡直方图均衡用于整体对比度调整。
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: 是否将得到的直⽅图向量归⼀化。
数字图像处理实验报告——图像常用格式及显示武汉大学2016.041 实验内容本实验报告主要介绍主要内容1. 理解灰度映射原理;2. 掌握灰度映射计算方法;3. 理解图像直方图的定义;4. 理解图像直方图的作用;5. 理解图像熵的定义及作用;6. 掌握图像直方图计算方法;7. 掌握图像熵的计算方法;8. 进一步熟悉图像文件256色、24位真彩色BMP图像格式;9. 进一步熟悉Visual C++ 6.0编程界面,及使用方法;10. 熟悉Visual C++中绘图函数方法;11. 编程完成计算图像几种灰度映射;12. 编程实现计算图像直方图、图像熵;13. 编程绘制图像直方图;14. 根据不通灰度映射处理观察图像直方图变化;15. 总结实验过程(实验报告):编程、调试、结果、分析、结论。
主要目的1. 建立相关实验环境:从指定服务器指定位置拷贝实验相关材料,包括:实验要求,实例程序,示例图像,VC++6.0程序,实验相关幻灯片;2. 使用实验一建立的简单多文档应用程序框架及、图像夺取和显示功能,进一步熟悉图像的格式及显示,熟悉图像的组织和存储方式。
3. 编写图像线性灰度映射:4. 编写图像直方图统计程序:5. 观察图像直方图主要函数说明1.void CZhangyanImageView::OnProcessZhifangtu()函数目的:在用户界面中添加直方图处理,并添加函数在.cpp文件中函数参数说明:建立直方图处理函数2.void CZhangyanImageView::OnProcessLinetran()函数目的:在用户界面中添加灰度变换处理,并添加函数在.cpp文件中函数参数说明:建立灰度变换处理函数主要代码注释1.灰度变换函数代码CZhangyanImageDoc* pDoc = GetDocument();//定义引用doc的指针ASSERT_V ALID(pDoc);unsigned char * pBits=pDoc->m_pBits;//把文件中的m_pBits赋予pBitsint nWidth=pDoc->imageWidth;int nHeight=pDoc->imageHeight;//定义整形的image图片宽和高int nValue=0;double dValue=0.0;long lTotal=0;long lTotalD=0;long lTotalL=0;int ab=100,bb=255,a=0,b=255;//定义原图像的灰度值0-255范围,定义处理后图像灰度值100-255范围if(pBits==NULL) return ;//遍历完成则返回for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;//统计出宽*当前高for(int j=0;j<nWidth;j++){lTotalD=lTotalL+j;//统计出第几个像素nValue=*(pBits+lTotalD);// 采用int nValue= *(m_pBits imageWidth * i+j )公式获得图像点灰度值dValue=ab+1.0*(bb-ab)/(b-a)*(nValue-a);//套用灰度变换公式pBits[lTotalD]=int(dValue);}}//对图像进行遍历与灰度处理Invalidate();//强制显示改变了的图像2.直方图生成函数m_bShow=TRUE;CZhangyanImageDoc* pDoc = GetDocument();//定义引用doc的指针ASSERT_V ALID(pDoc);unsigned char * pBits=pDoc->m_pBits; //把文件中的m_pBits图像指针赋予pBitsint nWidth=pDoc->imageWidth;int nHeight=pDoc->imageHeight; //定义整形的image图片宽和高int nValue=0;long lTotal=0;long lTotalD=0;long lTotalL=0;dMax=0;dMaxG=0;dMaxB=0;//数据初始化赋值存储图像灰度像素的计数if(pBits==NULL) return ;if(pDoc->m_nColorBits==8) //对图像进行是否是8彩色的判断{for(int k=0;k<256;k++){m_lValue[k]=0;m_dValue[k]=0.0;}for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;for(int j=0;j<nWidth;j++){lTotalD=lTotalL+j;nValue=*(pBits+lTotalD);//统计灰度值m_lValue[nValue]=m_lValue[nValue]+1;//加1 }}lTotal=nWidth*nHeight;for(INT k=0;k<256;k++){m_dValue[k]=1.0*m_lValue[k]/lTotal;if(dMax<m_dValue[k]) dMax=m_dValue[k];}}//对图像进行遍历并统计直方图数据long nValueG=0;long nValueB=0;//统计R G Bif(pDoc->m_nColorBits==24) //对图像进行是否是24彩色的判断{for(int k=0;k<256;k++){m_lValue[k]=0;m_dValue[k]=0.0;m_lValueG[k]=0;m_dValueG[k]=0.0;m_lValueB[k]=0;m_dValueB[k]=0.0;//}for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;for(int j=0;j<nWidth;j++){lTotalD=(lTotalL+j)*3;nValue=*(pBits+lTotalD);m_lValue[nValue]=m_lValue[nValue]+1;nValueG=*(pBits+lTotalD+1);m_lValueG[nValueG]=m_lValueG[nValueG]+1;nValueB=*(pBits+lTotalD+2);m_lValueB[nValueB]=m_lValueB[nValueB]+1;}}lTotal=nWidth*nHeight;for(int k=0;k<256;k++){m_dValue[k]=1.0*m_lValue[k]/lTotal;if(dMax<m_dValue[k]) dMax=m_dValue[k];m_dValueG[k]=1.0*m_lValueG[k]/lTotal;if(dMaxG<m_dValueG[k]) dMaxG=m_dValueG[k];m_dValueB[k]=1.0*m_lValueB[k]/lTotal;if(dMaxB<m_dValueB[k]) dMaxB=m_dValueB[k];}}//对图像进行遍历并统计直方图数据Invalidate();/强制显示改变了的图像3.变量声明void DrawGraph(CDC * pDC);//绘制直方图函数long m_lValue[256];//红色分量灰度统计double m_dValue[256];// 红色分量灰度频数long m_lValueG[256]; //绿色分量灰度统计double m_dValueG[256]; // 绿色分量灰度频数long m_lValueB[256]; //蓝色分量灰度统计double m_dValueB[256]; //蓝色分量灰度频数double dMax,dMaxG,dMaxB;//红、绿、蓝频数最大值BOOL m_bShow;//是否显示直方图4.图形绘制CZhangyanImageDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// CCCJImageDoc* pDoc 在各人的程序中不一样unsigned char * pBits=pDoc->m_pBits;int X0=0+5;int Y0=510;int WX=768+3,HY=500;int H=375;int W=256;CPen cyPen(PS_SOLID,2,RGB(255,255,0));CPen * oldPen=pDC->SelectObject(&cyPen);pDC->MoveTo(X0,Y0);pDC->LineTo(X0+WX,Y0);pDC->MoveTo(X0,Y0);pDC->LineTo(X0,Y0-HY);pDC->MoveTo(X0,Y0-HY);pDC->LineTo(X0+WX,Y0-HY);pDC->MoveTo(X0+WX,Y0);pDC->LineTo(X0+WX,Y0-HY);pDC->SelectObject(&oldPen);//设置直方图的区域{CPen redPen(PS_SOLID,1,RGB(255,0,0));oldPen=pDC->SelectObject(&redPen);for(int i=0;i<256;i++){int x0,y0,x1,y1;double dy;x0=X0+i*3;y0=Y0;x1=X0+i*3;dy=Y0-1.0*H*m_dValue[i]/dMax;y1=int(dy+0.5);pDC->MoveTo(x0,y0);pDC->LineTo(x1,y1); //进行绘图操作}pDC->SelectObject(oldPen);//以下略去对于24位的解释1.1灰度变换结果图灰度变换结果1.2图像直方图图读取图像直方图2实验日志2.1实验中遇到问题较于上次试验,本次试验显得轻车熟路许多,内容与调试也比较简单,感觉编写实验报告中遇到的最大困难就是对代码的阐述。
南通大学计算机科学与技术学院《数字图像处理》课程实验报告书实验名计算图像的直方图班级计 121姓名张进学号 12130220162014年6月 16 日一、实验内容1、打开一张图,计算其直方图。
二、图像直方图的概念图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。
纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。
图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征。
在实际工程中,图像直方图在特征提取、图像匹配等方面都有很好的应用。
三、灰度直方图的计算1、灰度直方图的定义灰度直方图是灰度级的函数,描述图像中该灰度级的像素个数(或该灰度级像素出现的频率):其横坐标是灰度级,纵坐标表示图像中该灰度级出现的个数(频率)。
一维直方图的结构表示为高维直方图可以理解为图像在每个维度上灰度级分布的直方图。
常见的是二维直方图。
如红-蓝直方图的两个分量分别表示红光图像的灰度值和蓝光图像灰度值的函数。
其图像坐标(Dr,Db)处对应在红光图像中具有灰度级Dr同时在蓝光图像中具有灰度级Db的像素个数。
这是基于多光谱——每个像素有多个变量——的数字图像,二维中对应每个像素统计个变量。
简单的说,直方图就是对数据进行统计,将统计值组织到一系列事先定义好的bin中。
bin的数值是从数据中计算出的特征的统计量,这些数据可以是诸如梯度,方向,色彩或者任何其他特征。
无论如何,直方图获得的是数据分布的统计图。
通常直方图的数据要低于原始数据。
由于原始数据点可以表征任何事情,所以直方图实际上是一个方便表示图像特征的手段。
2、灰度直方图的计算对于彩色图像的R、G、B各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。
如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理int main(){Mat Image=imread("../cat.png");cvtColor(Image,Image,CV_BGR2GRAY);const int channels[1]={0};const int histSize[1]={256};float hranges[2]={0,255};const float* ranges[1]={hranges};MatND hist;calcHist(&Image,1,channels,Mat(),hist,1,histSize,ranges);return 0;}3、彩色直方图计算int main(){Mat Image=imread("../cat.png");const int channels[3]={0,1,2};const int histSize[3]={256,256,256};float hranges[2]={0,255};const float* ranges[3]={hranges,hranges,hranges};MatND hist;calcHist(&Image,1,channels,Mat(),hist,3,histSize,ranges);return 0;}4、不均匀直方图分别统计0-50,50-80,80-150,150-230,230-255区间的灰度分布:int main(){Mat Image=imread("../cat.png");cvtColor(Image,Image,CV_BGR2GRAY);const int channels[1]={0};int histSize[1]={5};float hranges[6]={0,50,80,150,230,255};const float* ranges[1]={hranges};MatND hist;calcHist(&Image,1,channels,Mat(),hist,1,histSize,ranges,false);return 0;}四、直方图的显示直方图计算得到的实际上是一个多维数组,这并不够直观,我们希望能够像在Excel中把相关数据通过表的形式表示出来。
实验二数字图像的直方图统计一、实验目的1.了解对灰度图像进行直方图统计的基本原理;2.掌握用VC编程实现直方图统计的方法;3.在微机上调试程序;5. 分析数字图像直方图的特点。
二、实验原理图像的直方图图像的(灰度统计)直方图是一个一维的离散函数。
它的定义为:设s k为图像f(x,y)的第k级灰度值,n k是f(x,y)中具有灰度值s k的象素的个数,n是图像象素总数,则:p s(s k)= n k/n k=0,1, ,L-1称为图像f(x,y)的直方图。
这里p s(s k)代表原始图中第k个灰度级的出现概率。
以n k为自变量,以p s(s k)为函数,得到的曲线就是图像的直方图,在实际中常常直接将对第k个灰度级的统计值n k作为图像的直方图。
它提供了原图灰度值的分布情况,也可以说给出了一幅图所有灰度值的整体描述。
对灰度图像进行直方图统计的程序流程图如图2-1所示。
图2-1 灰度图像直方图统计流程三、实验前准备1.预习本实验中关于数字图像直方图统计的有关内容;2. 预习VC中添加对话框的步骤和方法;3.了解本实验的目的和实验内容。
四、实验内容1.在实验一的基础上读入并显示一幅数字图像;2.编写对灰度图像进行直方图统计的程序,并将结果显示在屏幕上。
五、实验报告要求1.总结对灰度图像进行直方图统计的过程,比较不同的图像其直方图特性;2.对实验结果进行分析。
六、参考步骤和程序在实验一的基础上,进行如下操作:1、点击ResourceView,右键点击Dialog,选Insert Dialog 在属性对话框中将ID改为ID_HIST,对话框名称改为“直方图”2、在工具栏中点“插入”-“新建类”,输入类名,并选Base Class为CDialog,Dialog ID为ID_HIST。
这样就将对话框和类联系起来了,在该对话框中拖入一Edit控件,将其ID 设为IDC_HISTSHOW;3、快捷键“Ctrl+W”,出现MFC ClassWizard对话框,在Messages栏中分别选WM_INITDIALOG和WM_Paint,再点击“Add Function”,即将对话框初始化和画图函数加入对话框类之中。
实验一 、信息熵与图像熵计算一、实验目的1、复习MATLAB 的基本命令,熟悉MATLAB 下的基本函数。
2、复习信息熵基本定义, 用MATLAB 会求信源的信息熵。
2、学习图像熵基本定义, 用MATLAB 会求图像熵。
二、实验内容1.能够写出MATLAB 源代码,求信源的信息熵。
2.根据图像熵基本知识,综合设计出MATLAB 程序,求出给定图像的图像熵。
三、实验仪器、设备1.计算机-系统最低配置 256M 内存、P4 CPU 。
2.Matlab 仿真软件 - 7.0 / 7.1 / 2006a 等版本Matlab 软件。
四、实验原理图像的熵是一种特征的统计形式,它反映了图像中平均信息量的多少。
图像的一维熵表示图像中灰度分布的聚集特征所包含的信息量,令pi 表示图像中灰度值为 i 的像素所占的比例,则定义灰度图象的一元灰度熵为:2550lo g i i i p p ==∑H图象的一维熵可以表示图像灰度分布的聚集特征,却不能反映图像灰度分布的空间特征,为了表征这种空间特征,可以在一维熵的基础上引入能够反映灰度分布空间特征的特征量来组成图像的二维熵。
选择图像的邻域灰度均值作为灰度分布的空间特征量,与图像的像素灰度组成特征二元组,记为( i, j ),其中i 表示像素的灰度值(0<=i<=255),j 表示领域灰度(0<=j<=255),2(,)/ij P f i j N = 即可反应某像素位置上的灰度值与其周围像素的灰度分布的综合特征,其中f(i,j)为特征二元组(i,j)出现的频数,N 为图像的尺度,定义离散的图像二维熵为:2550lo g ij ij i p p ==∑H依此构造的图像二维熵可以在反映图像所包含的信息量的前提下,突出反映图像中像素位置的灰度信息和像素邻域内灰度分布的综合特征.自信息是一个随机变量,它是指某一信源发出某一消息所含有的信息量。
所发出的消息不同,它们所含有的信息量也就不同。
数字图像处理实验报告——图像常用格式及显示武汉大学2016.041 实验内容本实验报告主要介绍主要内容1. 理解灰度映射原理;2. 掌握灰度映射计算方法;3. 理解图像直方图的定义;4. 理解图像直方图的作用;5. 理解图像熵的定义及作用;6. 掌握图像直方图计算方法;7. 掌握图像熵的计算方法;8. 进一步熟悉图像文件256色、24位真彩色BMP图像格式;9. 进一步熟悉Visual C++ 6.0编程界面,及使用方法;10. 熟悉Visual C++中绘图函数方法;11. 编程完成计算图像几种灰度映射;12. 编程实现计算图像直方图、图像熵;13. 编程绘制图像直方图;14. 根据不通灰度映射处理观察图像直方图变化;15. 总结实验过程(实验报告):编程、调试、结果、分析、结论。
主要目的1. 建立相关实验环境:从指定服务器指定位置拷贝实验相关材料,包括:实验要求,实例程序,示例图像,VC++6.0程序,实验相关幻灯片;2. 使用实验一建立的简单多文档应用程序框架及、图像夺取和显示功能,进一步熟悉图像的格式及显示,熟悉图像的组织和存储方式。
3. 编写图像线性灰度映射:4. 编写图像直方图统计程序:5. 观察图像直方图主要函数说明1.void CZhangyanImageView::OnProcessZhifangtu()函数目的:在用户界面中添加直方图处理,并添加函数在.cpp文件中函数参数说明:建立直方图处理函数2.void CZhangyanImageView::OnProcessLinetran()函数目的:在用户界面中添加灰度变换处理,并添加函数在.cpp文件中函数参数说明:建立灰度变换处理函数主要代码注释1.灰度变换函数代码CZhangyanImageDoc* pDoc = GetDocument();//定义引用doc的指针ASSERT_V ALID(pDoc);unsigned char * pBits=pDoc->m_pBits;//把文件中的m_pBits赋予pBitsint nWidth=pDoc->imageWidth;int nHeight=pDoc->imageHeight;//定义整形的image图片宽和高int nValue=0;double dValue=0.0;long lTotal=0;long lTotalD=0;long lTotalL=0;int ab=100,bb=255,a=0,b=255;//定义原图像的灰度值0-255范围,定义处理后图像灰度值100-255范围if(pBits==NULL) return ;//遍历完成则返回for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;//统计出宽*当前高for(int j=0;j<nWidth;j++){lTotalD=lTotalL+j;//统计出第几个像素nValue=*(pBits+lTotalD);// 采用int nValue= *(m_pBits imageWidth * i+j )公式获得图像点灰度值dValue=ab+1.0*(bb-ab)/(b-a)*(nValue-a);//套用灰度变换公式pBits[lTotalD]=int(dValue);}}//对图像进行遍历与灰度处理Invalidate();//强制显示改变了的图像2.直方图生成函数m_bShow=TRUE;CZhangyanImageDoc* pDoc = GetDocument();//定义引用doc的指针ASSERT_V ALID(pDoc);unsigned char * pBits=pDoc->m_pBits; //把文件中的m_pBits图像指针赋予pBitsint nWidth=pDoc->imageWidth;int nHeight=pDoc->imageHeight; //定义整形的image图片宽和高int nValue=0;long lTotal=0;long lTotalD=0;long lTotalL=0;dMax=0;dMaxG=0;dMaxB=0;//数据初始化赋值存储图像灰度像素的计数if(pBits==NULL) return ;if(pDoc->m_nColorBits==8) //对图像进行是否是8彩色的判断{for(int k=0;k<256;k++){m_lValue[k]=0;m_dValue[k]=0.0;}for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;for(int j=0;j<nWidth;j++){lTotalD=lTotalL+j;nValue=*(pBits+lTotalD);//统计灰度值m_lValue[nValue]=m_lValue[nValue]+1;//加1 }}lTotal=nWidth*nHeight;for(INT k=0;k<256;k++){m_dValue[k]=1.0*m_lValue[k]/lTotal;if(dMax<m_dValue[k]) dMax=m_dValue[k];}}//对图像进行遍历并统计直方图数据long nValueG=0;long nValueB=0;//统计R G Bif(pDoc->m_nColorBits==24) //对图像进行是否是24彩色的判断{for(int k=0;k<256;k++){m_lValue[k]=0;m_dValue[k]=0.0;m_lValueG[k]=0;m_dValueG[k]=0.0;m_lValueB[k]=0;m_dValueB[k]=0.0;//}for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;for(int j=0;j<nWidth;j++){lTotalD=(lTotalL+j)*3;nValue=*(pBits+lTotalD);m_lValue[nValue]=m_lValue[nValue]+1;nValueG=*(pBits+lTotalD+1);m_lValueG[nValueG]=m_lValueG[nValueG]+1;nValueB=*(pBits+lTotalD+2);m_lValueB[nValueB]=m_lValueB[nValueB]+1;}}lTotal=nWidth*nHeight;for(int k=0;k<256;k++){m_dValue[k]=1.0*m_lValue[k]/lTotal;if(dMax<m_dValue[k]) dMax=m_dValue[k];m_dValueG[k]=1.0*m_lValueG[k]/lTotal;if(dMaxG<m_dValueG[k]) dMaxG=m_dValueG[k];m_dValueB[k]=1.0*m_lValueB[k]/lTotal;if(dMaxB<m_dValueB[k]) dMaxB=m_dValueB[k];}}//对图像进行遍历并统计直方图数据Invalidate();/强制显示改变了的图像3.变量声明void DrawGraph(CDC * pDC);//绘制直方图函数long m_lValue[256];//红色分量灰度统计double m_dValue[256];// 红色分量灰度频数long m_lValueG[256]; //绿色分量灰度统计double m_dValueG[256]; // 绿色分量灰度频数long m_lValueB[256]; //蓝色分量灰度统计double m_dValueB[256]; //蓝色分量灰度频数double dMax,dMaxG,dMaxB;//红、绿、蓝频数最大值BOOL m_bShow;//是否显示直方图4.图形绘制CZhangyanImageDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// CCCJImageDoc* pDoc 在各人的程序中不一样unsigned char * pBits=pDoc->m_pBits;int X0=0+5;int Y0=510;int WX=768+3,HY=500;int H=375;int W=256;CPen cyPen(PS_SOLID,2,RGB(255,255,0));CPen * oldPen=pDC->SelectObject(&cyPen);pDC->MoveTo(X0,Y0);pDC->LineTo(X0+WX,Y0);pDC->MoveTo(X0,Y0);pDC->LineTo(X0,Y0-HY);pDC->MoveTo(X0,Y0-HY);pDC->LineTo(X0+WX,Y0-HY);pDC->MoveTo(X0+WX,Y0);pDC->LineTo(X0+WX,Y0-HY);pDC->SelectObject(&oldPen);//设置直方图的区域{CPen redPen(PS_SOLID,1,RGB(255,0,0));oldPen=pDC->SelectObject(&redPen);for(int i=0;i<256;i++){int x0,y0,x1,y1;double dy;x0=X0+i*3;y0=Y0;x1=X0+i*3;dy=Y0-1.0*H*m_dValue[i]/dMax;y1=int(dy+0.5);pDC->MoveTo(x0,y0);pDC->LineTo(x1,y1); //进行绘图操作}pDC->SelectObject(oldPen);//以下略去对于24位的解释1.1灰度变换结果图灰度变换结果1.2图像直方图图读取图像直方图2实验日志2.1实验中遇到问题较于上次试验,本次试验显得轻车熟路许多,内容与调试也比较简单,感觉编写实验报告中遇到的最大困难就是对代码的阐述。
C++中指针是比较难的,再加上vs开发中结构架构的重叠,各种的声明,比较复杂,仔细的阅读了懂得了int nValue= *(m_pBits imageWidth * i +j )代表了灰度值的获取,再结合灰度变换的公式,就很快清楚了进行灰度变换函数的意思,对于直方图数据采集中出现的很多变量感觉不好理解,对于DrawGraph函数绘制的理解还是比较弱的,希望下次实验时让学长来解疑答惑,总之,这次试验按部就班的成功完成,要尽力完善一下自己对c++的理解,获益匪浅。