1. 程式人生 > >OpenCV學習筆記(十三)邊緣檢測

OpenCV學習筆記(十三)邊緣檢測

#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;

}
效果圖: