1,c语言实现中值滤波以及算法实现描述
我们在一个矩阵中去除边缘,在剩余数中求取所有像素点的均值来取代中间的值,我们来举例说明:
1 | 2 | 3 | 3 | 1 |
3 |
10 | 23 | 54 | 3 |
2 | 23 | 45 | 14 | 2 |
1 | 21 | 32 | 28 | 1 |
3 | 4 | 4 | 2 | 3 |
1 | 2 | 3 | 3 | 1 |
3 | 27.8 | 27.8 | 27.8 | 3 |
2 | 27.8 | 27.8 | 27.8 | 2 |
1 | 27.8 | 27.8 | 27.8 | 1 |
3 | 4 | 4 | 2 | 3 |
图像的椒盐化补充:
椒盐噪声是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声是指两种噪声,一种是盐噪声(salt noise)盐=白色(255),另一种是胡椒噪声(pepper noise),椒=黑色(0)。
c语言代码实现:
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include
using namespace cv;
using namespace std;
//均值滤波
void AverFiltering(const Mat &src,Mat &dst) {
if (!src.data) return;
//at访问像素点
for (int i = 1; i= 0) && (j - 1) >= 0 && (i + 1)(i, j)[0] = (src.at(i, j)[0] + src.at(i - 1, j - 1)[0] + src.at(i - 1, j)[0] + src.at(i, j - 1)[0] +
src.at(i - 1, j + 1)[0] + src.at(i + 1, j - 1)[0] + src.at(i + 1, j + 1)[0] + src.at(i, j + 1)[0] +
src.at(i + 1, j)[0]) / 9;
dst.at(i, j)[1] = (src.at(i, j)[1] + src.at(i - 1, j - 1)[1] + src.at(i - 1, j)[1] + src.at(i, j - 1)[1] +
src.at(i - 1, j + 1)[1] + src.at(i + 1, j - 1)[1] + src.at(i + 1, j + 1)[1] + src.at(i, j + 1)[1] +
src.at(i + 1, j)[1]) / 9;
dst.at(i, j)[2] = (src.at(i, j)[2] + src.at(i - 1, j - 1)[2] + src.at(i - 1, j)[2] + src.at(i, j - 1)[2] +
src.at(i - 1, j + 1)[2] + src.at(i + 1, j - 1)[2] + src.at(i + 1, j + 1)[2] + src.at(i, j + 1)[2] +
src.at(i + 1, j)[2]) / 9;
}
else {//边缘赋值
dst.at(i, j)[0] = src.at(i, j)[0];
dst.at(i, j)[1] = src.at(i, j)[1];
dst.at(i, j)[2] = src.at(i, j)[2];
}
}
}
//图像椒盐化
void salt(Mat &image, int num) {
if (!image.data) return;//防止传入空图
int i, j;
srand(time(NULL));
for (int x = 0; x < num; ++x) {
i = rand() % image.rows;
j = rand() % image.cols;
image.at(i, j)[0] = 255;
image.at(i, j)[1] = 255;
image.at(i, j)[2] = 255;
}
}
void main()
{
Mat image = imread("路飞.jpg");
Mat Salt_Image;
image.copyTo(Salt_Image);
salt(Salt_Image, 3000);
Mat image1(image.size(), image.type());
Mat image2;
AverFiltering(Salt_Image, image1);
imshow("原图", image);
imshow("自定义均值滤波", image1);
waitKey();
}
运行结果如下: g++ 2_opencv.cpp `pkg-config opencv --cflags` `pkg-config opencv --libs`
opencv实现均值滤波:
import cv2
import numpy as np
img = cv2.imread('image11.jpg',1)
cv2.imshow('src',img)
dst = cv2.GaussianBlur(img,(5,5),1.5)
cv2.imshow('dst',dst)
cv2.waitKey(0)
运行结果如下:
2,c语言以及opencv实现中值滤波:
1 | 2 | 3 | 3 | 1 |
3 |
10 | 23 | 54 | 3 |
2 | 23 | 45 | 14 | 2 |
1 | 21 | 32 | 28 | 1 |
3 | 4 | 4 | 2 | 3 |
1 | 2 | 3 | 3 | 1 |
3 |
10 | 23 | 54 | 3 |
2 | 23 | 23 | 14 | 2 |
1 | 21 | 32 | 28 | 1 |
3 | 4 | 4 | 2 | 3 |
对中间的9个数据10,23,54,23,45,14,21,32,28进行排序,所以排序后的数据如下:
10,14,21,23,23,28,32,45,45 所以我们看到中值是23,我们只需要替换掉中间
值,将45替换为23即可。
c语言代码实现中值滤波:
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include
using namespace cv;
using namespace std;
typedef unsigned char uchar;
void swap(uchar* p1,uchar* p2)
{
uchar* temp = p1;
p1 = p2;
p2 = temp ;
}
//求九个数的中值
uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,
uchar n6, uchar n7, uchar n8, uchar n9) {
uchar arr[9];
arr[0] = n1;
arr[1] = n2;
arr[2] = n3;
arr[3] = n4;
arr[4] = n5;
arr[5] = n6;
arr[6] = n7;
arr[7] = n8;
arr[8] = n9;
for (int gap = 9 / 2; gap > 0; gap /= 2)//希尔排序
for (int i = gap; i < 9; ++i)
for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
swap(&arr[j], &arr[j + gap]);
return arr[4];//返回中值
}
//图像椒盐化
void salt(Mat &image, int num) {
if (!image.data) return;//防止传入空图
int i, j;
srand(time(NULL));
for (int x = 0; x < num; ++x) {
i = rand() % image.rows;
j = rand() % image.cols;
image.at(i, j)[0] = 255;
image.at(i, j)[1] = 255;
image.at(i, j)[2] = 255;
}
}
//中值滤波函数
void MedianFlitering(const Mat &src, Mat &dst) {
if (!src.data)return;
Mat _dst(src.size(), src.type());
for(int i=0;i 0 && (i + 1) < src.rows && (j - 1) > 0 && (j + 1) < src.cols) {
_dst.at(i, j)[0] = Median(src.at(i, j)[0], src.at(i + 1, j + 1)[0],
src.at(i + 1, j)[0], src.at(i, j + 1)[0], src.at(i + 1, j - 1)[0],
src.at(i - 1, j + 1)[0], src.at(i - 1, j)[0], src.at(i, j - 1)[0],
src.at(i - 1, j - 1)[0]);
_dst.at(i, j)[1] = Median(src.at(i, j)[1], src.at(i + 1, j + 1)[1],
src.at(i + 1, j)[1], src.at(i, j + 1)[1], src.at(i + 1, j - 1)[1],
src.at(i - 1, j + 1)[1], src.at(i - 1, j)[1], src.at(i, j - 1)[1],
src.at(i - 1, j - 1)[1]);
_dst.at(i, j)[2] = Median(src.at(i, j)[2], src.at(i + 1, j + 1)[2],
src.at(i + 1, j)[2], src.at(i, j + 1)[2], src.at(i + 1, j - 1)[2],
src.at(i - 1, j + 1)[2], src.at(i - 1, j)[2], src.at(i, j - 1)[2],
src.at(i - 1, j - 1)[2]);
}
else
_dst.at(i, j) = src.at(i, j);
}
_dst.copyTo(dst);//拷贝
}
int main() {
Mat image = imread("1.JPG");
Mat Salt_Image;
image.copyTo(Salt_Image);
salt(Salt_Image, 3000);
Mat image3, image4;
MedianFlitering(Salt_Image, image3);
medianBlur(Salt_Image, image4, 3);
imshow("自定义中值滤波处理后", image3);
imshow("openCV自带的中值滤波", image4);
waitKey();
}
代码实现效果如下: