影象非極大值抑制 Sobel 邊緣實現
阿新 • • 發佈:2019-01-01
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