空间滤波器

目录

一,空间滤波器

二,平滑滤波器

1,用途

2,线性滤波器

(1)均值滤波器

(2)高斯滤波器

3,非线性滤波器

(1)排序统计滤波器

(2)其他

三,锐化滤波器

1,用途

2,原理

3,梯度算子

(1)梯度的模

(2)简化近似梯度算子

(3)Roberts交叉梯度算子

(4)Prewitt梯度算子

(5)Sobel梯度算子

(6)梯度总结

4,拉普拉斯算子

5,非锐化掩蔽、高提升滤波

(1)非锐化掩蔽

(2)高提升滤波

四,模糊集合

1,使用模糊集进行灰度变换

2,使用模糊集进行边缘检测

五,可分离滤波器

六,双边滤波器

一,空间滤波器

使用空间模板进行的图像处理,被称为空间滤波。模板本身被称为空间滤波器。

二,平滑滤波器

1,用途

模糊处理,去除图像中一些不重要的细节,减小噪声

2,线性滤波器

就是做加权平均

《空间滤波器》

(1)均值滤波器

 其中,一种特例就是每个元素都相等,这种叫均值滤波器,也叫归一化滤波器,如下:

《空间滤波器》

imageBlur = cv2.blur(image2,(5,7))

第二个参数是核大小

《空间滤波器》

C++版:

int maxScaleUp = 100;
int scaleFactor = 1;

string windowName = "Resize Image";
string trackbarValue = "Scale";
Mat image;

void scaleImage(int, void*)
{

	Mat scaledImage;
	if (scaleFactor == 0)scaleFactor = 1;
	// Resize the image
	blur(image, scaledImage, Size(scaleFactor, scaleFactor));
	imshow(windowName, scaledImage);
	waitKey(0);
	//destroyAllWindows();
}

int main()
{
	image = imread("D:/2.png");
	resize(image, image, Size(400, 400));
	namedWindow(windowName, WINDOW_AUTOSIZE);
	createTrackbar(trackbarValue, windowName, &scaleFactor, maxScaleUp, scaleImage);
	scaleImage(25, 0);
	return 0;
}

《空间滤波器》

(2)高斯滤波器

以高斯卷积作为滤波器

卷积(Convolution)_nameofcsdn的博客-CSDN博客_卷积

imageBlur = cv2.GaussianBlur(image2,(5,5),1)

第二个参数是核大小,第三个参数是标准差

3,非线性滤波器

(1)排序统计滤波器

基于滤波器所在图像区域中像素的排序,由排序结果决定的值代替中心像素的值。

如中值滤波器、最大值滤波器、最小值滤波器,作用分别是去除噪声、寻找最亮点、寻找最暗点。

中值滤波:

int main()
{
	Mat image = imread("D:/img6.png");
	Mat image2;
	medianBlur(image, image2, 5);
	imshow("image", image);
	imshow("image2", image2);
	waitKey(0);
	return 0;
}

(2)其他

三,锐化滤波器

1,用途

突出图像中的细节,增强被模糊了的细节

印刷中的细微层次强调。弥补扫描对图像的钝化

超声探测成像,分辨率低,边缘模糊,通过锐化来改善

图像识别中,分割前的边缘提取

锐化处理恢复过度钝化、曝光不足的图像

尖端武器的目标识别、定位

2,原理

根据微积分中的偏微分,达到锐化效果。

锐化滤波器分为一阶微分滤波器(梯度算子)、二阶微分滤波器(拉普拉斯算子)。

3,梯度算子

(1)梯度的模

《空间滤波器》

各种梯度算子,都是这个公式的离散近似。

所有的梯度算子,梯度计算都是由两个模板组成,第一个求得梯度的第一项,第二个求得梯度的第二项,然后求和,得到梯度。

(2)简化近似梯度算子

《空间滤波器》

平方和再开方的计算过于复杂,于是又有了一些简化的近似计算非方案。

《空间滤波器》

(3)Roberts交叉梯度算子

《空间滤波器》 《空间滤波器》

相当于旋转了45度求梯度。

《空间滤波器》

《空间滤波器》

(4)Prewitt梯度算子

《空间滤波器》

《空间滤波器》

(5)Sobel梯度算子

