歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenCV圖像處理篇之圖像平滑

圖像平滑算法

圖像平滑與圖像模糊是同一概念,主要用於圖像的去噪。平滑要使用濾波器,為不改變圖像的相位信息,一般使用線性濾波器,其統一形式如下:

其中h稱為濾波器的核函數,說白了就是權值。不同的核函數代表不同的濾波器,有不同的用途。

在圖像處理中,常見的濾波器包括:

1.歸一化濾波器(Homogeneous blur)

也是均值濾波器,用輸出像素點核窗口內的像素均值代替輸出點像素值。


2.高斯濾波器(Guassian blur)

是實際中最常用的濾波器,高斯濾波是將輸入數組的每一個像素點與 高斯內核 卷積將卷積和當作輸出像素值。高斯核相當於對輸出像素的鄰域賦予不同的權值,輸出像素點所在位置的權值最大(對應高斯函數的均值位置)。二維高斯函數為,

1.中值濾波器(median blur)

中值濾波將圖像的每個像素用鄰域(以當前像素為中心的正方形區域)像素的中值代替。對椒鹽噪聲最有效的濾波器,去除跳變點非常有效。


2.雙邊濾波器(Bilatrial blur)

為避免濾波器平滑圖像去噪的同時使邊緣也模糊,這種情況下使用雙邊濾波器。關於雙邊濾波器的解釋參見http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html


下面的程序將先給標准Lena圖像添加椒鹽噪聲,分別使用4種不同的濾波器進行平滑操作,請注意觀察不同濾波器對椒鹽噪聲的去噪效果!

程序分析及結果
/*
 * FileName : image_smoothing.cpp
 * Author  : xiahouzuoxin @163.com
 * Version  : v1.0
 * Date    : Wed 17 Sep 2014 08:30:25 PM CST
 * Brief    :
 *
 * Copyright (C) MICL,USTB
 */
#include "cv.h"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp"

using namespace std;
using namespace cv;

const int MAX_KERNEL_LENGTH = 10;

const char *wn_name = "Smoothing";

static void salt(Mat &I, int n);
static void disp_caption(const char *wn_name, Mat src, const char *caption);
static void disp_image(const char *wn_name, Mat I);

/*
 * @brief 
 * @inputs 
 * @outputs
 * @retval 
 */
int main(int argc, char *argv[])
{
    if (argc<2) {
        cout<<"Usage: ./image_smoothing [file name]"<<endl;
        return -1;
    }

    Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    salt(I, 6000);
    imshow(wn_name, I);
    waitKey(0);

    Mat dst;  // Result

    /* Homogeneous blur */
    disp_caption(wn_name, I, "Homogeneous blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        blur(I, dst, Size(i, i), Point(-1,-1));
        disp_image(wn_name, dst);
    }

    /* Guassian blur */
    disp_caption(wn_name, I, "Gaussian blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        GaussianBlur(I, dst, Size(i, i), 0, 0);
        disp_image(wn_name, dst);
    }

    /* Median blur */
    disp_caption(wn_name, I, "Median blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        medianBlur(I, dst, i);
        disp_image(wn_name, dst);
    }

    /* Bilatrial blur */
    disp_caption(wn_name, I, "Bilatrial blur");
    for (int i=1; i<MAX_KERNEL_LENGTH; i+=2) {
        bilateralFilter(I, dst, i, i*2, i/2);
        disp_image(wn_name, dst);
    }
    waitKey(0);

    return 0;
}


/*
 * @brief  顯示提示文字(濾波方法)
 * @inputs 
 * @outputs
 * @retval 
 */
static void disp_caption(const char *wn_name, Mat src, const char *caption)
{
    Mat dst = Mat::zeros(src.size(), src.type());

    putText(dst, caption, Point(src.cols/4, src.rows/2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255,255,255));

    imshow(wn_name, dst);
    waitKey(0);
}

 

/*
 * @brief  顯示圖像
 * @inputs 
 * @outputs
 * @retval 
 */
static void disp_image(const char *wn_name, Mat I)
{
    imshow(wn_name, I);
    waitKey(1000);
}


/*
 * @brief  添加椒鹽噪聲
 * @inputs 
 * @outputs
 * @retval 
 */
static void salt(Mat &I, int n=3000)
{
    for (int k=0; k<n; k++) {
        int i = rand() % I.cols;
        int j = rand() % I.rows;

        if (I.channels()) {
            I.at<uchar>(j,i) = 255;
        } else {
            I.at<Vec3b>(j,i)[0] = 255;
            I.at<Vec3b>(j,i)[1] = 255;
            I.at<Vec3b>(j,i)[2] = 255;
        }
    }
}

上面程序的邏輯非常清晰:

1.讀入灰度圖,並添加椒鹽噪聲(6000個噪聲點):
Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
salt(I, 6000);


2.disp_caption和disp_image函數分別是用於顯示提示文字和平滑過程中的變化圖像的,平滑過程中圖像的變化如下圖:

注意觀察上面的圖,中值濾波(Median Blur)對椒鹽噪聲的效果最好!


3.四種濾波方法分別使用到4個OpenCV函數,這些函數的聲明都在imgproc.hpp中,這些函數的前2個參數都是原圖像和濾波後圖像。

歸一化濾波器blur的第3個參數為濾波核窗口的大小,Size(i,i)表示ixi大小的窗口。

高斯濾波器GaussianBlur第3個參數也是濾波核窗口的大小,第4、第5個參數分辨表示x方向和y方向的δ。

中值濾波器medianBlur第3個參數是濾波器的長度,該濾波器的窗口為正方形。

雙邊濾波器的函數原型如下:
//! smooths the image using bilateral filter
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
                            double sigmaColor, double sigmaSpace,
                            int borderType=BORDER_DEFAULT );


4.本程序使用的Makefile文件為:
 TARG=image_smoothing
 SRC=image_smoothing.cpp
 LIB=-L/usr/local/lib/
 INC=-I/usr/local/include/opencv/ -I/usr/local/include/opencv2
 CFLAGS=

 $(TARG):$(SRC)
    g++ -g -o $@ ${CFLAGS} $(LIB) $(INC) \
        -lopencv_core -lopencv_highgui -lopencv_imgproc \
        $^

 .PHONY:clean

 clean:
    -rm $(TARG) tags -f

--------------------------------------分割線 --------------------------------------

Ubuntu Linux下安裝OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm

Ubuntu 12.04 安裝 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm

CentOS下OpenCV無法讀取視頻文件 http://www.linuxidc.com/Linux/2011-07/39295.htm

Ubuntu 12.04下安裝OpenCV 2.4.5總結 http://www.linuxidc.com/Linux/2013-06/86704.htm

Ubuntu 10.04中安裝OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm

基於QT和OpenCV的人臉識別系統 http://www.linuxidc.com/Linux/2011-11/47806.htm

--------------------------------------分割線 --------------------------------------

OpenCV的詳細介紹:請點這裡
OpenCV的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved