问题1:什么是中值滤波?
使用像素点邻域附近的像素的中值代替该点的像素值。通俗点来说,在这个像素的左边找五个像素点,右边找五个像素点,将这些像素进行排序,排序过后产生一个中值,啊哈哈,就是中间大小的值,来代替该像素的值。
问题2:中值滤波有什么利弊?
中值滤波可以有效的去除斑点和椒盐噪声。但是效率低,其运算时间 为均值滤波的五倍以上。
问题3:相关API的了解
void medianBlur( InputArray src, OutputArray dst, int ksize );
参数 InputArray src: 输入得图像 通道可以为1 or 3 or 4通道的图像。
参数 OutputArray dst: 经过中值滤波的输出图像。
参数 int ksize: 模板尺寸 此参数必须为大于1的奇数,参数为 3 or 5时图像深度只能为CV_8U、CV_16U、CV_32F中的一个,如而对于较大孔径尺寸的图片,图像深度只能是CV_8U。
问题4:上面提到了 CV_8U、CV_16U这些内容,他们到底是啥呢?
在opencv中Mat这个东西存在各种对象,其中Mat.type()就是其中一个 那么这个东西有什么用呢 ?他是用来测试这个图像的类型参数的,举个例子来说 :
image = imread("Test.jpg",IMREAD_UNCHANGED);
cout << image.type() << endl;
此时控制台输出16 这是啥意思呢 结合下面的一个图片理解即可 ,Mat.type()函数可以返回该Mat的类型。类型表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)
那么16就带代表这个图像是一个八位无符号字符型数据 三通道。
中值滤波代码实现: 起到了滤波的效果 但是还不如OpenCv中自带的滤波器效果好。也没找出来原因 嘿嘿
#include
#include
using namespace cv;
using namespace std;
void salt(Mat &image, Mat & result, int k)
{
image.copyTo(result);
for (; k > 0; k--)
{
int i = rand() % result.rows;
int j = rand() % result.cols;
if (result.channels() == 1)
{
result.at(i, j) = 255;
}
if (result.channels() == 3)
{
result.at(i, j)[0] = 255;
result.at(i, j)[1] = 255;
result.at(i, j)[2] = 255;
}
}
}
uchar sort(uchar n1, uchar n2, uchar n3, uchar n4,uchar n5, uchar n6, uchar n7, uchar n8, uchar n9)
{
uchar *ptr = new uchar [9];
uchar temp;
*ptr = n1;
*(ptr + 1) = n2;
*(ptr + 2) = n3;
*(ptr + 3) = n4;
*(ptr + 4) = n5;
*(ptr + 5) = n6;
*(ptr + 6) = n7;
*(ptr + 7) = n8;
*(ptr + 8) = n9;
for(int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (ptr[i] > ptr[j])
{
temp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = temp;
}
}
}
temp = ptr[4];
delete[] ptr;
return temp;
}
void middleFilter(Mat& image, Mat & result)
{
image.copyTo(result);
for (int i = 0; i < result.rows; i++)
{
for (int j = 0; j < result.cols; j++)
{
if ((i > 0) && (i < result.rows - 1) && (j > 0) && (j < result.cols-1))
{
result.at(i, j)[0] = sort(result.at(i - 1, j - 1)[0],result.at(i - 1, j)[0] ,result.at(i - 1, j + 1)[0]
, result.at(i, j - 1)[0] , result.at(i, j)[0] , result.at(i, j + 1)[0]
,result.at(i + 1, j - 1)[0] , result.at(i + 1, j)[0] ,result.at(i + 1, j + 1)[0]);
result.at(i, j)[1] = sort(result.at(i - 1, j - 1)[1], result.at(i - 1, j)[1], result.at(i - 1, j + 1)[1]
, result.at(i, j - 1)[1], result.at(i, j)[1], result.at(i, j + 1)[1]
, result.at(i + 1, j - 1)[1], result.at(i + 1, j)[1], result.at(i + 1, j + 1)[1]);
result.at(i, j)[2] = sort(result.at(i - 1, j - 1)[2], result.at(i - 1, j)[2], result.at(i - 1, j + 1)[2]
, result.at(i, j - 1)[2], result.at(i, j)[2], result.at(i, j + 1)[2]
, result.at(i + 1, j - 1)[2], result.at(i + 1, j)[2], result.at(i + 1, j + 1)[2]);
}
}
}
}
int main()
{
Mat image,result1, result2,result3;
cout << int(sort(1, 4, 8, 0, 2, 3, 5, 6, 7)) << endl;
image = imread("Test.jpg",IMREAD_UNCHANGED);
salt(image, result1, 3000);
middleFilter(result1, result2);
medianBlur(result1,result3,3);
imshow("椒盐噪声", result1);
imshow("中值滤波", result2);
imshow("medianBlur", result3);
waitKey(0);
return 0;
}