《空间滤波器》

《空间滤波器》

int main()
{
	Mat image = imread("D:/2.png");
	Mat image2;
	Sobel(image, image2, image.depth(), 1, 1);
	imshow("image", image);
	imshow("image2", image2);
	waitKey(0);
	return 0;
}

(6)梯度总结

不同梯度算子的运算结果,换算到梯度的常数是不一样的。

Roberts交叉梯度算子的方向不太一样(坐标系旋转了45度),其他几个算子都是正常方向,x和y方向分别计算。

4,拉普拉斯算子

《空间滤波器》

《空间滤波器》

对应的核:

《空间滤波器》

int main()
{
	Mat image = imread("D:/2.png");
	Mat image2;
	Laplacian(image, image2, image.depth(), 1);
	imshow("image", image);
	imshow("image2", image2);
	waitKey(0);
	return 0;
}

《空间滤波器》

图像中的边缘往往是斜坡而不是悬崖,二阶微分关注的是斜坡的端点,一阶微分关注的是整个斜坡,从这个角度看,二阶微分效果更好。

4.25  从这开始

写了个这种斜坡边缘的图,对比sobel和拉普拉斯的效果:

int main()
{
	Mat img = Mat(400, 400, CV_8UC1);
	for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++) {
		int d = min(abs(i - 200), abs(j - 200));
		if (d <= 100)img.at<uchar>(i, j) = 240;
		else if (d >= 108)img.at<uchar>(i, j) = 80;
		else img.at<uchar>(i, j) = 240 - 10 * (d - 100);
	}
	Mat img2;
	Sobel(img, img2, img.depth(), 1, 1);
	Mat img3;
	Laplacian(img, img3, img.depth(), 1);
	cv::imshow("img", img);
	cv::imshow("img2*8", img2 * 8);
	cv::imshow("img3*8", img3 * 8);
	cv::waitKey(0);
	return 0;
}

ps:2个结果都和想象的不完全一样,这可能需要深究源代码才能搞清楚。

《空间滤波器》

《空间滤波器》

 《空间滤波器》

5,非锐化掩蔽、高提升滤波

(1)非锐化掩蔽

《空间滤波器》

int main()
{
	Mat img = Mat(400, 400, CV_8UC1);
	for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++) {
		int d = min(abs(i - 200), abs(j - 200));
		if (d <= 100)img.at<uchar>(i, j) = 240;
		else if (d >= 108)img.at<uchar>(i, j) = 80;
		else img.at<uchar>(i, j) = 240 - 10 * (d - 100);
	}
	Mat img3;
	Laplacian(img, img3, img.depth(), 1);
	Mat img4;
	blur(img, img4, Size(5, 5));
	cv::imshow("img", img);
	cv::imshow("img-img3", img - img3);
	cv::imshow("img + (img - img4 )", img + (img - img4));
	cv::waitKey(0);
	return 0;
}

(img同上)

《空间滤波器》

《空间滤波器》

边界非常突出

《空间滤波器》

 比原图的边界清楚一点,不过并不明显。

(2)高提升滤波

高提升滤波就是把模板的k倍加到原图上,k>1

int main()
{
	Mat img = Mat(400, 400, CV_8UC1);
	for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++) {
		int d = min(abs(i - 200), abs(j - 200));
		if (d <= 100)img.at<uchar>(i, j) = 240;
		else if (d >= 108)img.at<uchar>(i, j) = 80;
		else img.at<uchar>(i, j) = 240 - 10 * (d - 100);
	}
	Mat img3;
	Laplacian(img, img3, img.depth(), 1);
	Mat img4;
	blur(img, img4, Size(5, 5));
	cv::imshow("img", img);
	cv::imshow("img + (img - img4 )", img + (img - img4)*3);
	cv::waitKey(0);
	return 0;
}

《空间滤波器》

四,模糊集合

模糊集合论

使用模糊处理,可以在一定程度上消除输出结果对于阈值精确性的依赖

1,使用模糊集进行灰度变换

我们把直方图均衡表示为:

《空间滤波器》

按照模糊集合论,每个像素点以不同的程度同时分别属于暗集、灰集、亮集。

我们根据常见去模糊公式(重心法)的简化公式来计算变换结果:

