c++ opencv数字图像处理:空间滤波基础,低通滤波之均值滤波(盒式滤波)器
文章目录前言一、可分离滤波器核二、盒式滤波器核三、低通高斯滤波器核四、统计排序(非线性)滤波器五、opencv函数总结1.引入库前言数字图像处理c++ opencv(VS2019 opencv4.53)持续更新一、可分离滤波器核二、盒式滤波器核三、低通高斯滤波器核四、统计排序(非线性)滤波器五、opencv函数总结1.引入库代码如下(示例):import numpy as np...
前言
数字图像处理c++ opencv(VS2019 opencv4.53)持续更新
一、空间滤波基础
1.线性空间滤波原理
线性空间滤波器在图像f和滤波器核w之间执行乘积之和运算。用邻域像素改变中心像素的灰度值大小。
2.相关与卷积
相关以上面的滤波运算方法对图像进行遍历处即使w每个像素能够访问图像f中每个像素。卷积运算时将滤波器核w旋转180°再处理。
3.可分离滤波器核
卷积相关都存在分配律,即:
当一个滤波器核w可以表示为两个向量的积时:
w
=
c
r
T
w=cr^T
w=crT
w就是一个可分离滤波器核。
比如盒式滤波器核(均值滤波):
可分离滤波器好处:
对于大小为MN的图像和大小为mn的滤波器核,进行滤波时要MNmn次乘法和加法运算。而分离为两个m和n的向量后,计算次数为MN(m+n)次,两种计算次数之比为:
C
=
M
N
m
n
M
N
(
m
+
n
)
=
m
n
m
+
n
C=\frac{MNmn}{MN(m+n)}=\frac{mn}{m+n}
C=MN(m+n)MNmn=m+nmn
大大减少计算次数。
二、平滑(低通)滤波
1.盒式滤波器核(均值滤波器)
一个3*3大小的盒式滤波器核如下:
使用盒式滤波器对图像进行滤波,代码如下(示例):
#include<iostream>
#include<opencv2/opencv.hpp>
#include"Salt.h"
using namespace cv;
using namespace std;
//定义盒式滤波函数
void myfilter(int filter_size, Mat& image_input, Mat& image_output);
int main()
{
Mat image, image_gray, image_output, image_output2; //定义输入图像,灰度图像,输出图像
image = imread("lena.png"); //读取图像;
if (image.empty())
{
cout << "读取错误" << endl;
return -1;
}
imshow("image", image);
cvtColor(image, image_gray, COLOR_BGR2GRAY);
Salt(image_gray, 1000); //添加噪声
imshow("image_gray", image_gray);
//自己编写的程序
int filter_size = 7; //滤波器大小
myfilter(filter_size, image_gray, image_output);
//opencv自带程序
blur(image_gray, image_output2, Size(7, 7));
imshow("image_output", image_output);
imshow("image_output2", image_output2);
waitKey(0); //暂停,保持图像显示,等待按键结束
return 0;
}
//实现盒式滤波
void myfilter(int filter_size, Mat& image_input, Mat& image_output)
{
image_output = image_input.clone();
int k = (filter_size-1) / 2;
for (int i = k; i < (image_input.rows - k); i++)
{
for (int j = k; j < (image_input.cols - k); j++)
{
int sum = 0;
for (int m = -k; m < k + 1; m++)
{
for (int n = -k; n < k + 1; n++)
{
sum = sum + image_input.at<uchar>(i + m, j + n) ;
}
}
image_output.at<uchar>(i, j) = round(sum / (filter_size * filter_size));
}
}
}
噪声程序.h文件
#pragma once
#include<iostream>
#include<opencv2/opencv.hpp>
#include <random>
using namespace cv;
using namespace std;
void Salt(Mat image, int n);
噪声程序.cpp文件
#include "Salt.h"
void Salt(Mat image, int n)
{
default_random_engine generater;
uniform_int_distribution<int>randomRow(0, image.rows - 1);
uniform_int_distribution<int>randomCol(0, image.cols - 1);
int i, j;
for (int k = 0; k < n; k++)
{
i = randomCol(generater);
j = randomRow(generater);
if (image.channels() == 1)
{
image.at<uchar>(j, i) = 255;
}
else if (image.channels() == 3)
{
image.at<Vec3b>(j, i)[0] = 255;
image.at<Vec3b>(j, i)[1] = 255;
image.at<Vec3b>(j, i)[2] = 255;
}
}
}
结果:
更多推荐
所有评论(0)