英文叫做blur, 也叫做smootiing, 中文中叫做模糊或者平滑。
用过photoshop的人都应该知道,滤镜里面就有模糊这个选项,我们现在看看它是怎么实现的。
模糊(平滑)是一种常用的图片处理方式,它的作用可以用来降低噪声,还有其他用途
看一下opencv 里面的公式
g(i,j)是目标坐标的像素值, f(i+k,j+l)是k,l这些地方的像素值, h(k,l)是 kernel, 我不知道怎么去准确翻译它的意义,它是过滤器的系数。
简单的按照我的思路去理解,就是一个权值,模糊的含义是将所有的像素按照一定的权值进行运算,得到一个比较均衡的结果。
void boxblur(Mat input ,Mat &out, int x, int y)
{
// accept only char type matrices
CV_Assert(input.depth() != sizeof(uchar));
out.create(input.size(),input.type());
int nChannels = input.channels();
int nRows = input.rows;
int nCols = input.cols;
int size = x * y;
float kernel = 1.0/size;
int i,j;
uchar* p;
uchar* q;
uchar R,G,B;
for( i = x; i < nRows - x; ++i)
{
q = out.ptr<uchar>(i);
for ( j = y; j < nCols - y; ++j)
{
float sumR = 0;
float sumG = 0;
float sumB = 0;
for (int k =0; k<x;k++)
{
p = input.ptr<uchar>(i-x+k);
for(int l = 0; l < y;l++)
{
sumB += input.at<uchar>(i - x + k,(j + l - y)*nChannels) * kernel;//p[(l + j -y)*nChannels ] * kernel;
sumG += input.at<uchar>(i - x + k,(j + l - y)*nChannels + 1) * kernel;//p[(l + j -y)*nChannels + 1] * kernel;
sumR += input.at<uchar>(i - x + k,(j + l - y)*nChannels + 2) * kernel;//p[(l + j -y)*nChannels + 2] * kernel;
}
}
q[j*nChannels] = sumB;
q[j*nChannels+1] = sumG;
q[j*nChannels+2] = sumR;
}
}
}
void gaussblur(Mat input ,Mat &out, int x, int y) { float sigma = 1.5; Mat kernel; float pi = 3.1415926; kernel.create(x ,y ,CV_32F); float mx = x/2.0; float my = y/2.0;
//这里有问题,后面做修正。
for (int i =0; i< x;i++)
{
for (int j =0; j<y;j++)
{
kernel.at<float>(i,j) = exp(-1 * ((i - mx) * (i - mx) +(j - my) * (j-my) )/( 2 * sigma * sigma))/(2 * pi * sigma *sigma) ;
}
}
int nChannels = input.channels();
int nRows = input.rows;
int nCols = input.cols;
out.create(input.size(),input.type());
uchar* p;
uchar* q;
float* s;
for(int i = x; i < nRows - x; ++i)
{
q = out.ptr<uchar>(i);
for (int j = y; j < nCols - y; ++j)
{
float sumR = 0;
float sumG = 0;
float sumB = 0;
for (int k =0; k<x;k++)
{
p = input.ptr<uchar>(i-x+k);
s = kernel.ptr<float>(k);
for(int l = 0; l < y;l++)
{
sumB += p[(l + j -y)*nChannels ] * s[l];//input.at<uchar>(i - x + k,(j + l - y)*nChannels) * kernel;//
sumG += p[(l + j -y)*nChannels + 1] *s[l];//input.at<uchar>(i - x + k,(j + l - y)*nChannels + 1) * kernel;//
sumR += p[(l + j -y)*nChannels + 2] * s[l];//input.at<uchar>(i - x + k,(j + l - y)*nChannels + 2) * kernel;
}
}
q[j*nChannels] = sumB;
q[j*nChannels+1] = sumG;
q[j*nChannels+2] = sumR;
}
}
}
float sum = 0; for (int i =0; i< x;i++) { for (int j =0; j<y;j++) { sum+= kernel.at<float>(i,j) = exp(-1 * ((i - mx) * (i - mx) +(j - my) * (j-my) )/( 2 * sigma * sigma))/(2 * pi * sigma *sigma) ; } } for (int i =0; i< x;i++) { for (int j =0; j<y;j++) { kernel.at<float>(i,j) = kernel.at<float>(i,j)/ sum ; } }