直方图均衡化例题
数字图像处理计算题复习精华版

30452计算题复习一、直方图均衡化(P68)对已知图像进行直方图均衡化修正。
例:表1为已知一幅总像素为n=64×64的8bit数字图像(即灰度级数为8),各灰度级(出现的频率)分布列于表中。
要求将此幅图像进行均衡化修正(变换),并画出修正(变换)前后的直方图。
解:对已知图像均衡化过程见下表:画出直方图如下:(a)原始图像直方图(b)均衡化后直方图**以下部分不用写在答题中。
其中:①r k、n k中k = 0,1,…,7② p r (r k )= n k /n ,即计算各灰度级像素个数占所有像素个数的百分比,其中∑==kj jnn 0,在此题中n =64×64。
③ ∑==kj jrk r p s 0)(计,即计算在本灰度级之前(包含本灰度级)所有百分比之和。
④ ]5.0)1int[(+-=计并k k s L s ,其中L 为图像的灰度级数(本题中L = 8),int[ ]表示对方括号中的数字取整。
⑤ 并k k s s =⑥ n sk 为映射对应关系r k →s k 中r k 所对应的n k 之和。
⑦ n n s p sk k s /)(=,或为映射对应关系r k →s k 中r k 所对应的p r (r k )之和。
二、 模板运算 使用空间低通滤波法对图像进行平滑操作(P80)空间低通滤波法是应用模板卷积方法对图像每一个像素进行局部处理。
模板(或称掩模)就是一个滤波器,它的响应为H (r ,s ),于是滤波输出的数字图像g(x ,y )用离散卷积表示为)6.2.4(),(),(),(∑∑-=-=--=lls k k r s r H s y r x f y x g式中:x ,y = 0,1,2,…,N -1;k 、l 根据所选邻域大小来决定。
具体过程如下: (1)将模板在图像中按从左到右、从上到下的顺序移动,将模板中心与每个像素依次重合(边缘像素除外); (2)将模板中的各个系数与其对应的像素一一相乘,并将所有的结果相加; (3)将(2)中的结果赋给图像中对应模板中心位置的像素。
直方图的均衡化

三、例题演示
设有1幅64x64,8bit灰度图像,其直方 图见图1,所用均衡化变换函数(即累积 直方图)见图2,均衡化后的直方图见图 3。
直方图均衡化计算列表
序号
运算
1 列出原始图灰度级Sk,k=0,1,…7
0
1
2
2 统计原始直方图各灰度级象素数Nk 790 1023 850
3 用式1计算原始直方图(图1)
对图像空间域点的增强过程是通过增强函数t=EH(s)来完成的, t、s分别为目标图像和原始图像上的像素点(x,y)处的灰度值。
在进行均衡化处理时,增强函数EH需要满足两个条件: 1)、增强函数EH(s)在0≤s≤L-1的范围内是一个单调递增函数,
这个条件保证了在增强处理时没有打乱原始图像的灰度排列次序; 2)、对于0≤s≤L-1应当有0≤EH(s)≤L-1,它保证了变换过程
0 sk 1
k=0,1,…L-1
公式(2)
根据该方程可以由原图像的各像素灰度值直接得到直方图均衡化后各 像素的灰度值。
在实际处理变换时,一般先对原始图像的灰度情况进行统计分析,并
计算出原始直方图分布,然后根据计算出的累计直方图分布 t k ,按式 tkint[(L1)tk0.5]对其取整扩展并得出原灰度s k 到 t k 的灰度映
%step1:get histogram
for i=1:m;
for j=1:n;
k=plane(i,j);
tmhist(k)=tmhist(k)+1;
end
end
四、直方图均衡化的原理程序(lm2.m)
%step2:get cdf
cdf(1)=tmhist(1);
for i=2:256
▪ 其实在MATLAB中,用imhist函数求图像直方图,histeq函数可 以实现直方图均衡化操作(histogram equalization)。
数字图像处理课程设计报告---直方图均衡化

