第六節--基於Sobel的邊緣檢測C++程式的實現
阿新 • • 發佈:2019-01-08
/**********************************************************************************************************
*函式原型: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;
}
*函式原型: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;
}