图像阈值分割讲稿Word格式文档下载.docx
《图像阈值分割讲稿Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《图像阈值分割讲稿Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
图2
选择“CFengeView”。
点击“EditCode”,在自动生成“OnYuZhiFenGe”
函数中编写代码:
OnYuZhiFenGe()
if(m_Dib.IsValid())
inti;
intYuzhi;
//阈值变量
//各颜色分量的灰度分布密度
floatmidu[256];
//计算灰度分布密度
m_Dib.Zhifangtu(midu);
//调用灰度统计处理函数
//创建灰度直方图对话框
CDlgZhiFangTu*dlg;
dlg=newCDlgZhiFangTu(this);
dlg->
Create(IDD_DIALOG_ZhiFangTu);
//传递灰度分布密度数据给面板类
for(i=0;
i<
256;
i++)
m_fIntensity[i]=midu[i];
//显示对话框,由用户进行灰度折线变换
ShowWindow(SW_RESTORE);
//创建阈值选择对话框
CDlgYuZhiFenGedlg1;
dlg1.m_Yuzhi=0;
//显示对话框,提示用户输入阈值
if(dlg1.DoModal()==IDOK)
Yuzhi=dlg1.m_Yuzhi;
//删除对话框
deletedlg1;
deletedlg;
m_Dib.Yuzhifenge(Yuzhi);
//调用阈值分割处理函数
//重绘
Invalidate();
}
4、创建一个处理位图的类CDib,且CDib类是由CObject类派生出来的。
点击工程菜单栏中的插入【insert】→【insertclass】→类类型选“GenericClass”,→类名称填“CDib”→【ok】。
可以看见工程窗口的ClassView中多了一个CDib类;
点开CDib类的头文件,输入以下代码,注意变量可以直接复制,声明的函数不要直接复制(在CDib类右击选择“Addmemberfunction”,输入函数类型和函数名)。
classCDib:
publicCObject
public:
RGBQUAD*m_pRGB;
BYTE*m_pData;
UINTm_numberOfColors;
boolm_valid;
BITMAPFILEHEADERbitmapFileHeader;
//定义了一个文件头结构体的对象
BITMAPINFOHEADER*m_pBitmapInfoHeader;
//定义了一个指向信息头的结构体指针
BITMAPINFO*m_pBitmapInfo;
//定义了一个结构体指针,BITMAPINFO是一个包含有信息头,和调色板的结构体
intbyBitCount;
DWORDdwWidthBytes;
BYTE*pDib;
DWORDsize;
charm_fileName[256];
voidYuzhifenge(intYuzhi);
voidZhifangtu(float*tongji);
voidLoadFile(constchar*dibFileName);
voidSaveFile(constCStringfilename);
WORDDIBNumColors(LPBYTElpDIB);
WORDPaletteSize(LPBYTElpDIB);
BITMAPINFO*GetInfo();
BYTE*GetData();
RGBQUAD*GetRGB();
UINTGetNumberOfColors();
UINTGetHeight();
UINTGetWidth();
DWORDGetSize();
boolIsValid();
char*GetFileName();
CDib();
virtual~CDib();
};
6、对CDib类中的函数定义,找到Dib.cpp输入代码:
CDib:
CDib()
m_numberOfColors=0;
size=0;
m_valid=0;
byBitCount=0;
dwWidthBytes=0;
~CDib()
GlobalFreePtr(m_pBitmapInfo);
char*CDib:
GetFileName()
returnm_fileName;
boolCDib:
IsValid()
returnm_valid;
DWORDCDib:
GetSize()
if(m_pBitmapInfoHeader->
biSizeImage!
=0)
returnm_pBitmapInfoHeader->
biSizeImage;
}
else
DWORDheight=(DWORD)GetHeight();
DWORDwidth=(DWORD)GetWidth();
returnheight*width;
UINTCDib:
GetHeight()
return(UINT)m_pBitmapInfoHeader->
biHeight;
GetNumberOfColors()
intnumberOfColors;
if((m_pBitmapInfoHeader->
biClrUsed==0)&
&
(m_pBitmapInfoHeader->
biBitCount<
9))
//biClrUsed表示实际用到的颜色数,若0为2的biBitCount次中颜色
//biBitCount为用到的颜色的位数,小于9则表示最大为8位,那么之多为256色
switch(m_pBitmapInfoHeader->
biBitCount)
{
case1:
numberOfColors=2;
break;
case4:
numberOfColors=16;
case8:
numberOfColors=256;
}
else//若不是上面的情况,则直接返回颜色数
numberOfColors=(int)m_pBitmapInfoHeader->
biClrUsed;
returnnumberOfColors;
RGBQUAD*CDib:
GetRGB()
returnm_pRGB;
BYTE*CDib:
GetData()
returnm_pData;
BITMAPINFO*CDib:
GetInfo()
returnm_pBitmapInfo;
WORDCDib:
PaletteSize(LPBYTElpDIB)
return(DIBNumColors(lpDIB)*sizeof(RGBTRIPLE));
DIBNumColors(LPBYTElpDIB)
WORDwBitCount;
//DIBbitcount
wBitCount=((LPBITMAPCOREHEADER)lpDIB)->
bcBitCount;
switch(wBitCount)
case1:
return2;
case4:
return16;
case8:
return256;
default:
return0;
voidCDib:
SaveFile(constCStringfilename)
strcpy(m_fileName,filename);
CFiledibFile(m_fileName,CFile:
modeCreate|CFile:
modeWrite);
dibFile.Write((void*)&
bitmapFileHeader,sizeof(BITMAPFILEHEADER));
dibFile.Write((void*)pDib,size);
dibFile.Close();
LoadFile(constchar*dibFileName)
strcpy(m_fileName,dibFileName);
//将路径名称拷贝到m_fileName之中
modeRead);
//创建CFile类对象,只读方式
dibFile.Read((void*)&
//读取文件头的内容
if(bitmapFileHeader.bfType==0x4d42)//判断是否为bmp格式,单步调试你会发现,此时的bfType值
DWORDfileLength=dibFile.GetLength();
//读取文件的大小,你可以试试跟踪此值来看看它是否和你要打开的图片大小一致
size=fileLength-sizeof(BITMAPFILEHEADER);
//文件大小-文件头结构体的大小,此时你会发现,文件头的大小的确是14字节
pDib=(BYTE*)GlobalAllocPtr(GMEM_MOVEABLE,size);
//详见说明
(2)
dibFile.Read((void*)pDib,size);
//通过读取,把读出的数据存入刚才分配的内存之中
dibFile.Close();
//文件操作完成之后关闭文件
m_pBitmapInfo=(BITMAPINFO*)pDib;
//BITMAPINFO结构体指针指向该内存
m_pBitmapInfoHeader=(BITMAPINFOHEADER*)pDib;
//信息头指向该内存
m_pRGB=(RGBQUAD*)(pDib+m_pBitmapInfoHeader->
biSize);
//调色板指针指向该内存的调色板部分。
因为pDib原本指向信息头,偏移40字节(信息头结构体的大小)之后便到了调色板部分,因此用加法来实现指针的偏移
intm_numberOfColors=GetNumberOfColors();
//调用GetNumberOfColors函数来得到颜色数
if(m_pBitmapInfoHeader->
biClrUsed==0)
m_pBitmapInfoHeader->
biClrUsed=m_numberOfColors;
//把颜色数赋予biClrUsed之中
DWORDcolorTableSize=m_numberOfColors*
sizeof(RGBQUAD);
//用每个调色板结构体大小乘以颜色数量,得到调色板的大小
m_pData=pDib+m_pBitmapInfoHeader->
biSize+colorTableSize;
//这时候代表把m_pData指针指向实际图像数据了
if(m_pRGB==(RGBQUAD*)m_pData)//如果调色板指针位置和实际图像位置指针指向位置相同,那就代表没有调色板
m_pRGB=NULL;
//指针赋予空
m_pBitmapInfoHeader->
biSizeImage=GetSize();
//赋予实际位图的大小
m_valid=true;
else//如果不是bmp位图则失败
m_valid=false;
AfxMessageBox("
Thisisn'
tabitmapfile!
"
);
GetWidth()
biWidth;
Zhifangtu(float*tongji)
//循环变量
intj;
//灰度计数
inthuidu[256];
intwide,height;
//原图长、宽
//变量初始化
memset(huidu,0,sizeof(huidu));
if(m_pBitmapInfoHeader->
9)//灰度图像
wide=this->
GetWidth();
height=this->
GetHeight();
intwidth=(((wide*24)+31)/32*4);
LPBYTEtemp1=newBYTE[wide*height+1024];
//新图像缓冲区
//拷贝原图像到缓存图像
memcpy(temp1,m_pData,wide*height);
//对各像素进行灰度统计
for(i=0;
height;
i++)
for(j=0;
j<
wide;
j++)
{
unsignedchartemp=temp1[wide*i+j];
//灰度统计计数
huidu[temp]++;
}
//计算灰度分布密度
for(i=0;
i<
i++)
tongji[i]=huidu[i]/(height*wide*1.0f);
Yuzhifenge(intYuzhi)
//指向源图像的指针
LPBYTEp_data;
LPBYTElpSrc;
//指向缓存图像的指针
LPBYTElpDst;
//指向缓存DIB图像的指针
LPBYTEtemp;
//循环变量
longi;
longj;
//图像的高和宽
longwide;
longheight;
p_data=GetData();
wide=GetWidth();
height=GetHeight();
temp=newBYTE[wide*height];
memset(temp,255,wide*height);
for(j=0;
j<
height;
j++)
lpSrc=p_data+wide*j+i;
lpDst=temp+wide*j+i;
if(abs(*lpSrc-Yuzhi)<
30)
*lpDst=Yuzhi;
memcpy(p_data,temp,wide*height);
deletetemp;
7、创建一个对话框类CDlgYuZhiFenGe和CDlgZhiFangTu,且CDlgYuZhiFenGe和CDlgZhiFangTu类是由CDialog类派生出来的。
点击工程菜单栏中的【插入】→【窗体】→名称填“CDlgYuZhiFenGe”,→基类填“CDialog”→【确定】。
可以看见工程窗口的ClassView中多了一个CDlgYuZhiFenGe类;
CDlgZhiFangTu类同理。
8、在资源视图中做两个界面,分别为
阈值选择ID:
IDD_DIALOG_YuZhiFenGe
直方图灰度统计ID:
IDD_DIALOG_ZhiFangTu
做“阈值选择”界面如下图3,
阈值ID:
IDC_STATIC(默认)
编辑ID:
IDC_EDIT1(默认)
图3
右键编辑框,选“类向导”→“MemberVariable”选项卡中点“IDC_EDIT1”→“AddVariable”,弹出的对话框中如下图4填:
图4
在资源视图中做“直方图灰度统计”界面如图5,并在灰度直方图统计中添加“图像“控件,图像控件的ID为IDC_COORD(默认)。
图5
添加CDlgZhiFangTu的类向导,在灰度直方图对话框上右键点击建立类向导,设置如下图
图6
9、找到类CFengeView中的OnDraw(CDC*pDC)函数输入以下代码:
OnDraw(CDC*pDC)
CFengenDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
adddrawcodefornativedatahere
if(m_Dib.IsValid())
BYTE*pBitmapData=m_Dib.GetData();
LPBITMAPINFOpBitmapInfo=m_Dib.GetInfo();
intbitmapHeight=m_Dib.GetHeight();
intbitmapWidth=m_Dib.GetWidth();
intscaleWidth=(int)(bitmapWidth*m_scale);
intscaleHeitht=(int)(bitmapHeight*m_scale);
:
StretchDIBits(pDC->
GetSafeHdc(),0,0,scaleWidth,scaleHeitht,0,0,bitmapWidth,bitmapHeight,pBitmapData,pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
10、找到类CFengeView中的“CFengeView:
CFengeView()”函数输入以下代码:
CFengeView:
CFengeView()
addconstructioncodehere
m_scale=1;
m_fileName="
"
11、最后编译。
提示:
需要加入头文件,各个变量。
特别的floatm_fIntensity[256];
提示定义GlobalFreePtr和GlobalAllocPtr,需要加入头文件#include"
windowsx.h"