图像处理之滤波器

Author:Maddock

Date:2015-04-2514:59:04

转载请注明出去:http://www.cnblogs.com/adong7639/p/4453719.html

滤波器的原理很简单,通俗的说,对于二维数据,依照某一个核或者称之为模板扫描图像数据,将模板的数据和原始数据

按照一定的规则计算,获取新的图像数据。

Matlab 自带的滤波函数

edge fspecial 打开fspecial文件可以看到例子

I = imread('cameraman.tif');
subplot(2,2,1);imshow(I);title('Original Image');
H = fspecial('motion',20,45);
MotionBlur = imfilter(I,H,'replicate');
subplot(2,2,2);imshow(MotionBlur);title('Motion Blurred Image');
H = fspecial('disk',10);
blurred = imfilter(I,H,'replicate');
subplot(2,2,3);imshow(blurred);title('Blurred Image');
H = fspecial('unsharp');
sharpened = imfilter(I,H,'replicate');
subplot(2,2,4);imshow(sharpened);title('Sharpened Image');

opencv自带的滤波函数

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;

int main()
{
   /// 载入原图像
   Mat src = imread( "lena.jpg", 1 );
   Mat dst1 = src.clone();
   Mat dst2 = src.clone();
   Mat dst3 = src.clone();
   Mat dst4 = src.clone();
   int ksize = 7;
   blur( src, dst1, Size( ksize, ksize ), Point(-1,-1) );
   GaussianBlur( src, dst2, Size( ksize, ksize ), 0, 0 );
   medianBlur ( src, dst3, ksize );
   bilateralFilter(src, dst4, ksize, ksize*2, ksize/2 );
   imshow("blur", dst1 );
   imshow("GaussianBlur", dst2 );
   imshow("medianBlur", dst3 );
   imshow("bilateralFilter", dst4 );
   waitKey(0);
   return 0;
}

有关这些滤波函数可以参考opencv的api文档

C++: void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
Parameters:
  • src – Source image.
  • dst – Destination image of the same size and type as src .
  • ksize – Gaussian kernel size. ksize.width and ksize.height can differ but they both must be positive and odd. Or, they can be zero’s and then they are computed from sigma* .
  • sigmaX – Gaussian kernel standard deviation in X direction.
  • sigmaY – Gaussian kernel standard deviation in Y direction. If sigmaY is zero, it is set to be equal to sigmaX . If both sigmas are zeros, they are computed from ksize.width and ksize.height , respectively. See getGaussianKernel() for details. To fully control the result regardless of possible future modifications of all this semantics, it is recommended to specify all of ksize , sigmaX , and sigmaY .
  • borderType – Pixel extrapolation method. See borderInterpolate() for details.
OpenCv提供一个更加通用的滤波函数 filter2D      Convolves an image with the kernel.
C++: void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT )
C: void cvFilter2D(const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1, -1))
Parameters:
  • src – Source image.
  • dst – Destination image of the same size and the same number of channels as src .
  • ddepth – Desired depth of the destination image. If it is negative, it will be the same as src.depth() .
  • kernel – Convolution kernel (or rather a correlation kernel), a single-channel floating point matrix. If you want to apply different kernels to different channels, split the image into separate color planes using split() and process them individually.
  • anchor – Anchor of the kernel that indicates the relative position of a filtered point within the kernel. The anchor should lie within the kernel. The special default value (-1,-1) means that the anchor is at the kernel center.
  • delta – Optional value added to the filtered pixels before storing them in dst .
  • borderType – Pixel extrapolation method. See borderInterpolate() for details.

The function applies an arbitrary linear filter to an image. In-place operation is supported. When the aperture is partially outside the image, the function interpolates outlier pixel values according to the specified border mode.

The function does actually compute correlation, not the convolution:

\texttt{dst} (x,y) =  \sum _{ \stackrel{0\leq x' < \texttt{kernel.cols},}{0\leq y' < \texttt{kernel.rows}} }  \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} )

 

例子

   Mat image_orignal = imread("lena.jpg"); 
   Mat image_filter_mean; 
   Mat kernel = (Mat_<float>(3,3)<<1,1,1, 1,1,1, 1,1,1)/9; 
   filter2D(image_orignal,image_filter_mean,image_orignal.depth(),kernel);  
   imshow("filter2D",image_filter_mean);

 

滤波器中有几个比较棘手的问题:

1 边界问题

  由于模板多为矩形窗口,这样图像边界的像素急需要特别处理。borderType指定了滤波时的边界处理类型。

  可以参考http://blog.csdn.net/viewcode/article/details/8287599

  也可以预先给图像做边界处理 参考http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/copyMakeBorder/copyMakeBorder.html

  使用OpenCV函数 copyMakeBorder 设置边界(添加额外的边界)。

  以一行图像数据为例,abcdefgh是原图数据,|是图像边界,为原图加边

  borderType的类型:

    1. /*Various border types, image boundaries are denoted with '|' 
    2.   
    3.  * BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh 
    4.  * BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb 
    5.  * BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba 
    6.  * BORDER_WRAP:          cdefgh|abcdefgh|abcdefg         
    7.  * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i' 
    8.  */ 

2 速度问题

  图像的滤波是比较耗时的操作,图像越大,模板核越大耗时越多。对于大分辨的图像,其核函数也要比较大,才能有滤波效果。

  对于不同的滤波器,优化策略也不同,目前还没有找到什么方法

  均值滤波:使用积分图,积分图的计算参看图像积分图的计算方法基于MATLAB的adaboost级联形式的人脸检测实现

  中值滤波:????

  高斯滤波:可以分离的核,先行滤波,接着列滤波,使用SSE或者neon指令优化???

  任意核函数的滤波:???

参考:

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html

http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/imgproc/doc/filtering.html?highlight=gaussianblur#void%20GaussianBlur%28InputArray%20src,%20OutputArray%20dst,%20Size%20ksize,%20double%20sigmaX,%20double%20sigmaY,%20int%20borderType%29

http://jingyan.baidu.com/article/20b68a884d6272796cec62e0.html

http://m.oschina.net/blog/91963

http://wenku.baidu.com/view/f538274259eef8c75fbfb3bc.html?re=view

posted on 2015-04-24 16:01  Maddock  阅读(1527)  评论(0编辑  收藏  举报

导航