================================================================================
MICROSOFT 基础类库: ImageProcessing 项目概述
===============================================================================
应用程序向导已为您创建了这个 ImageProcessing 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写应用程序的起点。
本文件概要介绍组成 ImageProcessing 应用程序的每个文件的内容。
ImageProcessing.vcxproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件。
它包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
ImageProcessing.vcxproj.filters
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。
它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
ImageProcessing.h
这是应用程序的主要头文件。它包括其他项目特定的头文件(包括 Resource.h),并声明 CImageProcessingApp 应用程序类。
ImageProcessing.cpp
这是包含应用程序类 CImageProcessingApp 的主要应用程序源文件。
ImageProcessing.rc
这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源位于 2052 中。
res\ImageProcessing.ico
这是用作应用程序图标的图标文件。此图标包括在主要资源文件 ImageProcessing.rc 中。
res\ImageProcessing.rc2
此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
/////////////////////////////////////////////////////////////////////////////
对于主框架窗口:
项目包含标准 MFC 界面。
MainFrm.h, MainFrm.cpp
这些文件包含框架类 CMainFrame,该类派生自
CFrameWnd 并控制所有 SDI 框架功能。
/////////////////////////////////////////////////////////////////////////////
应用程序向导创建一个文档类型和一个视图:
ImageProcessingDoc.h,ImageProcessingDoc.cpp - 文档
这些文件包含 CImageProcessingDoc 类。编辑这些文件可以添加特殊文档数据并可实现文件保存和加载(通过 CImageProcessingDoc::Serialize)。
ImageProcessingView.h,ImageProcessingView.cpp - 文档的视图
这些文件包含 CImageProcessingView 类。
CImageProcessingView 对象用于查看 CImageProcessingDoc 对象。
/////////////////////////////////////////////////////////////////////////////
其他功能:
ActiveX 控件
应用程序包括对使用 ActiveX 控件的支持。
打印及打印预览支持
应用程序向导已通过从 MFC 库调用 CView 类中的成员函数,生成了用于处理打印、打印设置和打印预览命令的代码。
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.h,StdAfx.cpp
这些文件用于生成名为 ImageProcessing.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
Resource.h
这是标准头文件,它定义新的资源 ID。
Microsoft Visual C++ 读取并更新此文件。
ImageProcessing.manifest
应用程序清单文件供 Windows XP 用来描述应用程序
对特定版本并行程序集的依赖性。加载程序使用此
信息从程序集缓存加载适当的程序集或
从应用程序加载私有信息。应用程序清单可能为了重新分发而作为
与应用程序可执行文件安装在相同文件夹中的外部 .manifest 文件包括,
也可能以资源的形式包括在该可执行文件中。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。
如果应用程序在共享的 DLL 中使用 MFC,则需要重新发布这些 MFC DLL;如果应用程序所用的语言与操作系统的当前区域设置不同,则还需要重新发布对应的本地化资源 MFC100XXX.DLL。有关这两个主题的更多信息,请参见 MSDN 文档中有关 Redistributing Visual C++ applications (重新发布 Visual C++ 应用程序)的章节。
/////////////////////////////////////////////////////////////////////////////
开发过程中的备忘整理
CImage 浅拷贝
对象创建后,指向资源的指针并未分配内存。
isNull()
inline bool CImage::IsNull() const throw()
{
return( m_hBitmap == NULL );
}
使用前,先销毁对象
if(!image2.IsNull())
{
image2.Destroy();
}
image2.Create(500,500,32,CImage::createAlphaChannel);??
另外 HBITMAP m_hBitmap这个成员变量何时赋值
creat中会对bitmap赋值吗?
关于图像是否是索引的,isIndexed
void ImageCopy(CImage* pImgSrc, CImage* pImgDrt)
{
int MaxColors = imgOriginal.GetMaxColorTableEntries();
RGBQUAD* ColorTab;
ColorTab = new RGBQUAD[MaxColors];
CDC *pDCsrc,*pDCdrc;
if (!pImgDrt->IsNull())
{
pImgDrt->Destroy();
}
pImgDrt->Create(pImgSrc->GetWidth(),pImgSrc->GetHeight(),pImgSrc->GetBPP(),0);
if (pImgSrc->IsIndexed())
{
pImgSrc->GetColorTable(0,MaxColors,ColorTab);
pImgDrt->SetColorTable(0,MaxColors,ColorTab);
}
pDCsrc=CDC::FromHandle(pImgSrc->GetDC());
pDCdrc=CDC::FromHandle(pImgDrt->GetDC());
pDCdrc->BitBlt(0,0,pImgSrc->GetWidth(),pImgSrc->GetHeight(),pDCsrc,0,0,SRCCOPY);
pImgSrc->ReleaseDC();
pImgDrt->ReleaseDC();
delete ColorTab;
}
inline void CImage::Destroy() throw()
{
HBITMAP hBitmap;
if( m_hBitmap != NULL )
{
hBitmap = Detach();
::DeleteObject( hBitmap );
}
}
图像灰度化
void CEx_ImageView::OnToGray()//Cyan:添加
{
if(m_Image.IsNull())
return;
if(!m_Image.IsIndexed())
{
//直接修改像素颜色
COLORREF pixel;
int maxY=m_Image.GetHeight();
int maxX=m_Image.GetWidth();
byte r,g,b,avg;
for(int x=0;x<maxX;x++)
{
for(int y=0;y<maxY;y++)
{
pixel=m_Image.GetPixel(x,y);
r=GetRValue(pixel);
g=GetGValue(pixel);
b=GetBValue(pixel);
avg=(int)(((int)r+g+b)/3);
m_Image.SetPixelRGB(x,y,avg,avg,avg);
}
}
}
else
{
//获取并修改颜色表
int maxColors=m_Image.GetMaxColorTableEntries();
RGBQUAD* lpColorTable;
lpColorTable=new RGBQUAD[maxColors];
m_Image.GetColorTable(0,maxColors,lpColorTable);
for(int i=0;i<maxColors;i++)
{
int avg=(lpColorTable[i].rgbRed+lpColorTable[i].rgbGreen+lpColorTable[i].rgbBlue)/3;
lpColorTable[i].rgbRed=avg;
lpColorTable[i].rgbGreen=avg;
lpColorTable[i].rgbBlue=avg;
}
m_Image.SetColorTable(0,maxColors,lpColorTable);
delete(lpColorTable);
}
Invalidate();//强制调用OnDraw
}
句柄的使用:通过句柄得到对象 Attach
HBITMAP hBitmap=image.Detach();
CBitmap bmp;
bmp.Attach(hBitmap);
销毁对话框时,iamge2.destroy
GetPixel? gray=*(pRealData + nPitch*y + x*bitCount);
dlg.DoModal();
*(pRealData + nPitch*y + x*bitCount)=grayVal;
*(pRealData + nPitch*y + x*bitCount +1)=grayVal;
*(pRealData + nPitch*y + x*bitCount +2)=grayVal;
image2.SetPixel(x,y,RGB(target,target,target));
直方图均衡化 :分割界面需求
均衡化算法
直方图均衡化算法分为三个步骤,第一步是统计直方图每个灰度级出现的次数,第二步是累计归一化的直方图,第三步是计算新的像素值。
第一步:
for(i=0;i<height;i++){
for(j=0;j<width;j++){
n[s[i][j]]++;
}
}
for(i=0;i<L;i++){
p[i]=n[i]/(width*height);
}
这里,n[i]表示的是灰度级为i的像素的个数,L表示的是最大灰度级,width和height分别表示的是原始图像的宽度和高度,所以,p[i]表示的就是灰度级为i的像素在整幅图像中出现的概率(其实就是p[]这个数组存储的就是这幅图像的归一化之后的直方图)。
第二步:
for(i=0;i<=L;i++){
for(j=0;j<=i;j++){
c[i]+=p[j];
}
}
c[]这个数组存储的就是累计的归一化直方图。
第三步:
max=min=s[0][0];
for(i=0;i<height;i++){
for(j=0;j<width;j++){
if(max<s[i][j]){
max=s[i][j];
}else if(min>s[i][j]){
min=s[i][j];
}
}
}
找出像素的最大值和最小值。
for(i=0;i<height;i++){
for(j=0;j<width;j++){
t[i][j]=c[s[i][j]]*(max-min)+min;
}
}
t[][]就是最终直方图均衡化之后的结果。