设计题目:直方图均衡化1、直方图的理论基础:(1)直方图概念:灰度直方图表示图像中每种灰度出现的频率。
(2)直方图的作用: 反映一幅图像的灰度分布特性(3)直方图的计算: 式中:n k 为图像中出现r k 级灰度的像素数,n 是图像像素总数,而n k /n 即为频数。
2、设计目的: 产生一幅灰度级分布具有均匀概率密度的图像,扩展像素取值的动态范围,达到了图象增强的目的。
3、直方图均衡化的效果 :1)变换后直方图趋向平坦,灰级减少,灰度合并。
2)原始象含有象素数多的几个灰级间隔被拉大了,压缩的只是象素数少的几个灰度级,实际视觉能够接收的信息量大大地增强了,增加了图象的反差。
同时,也增加了图象的可视粒度。
4、离散情况下的直方图均衡化的算法:A 、列出原始图像的灰度级B 、统计各灰度级的像素数目C 、计算原始图像直方图各灰度级的频数D 、计算累积分布函数F 、应用以下公式计算映射后的输出图像的灰度级,P 为输出图像灰度级的个数,其中INT 为取整符号:G 、用的映射关系修改原始图像的灰度级,从而获得直方图近似为均匀分布的输出图像。
3、源程序代码// cqxhistView.cpp : implementation of the CCqxhistView class#include "stdafx.h"#include "cqxhist.h"#include "cqxhistDoc.h"#include "cqxhistView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////// // CCqxhistView1,,1,0,-=L j f j 1,,1,0,-=L j n j 1,,1,0,/)(-==L j n n f P j j f 1,,,1,0,)()(0-==∑=L k j f P f C k j j f ]5.0)()[(min min max ++-=g f C g g INT g i nn r p k k =)(1,,2,1,010-=≤≤l k r kIMPLEMENT_DYNCREATE(CCqxhistView, CView)BEGIN_MESSAGE_MAP(CCqxhistView, CView)//{{AFX_MSG_MAP(CCqxhistView)ON_COMMAND(ID_OPEN_IMAGE, OnOpenImage)ON_COMMAND(ID_HIST_IMAGE, OnHistImage)//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CCqxhistView construction/destructionCCqxhistView::CCqxhistView(){// TODO: add construction code here}CCqxhistView::~CCqxhistView(){}BOOL CCqxhistView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}///////////////////////////////////////////////////////////////////////////// // CCqxhistView drawingvoid CCqxhistView::OnDraw(CDC* pDC){CCqxhistDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereif(m_dib.m_bLoaded==true) //判断是否加载图像{//获取图像宽和高int nw=m_dib.GetDIBWidth();int nh=m_dib.GetDIBHeight();// 显示图像(具体的参数见CDIB类的该函数说明)m_dib.ShowDIB(pDC,10,10,nw,nh,m_dib.m_pDIBData,m_dib.m_pBMI);m_dib.ShowDIB(pDC,400,10,nw,nh,m_dib.m_pDumpDIBData,m_dib.m_pBMI); }if(m_bHist==true){//绘制原图像的直方图CString str;int nh=m_dib.GetDIBHeight();int i;// 画坐标轴// 绘制坐标轴pDC->MoveTo(410,nh+20); //(410,nh+20 )是直方图的左上角坐标// 垂直轴pDC->LineTo(410,nh+200);//(410,nh+200 )是直方图的左下角坐标// 水平轴pDC->LineTo(710,nh+200);//(710,nh+200 )是直方图的右下角坐标// 写X轴刻度值str.Format("0");pDC->TextOut(410, nh+200+10, str);str.Format("50");pDC->TextOut(460, nh+200+10, str);str.Format("100");pDC->TextOut(510, nh+200+10, str);str.Format("150");pDC->TextOut(560, nh+200+10, str);str.Format("200");pDC->TextOut(610, nh+200+10, str);str.Format("255");pDC->TextOut(665, nh+200+10, str);// 绘制X轴刻度for ( i = 0; i < 256; i += 25){if ((i & 1) == 0){// 10的倍数pDC->MoveTo(i + 10, nh+200-2);pDC->LineTo(i + 10, nh+200+2);}else{// 10的倍数pDC->MoveTo(i + 10, nh+200-2);pDC->LineTo(i + 10, nh+200+2);}}// 绘制X轴箭头pDC->MoveTo(705,nh+200-5);pDC->LineTo(710,nh+200);pDC->LineTo(705,nh+200+5);// 绘制y轴箭头pDC->MoveTo(410,nh+20);pDC->LineTo(405,nh+20+5);pDC->MoveTo(410,nh+20);pDC->LineTo(415,nh+20+5);int max=0;for(i=0;i<256;i++)if(m_yuan[i]>max)max=m_yuan[i];for(i=0;i<256;i++){pDC->MoveTo(410+i,nh+200);pDC->LineTo(410+i,nh+200-(m_yuan[i]*160/max));}}if(m_bHist==true){//绘画直方图CString str;int nh=m_dib.GetDIBHeight();int i;// 画坐标轴// 绘制坐标轴pDC->MoveTo(10,nh+20); //(10,nh+20 )是直方图的左上角坐标// 垂直轴pDC->LineTo(10,nh+200);//(10,nh+200 )是直方图的左下角坐标// 水平轴pDC->LineTo(310,nh+200);//(310,nh+200 )是直方图的右下角坐标// 写X轴刻度值str.Format("0");pDC->TextOut(10, nh+200+10, str);str.Format("50");pDC->TextOut(60, nh+200+10, str);str.Format("100");pDC->TextOut(110, nh+200+10, str);str.Format("150");pDC->TextOut(160, nh+200+10, str);str.Format("200");pDC->TextOut(210, nh+200+10, str);str.Format("255");pDC->TextOut(265, nh+200+10, str);// 绘制X轴刻度for ( i = 0; i < 256; i += 25){if ((i & 1) == 0){// 10的倍数pDC->MoveTo(i + 10, nh+200-2);pDC->LineTo(i + 10, nh+200+2);}else{// 10的倍数pDC->MoveTo(i + 10, nh+200-2);pDC->LineTo(i + 10, nh+200+2);}}// 绘制X轴箭头pDC->MoveTo(305,nh+200-5);pDC->LineTo(310,nh+200);pDC->LineTo(305,nh+200+5);// 绘制y轴箭头pDC->MoveTo(10,nh+20);pDC->LineTo(5,nh+20+5);pDC->MoveTo(10,nh+20);pDC->LineTo(15,nh+20+5);int max=0;for(i=0;i<256;i++)if(m_hist[i]>max)max=m_hist[i];for(i=0;i<256;i++){pDC->MoveTo(10+i,nh+200);pDC->LineTo(10+i,nh+200-(m_hist[i]*160/max));}}}///////////////////////////////////////////////////////////////////////////// // CCqxhistView printingBOOL CCqxhistView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CCqxhistView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CCqxhistView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}///////////////////////////////////////////////////////////////////////////// // CCqxhistView diagnostics#ifdef _DEBUGvoid CCqxhistView::AssertValid() const{CView::AssertValid();}void CCqxhistView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CCqxhistDoc* CCqxhistView::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCqxhistDoc)));return (CCqxhistDoc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CCqxhistView message handlersvoid CCqxhistView::OnOpenImage(){// TODO: Add your command handler code here// TODO: Add your command handler code herestatic char szFilter[]="BMP文件(*.bmp)|*.bmp||"; //定义过滤文件的类型 CFileDialog dlg(TRUE,"bmp",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);//定义文件对话框对象 CString filename;int ret=dlg.DoModal(); //运行打开文件对方框if(ret==IDOK){filename=dlg.GetFileName(); //获取所选择图像的路径 m_dib.LoadFromFile(filename); //加载图像if(!m_dib.m_bLoaded) //判断是否加载图像成功{AfxMessageBox("图像打不开");return;}for(int i=0;i<256;i++) //初始化直方图数组{ m_hist[i]=0;m_yuan[i]=0;}m_bHist=false;}{int nw=m_dib.GetDIBWidth();int nh=m_dib.GetDIBHeight();for(int j=0;j<nh;j++)for(int i=0;i<nw;i++){BYTE temp=m_dib.m_pdata[j*nw+i];m_yuan[temp]++;}}Invalidate(1); //刷新屏幕}void CCqxhistView::OnHistImage(){// TODO: Add your command handler code here//功能:实现直方图均衡化////////////////////////////判断图像是否打开,没打开,则弹出提示框并退出函数if(!m_dib.m_bLoaded){AfxMessageBox("图像还打开,请先打开图像!");return;}//获取图像宽和高int nw=m_dib.GetDIBWidth();int nh=m_dib.GetDIBHeight();int i,j,k;int count[256]={0};//定义一个数组,用于存放灰度级个数 float p[256];//定义一个数组,用于存放灰度级出现频率//对图像进行直方图均衡化处理for(i=0;i<nh;i++)for(j=0;j<nw;j++){k=m_dib.m_pdata[i*nw+j];//计算灰度级个数count[k]++;}for(k=0;k<256;k++)p[k]=count[k]/(nw*nh*1.0f);float c[256]={0};float sum=0.0;int ngray[256];//新的灰度级for(k=0;k<256;k++)//计算累积频率{sum+=p[k];c[k]=sum;ngray[k]=(int)(255.0*c[k]+0.5);}for(i=0;i<nh;i++)for(j=0;j<nw;j++){k=m_dib.m_pdata[i*nw+j];m_dib.m_pdata[i*nw+j]=ngray[k];}{int nw=m_dib.GetDIBWidth();int nh=m_dib.GetDIBHeight();for(int j=0;j<nh;j++)for(int i=0;i<nw;i++){BYTE temp=m_dib.m_pdata[j*nw+i];m_hist[temp]++;}}//将修改的m_pdata的数据赋值给m_pDIBData,以显示修改的结果m_dib.UpdateData();m_bHist=true;//将修改的m_pdata的数据赋值给m_pDIBData,以显示修改的结果 m_dib.UpdateData();//刷新屏幕Invalidate();}4、实验结果C++编程结果:。
数字图像处理期末考试题库

