sobel 边缘检测 c++实现

发布时间:2022-08-18 18:24

存在一个问题,sobel边缘检测 就是用sobel卷积核 卷积图像,但是因为卷积核中的参数有些是负数,若是卷积后的值是负数该怎么解释,望大佬看见提点一下我。

#include
#include
#include

using namespace cv;
using namespace std;



Mat Padding(Mat& image,int padNum = 1) {
	Mat dst = Mat::zeros(image.size[0]+2*padNum, image.size[1] + 2*padNum, CV_8UC1);
	
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			dst.at(i + 1, j + 1) = image.at(i, j);
		}
	}

	return  dst;

}

Mat  convolution(Mat &image, Mat &kernal) {

	Mat dst = Mat ::zeros(image.size(),image.type());
	// padding 填充
	Mat test = Padding(image);// 6*6 填充一层 变 8*8
	
	double pixSum = 0;
	
	for (int i = 0; i < image.rows; i++) {
		for (int j = 0; j < image.cols; j++)
		{
			
		
			//这个像素就在卷积核的中心处
			for (int k = 0; k < kernal.rows; k++) {
				for (int l = 0; l < kernal.cols; l++) {
					pixSum += kernal.at(k, l) * double(test.at(k + i, l + j));
					
				}
			}
			//if (pixSum < 0) { pixSum = 0; }
			dst.at(i, j) = abs(pixSum);
			pixSum = 0;
		}
	}

	return dst;

}


Mat gradientImg(Mat image) {
	Mat test = Mat:: ones(Size(6, 6), CV_8UC1);
	Mat kernal_x = (Mat_(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);

	Mat dst = convolution(test, kernal_x);;

	dst = convolution(image, kernal_x);
	return dst;
	
}




int main(int argc, char* argv[])
{
	//load pics

	string imgPath = "E:\\研究生\\数字图像处理\\c++\\字符识别\\Project1\\lena.png";
	Mat srcImg = imread(imgPath,0);//RGB,JPG,PNG,TIFF格式,灰度格式读入

	if (srcImg.empty()) {
		cout << "can't load pic" << endl;
		exit(-1);
	}
	//show pics
	//imshow("src",srcImg);

	Mat gradient= gradientImg(srcImg);
	imshow("gradient x ", gradient);

	//与opencv 对比
	Mat gx;
	Sobel(srcImg, gx, CV_16S, 1, 0);
	convertScaleAbs(gx, gx);
	imshow("opencv x ", gx);

	waitKey(0);//wait function
	destroyAllWindows();


	return 0;
}

对x 方向的sobel 滤波操作效果有一些差别

 感觉就是上面的卷积的时候,出现负数时直接求绝对值的操作有关。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号