1. 程式人生 > >影象非極大值抑制 Sobel 邊緣實現

影象非極大值抑制 Sobel 邊緣實現

bool SobelVerEdge(cv::Mat srcImage, cv::Mat& resultImage)
{
    CV_Assert(srcImage.channels() == 1);
	srcImage.convertTo(srcImage, CV_32FC1);
	// 水平方向的 Sobel 運算元
	cv::Mat sobelx = (cv::Mat_<float>(3,3) << -0.125, 0, 0.125,
		-0.25, 0, 0.25,
		-0.125, 0, 0.125); 
	cv::Mat ConResMat;
    // 卷積運算
	cv::filter2D(srcImage, ConResMat, srcImage.type(), sobelx);
	// 計算梯度的幅度
	cv::Mat graMagMat;
	cv::multiply(ConResMat, ConResMat, graMagMat);
	// 根據梯度幅度及引數設定閾值
    int scaleVal = 4;
	double thresh = scaleVal * cv::mean(graMagMat).val[0];
	cv::Mat resultTempMat = cv::Mat::zeros(
        graMagMat.size(), graMagMat.type());
	float* pDataMag = (float*)graMagMat.data;
	float* pDataRes = (float*)resultTempMat.data;
    const int nRows = ConResMat.rows;
    const int nCols = ConResMat.cols;
	for (int i = 1; i != nRows - 1; ++i) {
		for (int j = 1; j != nCols - 1; ++j) {
            // 計算該點梯度與水平或垂直梯度值大小比較結果
			bool b1 = (pDataMag[i * nCols + j] > pDataMag[i * 
              nCols + j - 1]);
			bool b2 = (pDataMag[i * nCols + j] > pDataMag[i * 
              nCols + j + 1]);
			bool b3 = (pDataMag[i * nCols + j] > pDataMag[(i - 1)
              * nCols + j]);
			bool b4 = (pDataMag[i * nCols + j] > pDataMag[(i + 1) 
             * nCols + j]);
            // 判斷鄰域梯度是否滿足大於水平或垂直梯度
            // 並根據自適應閾值引數進行二值化
			pDataRes[i * nCols + j] = 255 * ((pDataMag[i * 
              nCols + j] > thresh) &&
				((b1 && b2) || (b3 && b4)));   
		}
	}
	resultTempMat.convertTo(resultTempMat, CV_8UC1);
    resultImage = resultTempMat.clone();
	return true;
}


轉載:http://blog.csdn.net/zhuwei1988