数字图像处理期末考试题库某数字图像处理的主要内容及特点图像获取、图像变换、图像增强、图像恢复、图像压缩、图像分析、图像识别、图像理解(1)处理精度高,再现性好。
(2)易于控制处理效果。
(3)处理的多样性。
(4)图像数据量庞大。
(5)图像处理技术综合性强。
某图像增强:通过某种技术有选择地突出对某一具体应用有用的信息,削弱或抑制一些无用的信息。
图像增强不存在通用理论。
图像增强的方法:空间域方法和变换域方法。
某图像反转:S=L-1-r1.与原图像视觉内容相同2.适用于增强嵌入于图像暗色区域的白色或灰色细节。
某对数变换S=C某log(1+r)c为常数,r>=0作用与特点:对数变换将输入中范围较窄的低灰度值映射为输出中较宽范围的灰度值,同时,对输入中范围较宽的高灰度值映射为输出中较窄范围的灰度值。
对数函数的一个重要特征是可压缩像素值变化较大的图像的动态范围;某幂律(伽马)变换=c某(r+ɛ)ɤ伽马小于1时减小图像对比度,伽马大于1时增大对比度。
某灰度直方图:是数字图像中各灰度级与其出现的频数间的统计关系。
某直方图均衡化:直方图均衡化就是通过变换函数将原图像的直方图修正为均匀的直方图,即使各灰度级具有相同的出现频数,图象看起来更清晰。
直方图均衡化变换函数必须为严格单调递增函数。
直方图均衡化的特点:›1.能自动增强图像的对比度2.得到了全局均衡化的直方图,即均匀分布3.但其效果不易控制某直方图规定化(匹配):用于产生处理后有特殊直方图的图像的方法某空间滤波即直接对图像像素进行处理。
获得最佳滤波效果的唯一方法是使滤波掩模中心距原图像边缘的距离不小于(n-1)/2个像素。
某平滑滤波器用于模糊处理和减小噪声。
平滑线性空间滤波器的输出是:待处理图像在滤波器掩模邻域内的像素的简单平均值。
优点:减小了图像灰度的“尖锐”变化,故常用于图像降噪。
负面效应:模糊了图像的边缘,因为边缘也是由图像灰度的尖锐变化造成的。
空间均值处理的重要应用是,为了对感兴趣的物体得到一个粗略的描述而模糊一幅图像。
图像直方图的均衡化处理图的均衡化

