图像卷积下非极大值抑制 Sobel 的实现

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

你可能感兴趣的:(opencv3常用代码示例)