bool sobelOptaEdge(const cv::Mat& srcImage,
cv::Mat& resultImage, int flag)
{
CV_Assert(srcImage.channels() == 1);
// 初始化sobel水平核因子
cv::Mat sobelX = (cv::Mat_(3, 3) << 1, 0, -1,
2, 0, -2,
1, 0, -1);
// 初始化sebel垂直核因子
cv::Mat sobelY = (cv::Mat_(3, 3) << 1, 2, 1,
0, 0, 0,
-1, -2, -1);
// 计算水平与垂直卷积
cv::Mat edgeX, edgeY;
filter2D(srcImage, edgeX, CV_32F, sobelX);
filter2D(srcImage, edgeY, CV_32F, sobelY);
// 根据传入参数确定计算水平或垂直边缘
int paraX = 0;
int paraY = 0;
switch(flag)
{
case 0 : paraX = 1;
paraY = 0;
break;
case 1: paraX = 0;
paraY = 1;
break;
case 2: paraX = 1;
paraY = 1;
break;
default: break;
}
edgeX = abs(edgeX);
edgeY = abs(edgeY);
cv::Mat graMagMat = paraX * edgeX.mul(edgeX) +
paraY * edgeY.mul(edgeY);
// 计算阈值
int scaleVal = 4;
double thresh = scaleVal * cv::mean(graMagMat).val[0];
resultImage = cv::Mat::zeros(srcImage.size(),
srcImage.type());
for(int i = 1; i < srcImage.rows - 1; i++)
{
float* pDataEdgeX = edgeX.ptr(i);
float* pDataEdgeY = edgeY.ptr(i);
float* pDataGraMag = graMagMat.ptr(i);
// 阈值化和极大值抑制
for(int j = 1; j < srcImage.cols-1; j++)
{
if( pDataGraMag[j] > thresh && (
(pDataEdgeX[j] > paraX * pDataEdgeY[j] &&
pDataGraMag[j] >
pDataGraMag[j-1] && pDataGraMag[j] >
pDataGraMag[j+1]) ||
(pDataEdgeY[j] > paraY * pDataEdgeX[j] &&
pDataGraMag[j] >
pDataGraMag[j-1] && pDataGraMag[j] >
pDataGraMag[j+1]) ) )
resultImage.at(i, j) = 255;
}
}
return true;
}
转载:http://blog.csdn.net/zhuwei1988