图像直⽅图的均衡化处理图的均衡化图像直⽅图的均衡化处理⼀,技术要求1.1,利⽤matlab提供的函数处理 (2)1.2,利⽤matlab⾃⾏编辑代码处理 (3)⼆,基本原理 (3)2.1,直⽅图的均衡化 (3)2.2,直⽅图的标准化 (3)三,建⽴模型描述 ......................................................................... 3~43.1,利⽤matlab提供的函数处理 (4)3.2,利⽤matlab⾃⾏编辑代码 (4)四,源程序代码 ............................................................................. 5~64.1,绘制图像直⽅图的代码 (5)4.2,绘制图像均衡化后直⽅图的代码 (5)4.3,显⽰均衡化后图像的代码 (6)五,调试过程及结论 ..................................................................... 6~85.1,在编辑窗⼝键⼊绘制直⽅图的源代码得到的输出结果为图2 (6)5.2,利⽤matlab函数绘制的图像直⽅图标准化的输出结果如图3..75.3,直⽅图均衡化输出结果如图4所⽰。
(8)六,⼼得体会 (9)七,参考⽂献 (9)图像直⽅图的均衡化处理⼀,技术要求1.1,利⽤matlab提供的函数处理利⽤matlab提供的函数画出⼀幅图像的直⽅图,对其进⾏均衡化和标准化处理,并⽐较均衡化(标准化)后图像和原图像的区别。
1.2,利⽤matlab⾃⾏编辑代码处理利⽤matlab⾃⾏编辑代码,实现⼀幅图像的直⽅图显⽰和均衡化的处理,同样⽐较处理前后两幅图像的区别,了解图像均衡化的效果和实际运⽤。
⼆,基本原理直⽅图是多种空域处理技术的基础。
它能有效的⽤于图像增强。
数字图像处理作业 直方图均衡

