/**********************************************************************************************************
*函数原型: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;
}