OpenCV學習筆記(十三)邊緣檢測
阿新 • • 發佈:2019-02-05
效果圖:#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; void marrEdge(const Mat src, Mat& result, int kerValue, double delta) { //計算LoG運算元 Mat kernel; //半徑 int kerLen = kerValue / 2; kernel = Mat_<double>(kerValue, kerValue); //滑窗 for (int i = -kerLen; i <= kerLen; i++) { for (int j = -kerLen; j <= kerLen; j++) { //生成核因子 kernel.at<double>(i + kerLen, j + kerLen) = exp(-((pow(j, 2) + pow(i, 2)) / (pow(delta, 2) * 2))) *((pow(j, 2) + pow(i, 2) - 2 * pow(delta, 2)) / (2 * pow(delta, 4))); } } //設定輸入引數 int kerOffset = kerValue / 2; Mat laplacian = (Mat_<double>(src.rows - kerOffset * 2, src.cols - kerOffset * 2)); result = Mat::zeros(src.rows - kerOffset * 2, src.cols - kerOffset * 2, src.type()); double sumLaplacian; //遍歷計算卷積影象的拉普拉斯運算元 for (int i = kerOffset; i < src.rows - kerOffset; ++i) { for (int j = kerOffset; j < src.cols - kerOffset; ++j) { sumLaplacian = 0; for (int k = -kerOffset; k <= kerOffset; ++k) { for (int m = -kerOffset; m <= kerOffset; ++m) { //計算影象卷積 sumLaplacian += src.at<uchar>(i + k, j + m)*kernel.at<double>(kerOffset + k, kerOffset + m); } } //生成拉普拉斯結果 laplacian.at<double>(i - kerOffset, j - kerOffset) = sumLaplacian; } } for (int y = 1; y < result.rows - 1; ++y) { for (int x = 1; x < result.cols-1; ++x) { result.at<uchar>(y, x) = 0; //領域判定 if (laplacian.at<double>(y - 1, x)*laplacian.at<double>(y + 1, x) < 0) { result.at<uchar>(y, x) = 255; } if (laplacian.at<double>(y, x - 1)*laplacian.at<double>(y, x + 1) < 0) { result.at<uchar>(y, x) = 255; } if (laplacian.at<double>(y + 1, x - 1)*laplacian.at<double>(y - 1, x + 1) < 0) { result.at<uchar>(y, x) = 255; } if (laplacian.at<double>(y - 1, x - 1)*laplacian.at<double>(y + 1, x + 1) < 0) { result.at<uchar>(y, x) = 255; } } } } int main() { Mat srcImage = imread("D:\\3.jpg"); if (!srcImage.data) return -1; Mat edge,srcGray; cvtColor(srcImage, srcGray, CV_RGB2GRAY); marrEdge(srcGray, edge, 9, 1.6); imshow("srcImage", srcImage); imshow("edge", edge); waitKey(0); return 0; }