作业3:直方图均衡1.选取一张对比度不明显的彩色图像,编写MATLAB代码对RGB通道独立地进行直方图均衡,同时用PHOTOSHOP软件对其进行均衡,比较两种处理方法在效果上的差异。
使用R/G/B=image(:,:,1/2/3);提取图像的三个通道,imshow(R);显示三个通道的图像,imhist(R);显示对应颜色分量的直方图,r=histeq(R);分别对三个通道进行直方图均衡化,equated = cat(3,r,g,b);联合RGB三个数组,得到均衡化后的图像。
原图与matlab直方图均衡化后的图像原图的RGB分量均衡后的RGB分量在photoshop中处理图像后得到下图的结果。
Ps中得到的图像RGB通道独立直方图均衡得到的图像比较:选取的原图是逆光拍摄,颜色很暗,暗部细节很多。
经过matlab处理后,灰度级部分合并,灰度级较低的间隔变大,灰度级较高的间隔变小。
但对真彩色图像的直方图均衡化时,通过单纯地对RGB三个分量图像分别均衡、合并, 会使均衡后的图像出现轻微的色彩失真现象, 而且原图中灰度级较高的地方的细节部分缺失。
但是经过ps处理后的图像,原本灰度值较低的地方明显变亮,同时原本灰度值较高的地方仍然很好保留了,并没有出现matlab处理后的问题。
Ps处理后的图像色彩也很正常,没有出现失真的问题。
数字图像直方图的算法步骤:①列出原始图像的灰度级f j,j=0,1,…,L-1,②统计各灰度级的像素数目n j,j=0,1,…,L-1,③计算原始图像直方图各灰度级的频数p(f j)= n j/N,j=0,1,…,L-1,④计算累计分布函数C(j)=Σp(f k), j=0,1,…,L-1,⑤g i= INT[(g max-g min)C(f)+g min+0.5]2.阅读"Exact Hitogram Specification"这篇英文文献第二部分和第三部分,结合压缩包中MATLAB源代码,理解精确直方图均衡的算法原理,重点是借助空间滤波实现像素排序的算法原理,用(1)中图片,比较精确直方图均衡和PHOTOSHOP均衡的效果差异。
直方图均衡化、规定化程序及结果