《空间滤波器》

《空间滤波器》

即根据像素属于暗集、灰集、亮集的程度进行加权平均,vd,vg,vb取常数。

const int d = 40;
double isDark(int pix)
{
	if (pix < 128 - d)return 1;
	if (pix > 128)return 0;
	return (128.0 - pix) / d;
}
double isBright(int pix)
{
	if (pix > 128 + d)return 1;
	if (pix < 128)return 0;
	return (pix - 128.0) / d;
}
double isGray(int pix)
{
	if (pix < 128 - d)return 0;
	if (pix > 128 + d)return 0;
	return 1 - abs(pix - 128.0) / d;
}

int main()
{
	Mat img = imread("D:/img9.png", 0);
	Mat img2;
	equalizeHist(img, img2);
	Mat img3(img.rows, img.cols, img.type());
	for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++) {
		int p = int(img.at<uchar>(i, j));
		int p2 = (isDark(p) * 20 + isBright(p) * 240 + isGray(p) * 128) / (isDark(p) + isBright(p) + isGray(p));
		img3.at<uchar>(i, j) = uchar(p2);
	}
	cv::imshow("img", img);
	cv::imshow("img2", img2);
	cv::imshow("img3", img3);
	cv::waitKey(0);
	return 0;
}

《空间滤波器》  《空间滤波器》 《空间滤波器》

2,使用模糊集进行边缘检测

《空间滤波器》

double isSame(int dp)
{
	dp = abs(dp);
	if (dp < 30)return 1 - dp / 30.0;
	return 0;
}
int deblur(double isSame)
{
	if (isSame < 0.9)return (1 - isSame / 0.9) * 255;
	return 0;
}

int main()
{
	Mat img = imread("D:/img10.png", 0);
	Mat img2(img.rows, img.cols, img.type());
	img2 = 0;
	for (int i = 1; i < img.rows - 1; i++)for (int j = 1; j < img.cols - 1; j++) { // 四邻居
		int p = img.at<uchar>(i, j);
		int up = img.at<uchar>(i - 1, j), down = img.at<uchar>(i + 1, j);
		int left = img.at<uchar>(i, j - 1), right = img.at<uchar>(i, j + 1);
		up -= p, down -= p, left -= p, right -= p; //计算四个方向的差分
		double sup = isSame(up), sdown = isSame(down);
		double sleft = isSame(left), sright = isSame(right);
		double smin1 = min(sup, sleft), smin2 = min(sup, sright), smin3 = min(sdown, sleft), smin4 = min(sdown, sright);
		double smax = max(max(smin1, smin2), max(smin3, smin4));
		img2.at<uchar>(i, j) = deblur(smax);
	}
	cv::imshow("img", img);
	cv::imshow("img2", img2);
	Canny(img, img, 200, 100, 3);
	cv::imshow("img3", img);
	cv::waitKey(0);
	return 0;
}

输入人的头部扫描图像:

《空间滤波器》  

输出2个结果:

《空间滤波器》 《空间滤波器》

 canny边缘检测(图三)的轮廓更清晰,没有噪点,模糊边缘检测的结果(图二)有很多噪点,但是保留了更多的边缘信息。

五,可分离滤波器

可分离滤波器:如果一个核可以表示成2个向量的乘积,那么采用分离式的计算就可以节省大量时间

(1)sobel

《空间滤波器》

《空间滤波器》

分离式:《空间滤波器》

这个例子可以节约大概一半时间。

(2)高斯

 《空间滤波器》

分离式:《空间滤波器》 

这个例子可以节约大概3/5时间

(3)opencv中相关实现

可分离滤波器

六,双边滤波器

  • 目前我们了解的滤波器都是为了 平滑 图像, 问题是有些时候这些滤波器不仅仅削弱了噪声, 连带着把边缘也给磨掉了。 为避免这样的情形 (至少在一定程度上 ), 我们可以使用双边滤波。
  • 类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。 这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。

Bilateral Filtering

opencv 接口:

void bilateralFilter( InputArray src, OutputArray dst, int d, 
double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );

    原文作者:csuzhucong
    原文地址: https://blog.csdn.net/nameofcsdn/article/details/118390671
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