一、直方图均衡化
1. 如何用在MFC中画直方图:
这是一个对话框类的成员函数,IDC_PIC2是对话框中picture control的控件ID,目标直方图计划要画在picture control中。
source_image是CImage类型的一个对象,因为是对灰度级为256的图片进行直方图均衡化,所以默认数据数组大小256.
plot_hist()函数得到该图像各点的频数,并把频数的数组存到data数组中。
source_image.plot_hist();
LONG* data = source_image.data;
void IDD_GRAPH::OnDraw(){
CRect rectClient;
CWnd *pWnd = GetDlgItem(IDC_PIC2);
pWnd->GetClientRect(&rectClient);
CDC *pDC = pWnd->GetDC();
HDC hDC= pDC->GetSafeHdc();
SIZE sz;
sz.cx = rectClient.Width()-30;
sz.cy = rectClient.Height()-70;
int nLength = 256;
source_image.plot_hist();
LONG* data = source_image.data;
CPoint origin(10,sz.cy+10);//原点坐标(10, sz高度+20)
CString str;
pDC->Rectangle(0,0,sz.cx+30,sz.cy+70);//轮廓大小,上空10,下空20
CPen cyPen(PS_SOLID,2,RGB(0,0,0));
CPen *oldPen=pDC->SelectObject(&cyPen);
pDC->MoveTo(origin); // 移到原点
pDC->LineTo(origin.x+sz.cx+5,origin.y);//画X轴
pDC->LineTo(origin.x+sz.cx,origin.y+5);
pDC->MoveTo(origin.x+sz.cx+5,origin.y);//画X轴箭头
pDC->LineTo(origin.x+sz.cx,origin.y-5);
pDC->MoveTo(origin); // 移到原点
pDC->LineTo(origin.x,origin.y-sz.cy);
pDC->MoveTo(origin.x-5,origin.y-sz.cy+5);//画Y轴箭头
pDC->LineTo(origin.x,origin.y-sz.cy);
pDC->LineTo(origin.x+5,origin.y-sz.cy+5);
pDC->TextOut(origin.x+10,origin.y+20,"Histogram of source image");//图名
for(int i=0;i<nLength;i=i+50)//刻度
{
str.Format("%d",i);
pDC->TextOut(origin.x+i,origin.y+3,str);
}
CPen redPen(PS_SOLID,1,RGB(255,0,0)); //红
oldPen=pDC->SelectObject(&redPen);
long total=0;
long lMaxCount=0;
int idMax;
lMaxCount=Max(data,nLength,idMax);
if(lMaxCount>0)
{
for(int i=0;i<nLength;i++)
{
pDC->MoveTo(origin.x+i,origin.y);
pDC->LineTo(origin.x+i,origin.y+1-(int)(data[i]*sz.cy/lMaxCount));
total+=data[i];
}
}
CString strmax;
strmax.Format("最值为%d,数目为%d",idMax,lMaxCount);
pDC->TextOut(origin.x+10,ori