一、直方图均衡化程序A=imread('a.jpg');I=rgb2gray(A);J=histeq(I);figure,imshow(A)figure,imshow(I);title('原灰色图像');figure,imhist(I);title('原图像的灰度直方图');figure,imhist(J);title('均衡化图像的直方图');figure,imshow(J);title('均衡化图像');图片1结果原灰色图像10002000300040005000600070008000原图像的灰度直方图0501001502002500均衡化图像的直方图050100150200250图片2结果0原图像的灰度直方图050100150200250020004000600080001000012000均衡化图像的直方图050100150200250均衡化图像二、直方图规定化程序I=imread('tire.tif');J=histeq(I,32);[counts,x]=imhist(J);Q=imread('a.jpg');figure;imshow(Q);title('原图像');A=rgb2gray(Q);figure;imhist(A);title('原图像直方图');M=histeq(A,counts);figure;imshow(M);title('直方图规定化后的图像'); figure;imhist(M);title('规定直方图');Figure;subplot(1,2,1); imhist(I,64); subplot(1,2,2); imhist(J,64); 图片1结果原图像10002000300040005000600070008000原图像直方图050100150200250直方图规定化后的图像200040006000800010000120001400016000规定直方图050100150200250图片2结果原图像0原图像直方图050100150200250直方图规定化后的图像200040006000800010000120001400016000规定直方图050100150200250。
直方图均衡化

