1. 程式人生 > >第六節--基於Sobel的邊緣檢測C++程式的實現

第六節--基於Sobel的邊緣檢測C++程式的實現

 /**********************************************************************************************************
*函式原型:BOOL CImgProcess::EdgeSobel(CImgProcess* pTo,BYTE bTher,BYTE bEdegType, BOOL bThinning,BOOL bGOnly)
*函式功能:基於Sobel的邊緣檢測
*函式引數:1--CImgProcess* pTo----指向輸出影象的指標
*        2--BYTE bTher------人為指定的閥值,預設為0,即自動確定的閥值
*        3--BYTE bEdgeType--_EdgeAll-所有邊緣,EdgeH-水平邊緣,EdgeV-垂直邊緣,EdgeCW-45度邊緣 EdgeCCW-135度
*        4--BOOL bThinning---決定是否進行邊緣細化,預設為true,即執行邊緣細化
*        5--BOOL bGOnly------決定是否僅輸出梯度影象,預設為false,即輸出閥值化後的二值影象,當此引數為true時,
*                            bThre引數和bThinning引數將被忽略
*函式返回值:
*        布林型別,true為成功,false為失敗
***********************************************************************************************************/
BOOL CImgProcess::EdgeSobel(CImgProcess* pTo,BYTE bTher,BYTE bEdegType, BOOL bThinning,BOOL bGOnly)
{
 if(m_pBMIH->biBitCount!=8)
  return false;
 //[1]定義模板資料
 //[2]水平邊緣檢測
 const float cfSobelH[9]={
 -1,-1,-1,
 0,0,0,
 1,1,1
 };
 //[3]垂直邊緣檢測
 const float cfSobelV[9]={
 -1,0,1,
 -1,0,1,
 -1,0,1
 };
 //[4]45度邊緣檢測
 const float cfSobelCW[9]={
 -1,-1,0,
 -1,0,1,
  0,1,1
 };
 //[5]135度邊緣檢測
 const float cfSobelCCW[9]={
  0,1,1,
 -1,0,1
 -1,-1,0
 };
 //[6]臨時CImgProcess變數
 CImgProcess imgTemp=*this;
 CImgProcess imgMid=*this;
 //[7]根據選擇的邊緣型別應用模板
 switch(bEdegType)
 {
 case 0://所有邊緣
  Template(&imgTemp,3,3,1,1,(float*)cfSobelH,1);
  Template(&imgMid,3,3,1,1,(float*)cfSobelV,1);
  imgTemp=imgTemp+imgMid;
  Template(&imgMid,3,3,1,1,(float*)cfSobelCW,1);
  imgTemp=imgTemp+imgMid;
  Template(&imgMid,3,3,1,1,(float*)cfSobelCCW,1);
  imgTemp=imgTemp+imgMid;
  break;
 case 1://水平邊緣
  Template(&imgTemp,3,3,1,1,(float*)cfSobelH,1);
  break;
 case 2://垂直邊緣
  Template(&imgTemp,3,3,1,1,(float*)cfSobelV,1);
  break;
 case 3://45度邊緣
  Template(&imgTemp,3,3,1,1,(float*)cfSobelCW,1);
  break;
 case 4://135度邊緣
  Template(&imgTemp,3,3,1,1,(float*)cfSobelCCW,1);
  break;
 default://引數錯誤
  return false;
 }//switch
 if(bGOnly)
 {
  *pTo=imgTemp;//僅輸出梯度
 }
 else
 {
  //[8]根據閥值進行閥值化
  if(bThre)
  {
   imgTemp.Threshold(pTo,bTher);
  }
  else
  {//自動閥值化
   imgTemp.AutoThreshold(pTo);
  }
  if(bThinning)
  {
   pTo->LinTran(&imgTemp,-1,255);//第一次反色,為邊緣細化做準備
   imgTemp.Thinning();//邊緣細化
   imgTemp.LinTran(pTo,-1,255);
  }
 }
 return true;
}