资源描述
VC++的源程序如下;
// txclView.cpp : implementation of the CTxclView class
//
#include "stdafx.h"
#include "txcl.h"
#include "txclDoc.h"
#include "txclView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTxclView
int m_yuan[256],m_hist[256];
IMPLEMENT_DYNCREATE(CTxclView, CView)
BEGIN_MESSAGE_MAP(CTxclView, CView)
//{{AFX_MSG_MAP(CTxclView)
ON_COMMAND(OPEN, OnOPEN)
ON_COMMAND(His, OnHis)
//}}AFX_MSG_MAP
// Standard printing commands
ON_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()
/////////////////////////////////////////////////////////////////////////////
// CTxclView construction/destruction
CTxclView::CTxclView()
{
// TODO: add construction code here
}
CTxclView::~CTxclView()
{
}
BOOL CTxclView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CTxclView drawing
void CTxclView::OnDraw(CDC* pDC)
{
CTxclDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(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);
}
}
/////////////////////////////////////////////////////////////////////////////
// CTxclView printing
BOOL CTxclView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CTxclView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CTxclView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CTxclView diagnostics
#ifdef _DEBUG
void CTxclView::AssertValid() const
{
CView::AssertValid();
}
void CTxclView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CTxclDoc* CTxclView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTxclDoc)));
return (CTxclDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CTxclView message handlers
void CTxclView::OnOPEN()
{
// TODO: Add your command handler code here
static 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;
}
}
Invalidate(1); //刷新屏幕
}
void CTxclView::OnHis()
{
// 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]={0};//定义一个数组,存放灰度级频率
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]={0};
for(k=0;k<256;k++)
{
sum+=p[k];
c[k]=sum; //计算累计直方图
ngray[k]=(int)(255*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]; //均衡化
}
if(m_dib.m_bLoaded==true)
{
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();
//刷新屏幕
Invalidate();
}
CDIB程序;
#if !defined (__DIB_H__)
#define __DIB_H__
#if _MSC_VER>=1000
#pragma once
#endif
//DBI.H:header file
//
////////////////////////
//CDIB class
class CDIB:public CObject{
public:
int m_nImType;
void close();
void UpdateData();
void InvalidateData();
BYTE *m_pdata;
BYTE *m_pR,*m_pG,*m_pB;
void ShowDIB(CDC *,int,int,int,int,BYTE*,BITMAPINFO*);
bool m_bLoaded;
CDIB();
virtual ~CDIB();
BITMAPINFO* m_pBMI; //BITMAPINFO pointer
BYTE* m_pDIBData; //DIB data pointer
BYTE* m_pDumpDIBData;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
CPalette *m_pPalette;
DWORD dataBytes;
bool SaveFile(LPCTSTR lpszFileName);
virtual bool LoadFromFile(LPCTSTR lpszFileName);
int GetDIBWidth()
{
return m_pBMI->bmiHeader.biWidth;
}
int GetDIBHeight()
{
return m_pBMI->bmiHeader.biHeight;
}
};
////////////////////////
#endif // !defined (__DIB_H__)
MATLAB程序;
RGB = imread('1.png'); % 读取彩色图
subplot(131);
imshow(RGB);
title('彩色图');
I=rgb2gray(RGB); % 将彩色图转化为灰度图
subplot(132);
imshow(I);
title('灰度图');
[R, C] = size(I);
% 统计每个像素值出现次数
cnt = zeros(1, 256);
for i = 1 : R
for j = 1 : C
cnt(1, I(i, j) + 1) = cnt(1, I(i, j) + 1) + 1;
end
end
f = zeros(1, 256);
f = double(f); cnt = double(cnt);
% 统计每个像素值出现的概率, 得到概率直方图
for i = 1 : 256
f(1, i) = cnt(1, i) / (R * C);
end
% 求累计概率,得到累计直方图
for i = 2 : 256
f(1, i) = f(1, i - 1) + f(1, i);
end
% 用f数组实现像素值[0, 255]的映射。
for i = 1 : 256
f(1, i) = f(1, i) * 255;
end
% 完成每个像素点的映射
I = double(I);
for i = 1 : R
for j = 1 : C
I(i, j) = f(1, I(i, j) + 1);
end
end
% 输出
I = uint8(I);
subplot(133);
imshow(I);
title('直方图均衡化');
展开阅读全文