直⽅图均衡化今天学习了下直⽅图均衡化的原理。
先来看看维基百科上的⼀个例⼦: 从这张未经处理的灰度图可以看出,其灰度集中在⾮常⼩的⼀个范围内。
这就导致了图⽚的强弱对⽐不强烈。
直⽅图均衡化的⽬的,就是使得灰度分布尽可能平均地“填满”整个灰度空间(0~255),就是做到直⽅图的上界是⼀条平⾏于X轴的直线(理想化)。
有了这个⽬标之后,开始推导。
这个推导过程从连续函数出发。
第⼀步:建⽴⼀个从灰度r到s的映射s=T(r)第⼆步:将均衡化后的直⽅图的分布H B 表⽰成原图灰度分布H A 的函数 --> H B(s)=H A(r)/T(r),原理见下。
第三步:理想化的灰度分母应为常数,得T(r)=k*H A(r),不妨另:k=C/A o .(A o为所有像素数)第四步:两边同时积分(0->L),由密度函数的归⼀化条件得 : s=T(L)=C,因为s取值也是0->L,所以C=L。
第五步:把连续函数写成离散形式以适应计算机的处理。
(写出来⼤概就是这样,⾃⼰也能理解,但是总是感觉怪怪的) 可以看出,直⽅图均衡化只是将直⽅图进⾏了伸缩变换,或者说是⼀个搬移。
将变化律低的部分挤压,将变化率⾼的部分拉伸,得到⼀个两边变化陡峭中间平滑的灰度分布(单峰的话就很明显)。
可以看看维基百科上直⽅图均衡化之后的例⼦: 通过观察可以发现,由于中间部分灰度被拉伸了,灰度的取值变得不是很“连续”。
这个就是直⽅图均衡化的⼀个缺点吧。
(其实是离散的问题)———————————————————————————————————————————————————————————————————————————————闲着⽆聊搞了个最简单的直⽅图均衡化⼩程序,⼤家可以⾃⼰拿去试⼀下。
接下来的计划是做⾃适应直⽅图均衡化和对⽐对限制的直⽅图均衡化。
代码:#include <iostream>#include <string>#include <io.h>#include <opencv2/opencv.hpp>#include<math.h>#include<cv.h>using namespace std;using namespace cv;void main(int argc, char** argv){//变量定义//图⽚类IplImage *src , *dst;IplImage *histframesrc , *histframedst;CvSize size;//直⽅图类CvHistogram *histo_src , *histo_dst;int scale;float histmin,histmax;int bins=256;float range[]={0,255};float *ranges[]={range};//杂家int i,j,k,m,n; //循环变量……⽽已float s_r[256]; //S(r)映射函数//---------------------------------------------------------------src=cvLoadImage("11.jpg",0); //图⽚变量初始化cvShowImage("src",src);size=cvGetSize(src);dst=cvCreateImage(size,8,1);histo_src=cvCreateHist(1,&bins,CV_HIST_ARRAY,ranges); //直⽅图初始化histo_dst=cvCreateHist(1,&bins,CV_HIST_ARRAY,ranges);cvCalcHist(&src,histo_src,0,0); //计算直⽅图cvNormalizeHist(histo_src,1); //归⼀//累加,求S(r)映射s_r[0]=cvQueryHistValue_1D(histo_src,0);for(i=1;i<=255;i++){s_r[i]=s_r[i-1]+cvQueryHistValue_1D(histo_src,i);}//当然要把是S(r)归⼀到255啦for(i=0;i<=255;i++){s_r[i]=cvRound(s_r[i]*255);}//遍历图像并由sr关系进⾏直⽅图均衡化啦CvScalar s;for(m=0;m<size.height;m++){for(n=0;n<size.width;n++){s=cvGet2D(src,m,n);i=s.val[0];i=s_r[i];s.val[0]=i;cvSet2D(dst,m,n,s);}}//计算dst直⽅图cvCalcHist(&dst,histo_dst,0,0);cvNormalizeHist(histo_dst,1);//SHOWOFF⼀下啦cvShowImage("dst",dst);scale=1;//画出src和dst的直⽅图histframesrc=cvCreateImage( cvSize(bins*scale,256),8,1);histframedst=cvCreateImage( cvSize(bins*scale,256),8,1);//src的cvGetMinMaxHistValue(histo_src , &histmin , &histmax , 0 , 0 );for(int i = 0; i < bins; i++){/** 获得直⽅图中的统计次数,计算显⽰在图像中的⾼度 */float bin_val = cvGetReal1D(histo_src->bins,i);bin_val=bin_val*255/histmax;s.val[0]=cvRound(bin_val);cvRectangle(histframesrc,cvPoint(i*scale,256),cvPoint((i+1)*scale,256-bin_val),s,-1,8,0); }cvShowImage("src's hisogram",histframesrc);//dst的cvGetMinMaxHistValue(histo_dst , &histmin , &histmax , 0 , 0 );for(int i = 0; i < bins; i++){/** 获得直⽅图中的统计次数,计算显⽰在图像中的⾼度 */float bin_val = cvGetReal1D(histo_dst->bins,i);bin_val=bin_val*255/histmax;cout<<bin_val<<"\t";s.val[0]=cvRound(bin_val);cvRectangle(histframedst,cvPoint(i*scale,256),cvPoint((i+1)*scale,256-bin_val),s,-1,8,0); }cvShowImage("dst's hisogram",histframedst);//输出sr试⼀下for(i=0;i<=255;i++)cout<<s_r[i]<<"\n";for(;;)if(cvWaitKey(0)==27)break;}结果:(直⽅图变得平缓了但是中间部分变得稀疏了)。