⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagecodesdoc.cpp

📁 VC写的harris角点检测程序。又名plessey
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}


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 + -