📄 imagecodesdoc.cpp
字号:
}
void CImageCodesDoc::show()
{
if ( hBitmap )
{
if ( DIB )
delete DIB;
DIB = new CDIBSectionLite;
DIB->SetBitmap( hBitmap );//重要!!!
// Display image information
CStatusBar * p = (CStatusBar * ) AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
if (p)
{
CString cImageInfo;
int iColors;
switch (DIB->GetBitCount())
{
case 1: iColors = 2; break;
case 4: iColors = 16; break;
case 8: iColors = 256; break;
case 24: iColors = 256*256*256; break;
default: iColors = 0; break;
}
cImageInfo.Format( "%d x %d x %d", DIB->GetWidth(), DIB->GetHeight(), iColors );
p->SetPaneText(p->CommandToIndex(ID_INDICATOR_IMAG), cImageInfo, TRUE);
}
}
else
{
const char *msg;
GetLastBMGErrorMessage( &msg );
AfxGetApp()->m_pMainWnd->MessageBox( msg, "BMG error", MB_OK | MB_ICONERROR );
}
AfxGetApp()->m_pMainWnd->Invalidate();
}
void CImageCodesDoc::TransTo2D()
{
unsigned int m,count;//m对字节操作,count对象素操作
unsigned int r=0,c=0;//r,c,分别代表行、列;
transflag=true;
//下面把结构体中的一维数组*bits读出并转化为二维数组**trans
//调用一次TransTo2D就使每一个象素的RGB值存入二维数组trans中,
//顺序为0X00BBGGRR,而且trans的值不再改变,直到再打开一幅新图象
for(count=0,m=0,r=-1,c=0;count<r0*c0;count++)
{
if(count%c0==0) r++;
c=count%c0;
unsigned int temp1,temp2,temp3;
temp1=img.bits[m];
temp2=img.bits[m+1];
temp3=img.bits[m+2];
trans[r][c]=temp1*256*256+temp2*256+temp3;
m+=3;
}
for(;c<c0-1;c++)
trans[r][c]=0;//用0填充剩余部分
}
void CImageCodesDoc::TransBack(unsigned int **trans)
{
//该函数在调用显示函数Display前必须调用,因为它把处理后的
//二维象素值阵列转化为一维无符号字符型,以与img相关联,并显示。
unsigned int m,r,c;//r,c,分别代表行、列;
for(r=0,m=0;r<r0;r++)
for(c=0,m=0;c<c0;c++)
{
back[r*3*c0+m+2]=trans[r][c]%256;
back[r*3*c0+m+1]=(trans[r][c]/256)%256;
back[r*3*c0+m]=(trans[r][c]/256)/256;
m+=3;
}
}
//把二维数组trans的值输出到d盘上的文件中
void CImageCodesDoc::DataOutToFile(unsigned int **trans)
{
::SetCursor(mHWait);
fstream file;
unsigned int r=0;
unsigned int c=0;
static int temp=0;
if(temp==0)
file.open("d:\\out.txt",ios::out),temp++;
else if(temp==1)
file.open("d:\\out1.txt",ios::out),temp++;
else
file.open("d:\\out2.txt",ios::out),temp=0;
if(!file) exit(1);
for(r=0;r<r0;r++)
{
for(c=0;c<c0;c++)
file<<trans[r][c]<<" ";
file<<'\n';
}
file.close();
file.open("d:\\out1.txt",ios::out);
if(!file) exit(1);
for(r=0;r<r0*c0*3;r++)
{
file<<back[r]<<' ';
if(r%15==0) file<<endl;
}
file.close();
::SetCursor(mHArrow);
}
void CImageCodesDoc::OnProcessDataout()
{
// TODO: Add your command handler code here
if(transflag==false) TransTo2D();//先要保证trans中有值
DataOutToFile(trans);
}
void CImageCodesDoc::CopyBackToBits()//把back中的值拷贝到bits中
{
unsigned int r=0;
unsigned int c=0;
for(r=0;r<r0*c0*3;r++)
{
img.bits[r]=back[r];
}
}
void CImageCodesDoc::Display()
{
//img的bits所指的象素值一旦改变,就可以通过下面
//三条语句来显示更改后的图像。very important !!!
//或者直接调用Display函数!
CopyBackToBits();
hBitmap=CreateBitmapFromData( img, 0 );
show();
}
void CImageCodesDoc::OnProcessGray()
{
label=false;//表示是对当前图处理
Gray();//把图像灰度化,并且每个像素占8位
ConvertTo24Bits(GrayValue);//为了不降低亮度,要让每个像素占24位。
TransBack(GrayValue);//把二维数组转化为一维数组
Display(); //转化为一维数组后,就可以调用dispay直接输出了
ConvertTo8Bits(GrayValue);//让GrayValue中仅保存灰度像素的8位有效值
}
void CImageCodesDoc::Gray()
{
// TODO: Add your command handler code here
//该函数使用后,灰度矩阵GrayValue中有8位值,而且不在改变
//直到再打开一幅新的图像
::SetCursor(mHWait);
unsigned int r,c;
if(transflag==false) TransTo2D();
Grayflag=true;//灰度矩阵中已经有值
for(r=0;r<r0;r++)
for(c=0;c<c0;c++)
{
unsigned int t,t1,t2,t3;
t1=trans[r][c]%256;
t2=(trans[r][c]/256)%256;
t3=(trans[r][c]/256)/256;
t=(unsigned int)(0.3*t1+0.59*t2+0.11*t3);//灰度化公式
GrayValue[r][c]=t;
}
::SetCursor(mHArrow);
}
void CImageCodesDoc::OnProcessRecover()
{
// TODO: Add your command handler code here
if(transflag==false)
{
AfxMessageBox("对不起,您还没有对原始图进行处理!");
return;
}
label=false;
TransBack(trans);
Display();
}
void CImageCodesDoc::TemplateConvolution(double T[3][3])
{
unsigned int r,c,i,j;
double sum=0.0;
if(label==TRUE)//是进行当前图处理
{
if(convoflag==false)//检查convo是否为空
CopyGrayValueToConvo();
for(r=0;r<r0-2;r++)
for(c=0;c<c0-2;c++)
{
for(i=0;i<3;i++)//当前图处理都是使用上一步得出的convo值
for(j=0;j<3;j++)
sum+=T[i][j]*convo[r+i][c+j];
if(abs((int)(sum))>255)
GrayValue[r+1][c+1]=255;
else
GrayValue[r+1][c+1]=abs((int)(sum));
sum=0.0;
}
CopyGVToConvo();//我们编的接口一定要通过convo来显示,所以把临时数组GrayValue的值拷到convo中
Grayflag=false;//GrayValue充当一次临时数组后,灰度值已经改变
}
else//是进行原始图处理
{
if(Grayflag==false) Gray();//检查原始图是否已经灰度化
for(c=0;c<c0;c++)
{
convo[0][c]=255;
convo[r0-1][c]=255;
}
for(r=1;r<r0-1;r++)
{
convo[r][0]=255;
convo[r][c0-1]=255;
}
for(r=0;r<r0-2;r++)//原始图处理都是对灰度矩阵进行处理
for(c=0;c<c0-2;c++)
{
for(i=0;i<3;i++)
for(j=0;j<3;j++)
sum+=T[i][j]*GrayValue[r+i][c+j];
if(abs((int)(sum))>255) //并且把处理后的值放到convo中,以供显示。
convo[r+1][c+1]=255;
else
convo[r+1][c+1]=abs((int)(sum));
sum=0.0;
}
}
}
void CImageCodesDoc::OnProcessSobel()
{
// TODO: Add your command handler code here
//因为要用到两块模板,所以没直接调用模板卷积函数
label=false;//声明进行原始图处理
if(Grayflag==false) Gray();
unsigned int i,j,r,c;
unsigned int GrayColorx,GrayColory;
::SetCursor(mHWait);
for(c=0;c<c0;c++)
{
convo[0][c]=255;
convo[r0-1][c]=255;
}
for(r=1;r<r0-1;r++)
{
convo[r][0]=255;
convo[r][c0-1]=255;
}
for(i=1;i<r0-1;i++)
for(j=1;j<c0-1;j++)
{
GrayColorx=(GrayValue[i-1][j+1]+2*GrayValue[i][j+1]+GrayValue[i+1][j+1])
-(GrayValue[i-1][j-1]+2*GrayValue[i][j-1]+GrayValue[i+1][j-1]);
GrayColory=(GrayValue[i-1][j-1]+2*GrayValue[i-1][j]+GrayValue[i-1][j+1])
-(GrayValue[i+1][j-1]+2*GrayValue[i+1][j]+GrayValue[i+1][j+1]);
convo[i][j]=abs(GrayColorx)+abs(GrayColory);
if(convo[i][j]>255) convo[i][j]=255;
}
ConvertTo24Bits(convo);//为了不降低亮度,升为24位
TransBack(convo);//将convo值放到一维数组back中,以显示
Display();//显示back
ConvertTo8Bits(convo);//convo中仅保存灰度像素的8位有效值
::SetCursor(mHArrow);
}
void CImageCodesDoc::EdgeDetect(double T[3][3])
{
::SetCursor(mHWait);
TemplateConvolution(T);//先调用模板卷积函数,然后显示convo
ConvertTo24Bits(convo);
TransBack(convo);
Display();
ConvertTo8Bits(convo);
::SetCursor(mHArrow);
}
void CImageCodesDoc::ConvertTo24Bits(unsigned int **convo)
{
::SetCursor(mHWait);
unsigned int temp,r,c;
for(r=0;r<r0;r++)//将8位的灰度像素转化为24位的,以不降低亮度
for(c=0;c<c0;c++)
{
temp=convo[r][c]+convo[r][c]*256+convo[r][c]*256*256;
convo[r][c]=temp;
}
::SetCursor(mHArrow);
}
void CImageCodesDoc::ConvertTo8Bits(unsigned int **convo)
{
unsigned int r,c;
for(r=0;r<r0;r++)
for(c=0;c<c0;c++)
{
convo[r][c]%=256;//保留灰度像素的8位有效值
}
}
void CImageCodesDoc::OnProcessLap()
{
// TODO: Add your command handler code here
label=false;
double T[3][3]={0,1,0,1,-4,1,0,1,0}; //laplace模板
EdgeDetect(T);
}
void CImageCodesDoc::OnProcessAve()
{
// TODO: Add your command handler code here
label=false;
double T[3][3]={0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11,0.11}; //平滑模板
EdgeDetect(T);
}
void CImageCodesDoc::OnProcessHor()
{
// TODO: Add your command handler code here
label=false;
double T[3][3]={0,-1,0,0,1,0,0,0,0}; //水平边缘模板
EdgeDetect(T);
}
void CImageCodesDoc::OnProcessHv()
{
// TODO: Add your command handler code here
label=false;
double T[3][3]={-1,0,0,0,1,0,0,0,0};//垂直边缘模板
EdgeDetect(T);
}
void CImageCodesDoc::OnProcessMid()
{
// TODO: Add your command handler code here
label=false;
if(Grayflag==false) Gray();
::SetCursor(mHWait);
unsigned int r,c,sort[3][3];//sort存放需要排序的9个像素
unsigned int i,j;
for(c=0;c<c0;c++)
{
convo[0][c]=GrayValue[0][c];
convo[r0-1][c]=GrayValue[r0-1][c];
}
for(r=1;r<r0-1;r++)
{
convo[r][0]=GrayValue[r][0];
convo[r][c0-1]=GrayValue[r][c0-1];
}
for(r=0;r<r0-2;r++)
for(c=0;c<c0-2;c++)
{
for(i=0;i<3;i++)//把需要排序的9个像素拷贝到sort中
for(j=0;j<3;j++)
sort[i][j]=GrayValue[r+i][c+j];
convo[r+1][c+1]=SortAndSelectM(sort);//选取sort中的中间值赋给中心像素
}
ConvertTo24Bits(convo);//显示convo
TransBack(convo);
Display();
ConvertTo8Bits(convo);
convoflag=TRUE;
::SetCursor(mHArrow);
}
void CImageCodesDoc::OnProcessRui()
{
// TODO: Add your command handler code here
label=false;
double T[3][3]={0,-1,0,-1,5,-1,0,-1,0}; //锐化模板
EdgeDetect(T);
}
void CImageCodesDoc::OnProcessVer()
{
// TODO: Add your command handler code here
label=false;
double T[3][3]={0,0,0,-1,1,0,0,0,0};//垂直边缘模板
EdgeDetect(T);
}
void CImageCodesDoc::OnProcessErzhihua()
{
// TODO: Add your command handler code here
unsigned int r,c;
label=false;
erflag=TRUE;//表示原始图已经进行过二值化
unsigned int TH;
if(Grayflag==false) Gray() ;
CSetThr thrdlg;
if(thrdlg.DoModal()!=IDOK)//弹出二值化对话框
return;
TH=thrdlg.m_thr;//得到用户设定的阈值
for(r=0;r<r0;r++)
for(c=0;c<c0;c++)
{
if(GrayValue[r][c]>TH) convo[r][c]=255;//二值化
else convo[r][c]=0;
}
ConvertTo24Bits(convo);
TransBack(convo);
Display();
ConvertTo8Bits(convo);
convoflag=true;
}
void CImageCodesDoc::OnProcessRobert()
{
// TODO: Add your command handler code here
label=false;//是在进行原始图处理
if(Grayflag==false) Gray();
unsigned int GrayColorx,GrayColory,GrayColor;
unsigned int i,j,r,c;
::SetCursor(mHWait);
for(c=0;c<c0;c++)
{
convo[0][c]=255;
convo[r0-1][c]=255;
}
for(r=1;r<r0-1;r++)
{
convo[r][0]=255;
convo[r][c0-1]=255;
}
for(i=1;i<r0-1;i++)
for(j=1;j<c0-1;j++)
{
GrayColorx=GrayValue[i][j]-GrayValue[i-1][j-1];//robert算法
GrayColory=GrayValue[i-1][j]-GrayValue[i][j-1];
GrayColor=abs(GrayColorx)+abs(GrayColory);
if(GrayColor>255) GrayColor=255;
convo[i][j]=GrayColor;
}
ConvertTo24Bits(convo);//显示convo
TransBack(convo);
Display();
ConvertTo8Bits(convo);
convoflag=TRUE;
::SetCursor(mHArrow);
}
void CImageCodesDoc::OnUpdateProcessGray(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(trans!=NULL);//尚未打开图像时,相应的处理菜单要灰化
}
void CImageCodesDoc::OnUpdateProcessErzhihua(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -