小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

圖像平滑處理

 Rainbow_Heaven 2017-09-25
  • 原理?

Note

以下原理來源于Richard Szeliski 的著作 Computer Vision: Algorithms and Applications 以及 Learning OpenCV

  • 平滑 也稱 模糊, 是一項簡單且使用頻率很高的圖像處理方法。

  • 平滑處理的用途有很多, 但是在本教程中我們僅僅關注它減少噪聲的功用 (其他用途在以后的教程中會接觸到)。

  • 平滑處理時需要用到一個 濾波器 。 最常用的濾波器是 線性 濾波器,線性濾波處理的輸出像素值 (i.e. g(i,j)) 是輸入像素值 (i.e. f(i+k,j+l))的加權和 :

    g(i,j) = \sum_{k,l} f(i+k, j+l) h(k,l)

    h(k,l) 稱為 , 它僅僅是一個加權系數(shù)。

    不妨把 濾波器 想象成一個包含加權系數(shù)的窗口,當使用這個濾波器平滑處理圖像時,就把這個窗口滑過圖像。

  • 濾波器的種類有很多, 這里僅僅提及最常用的:

歸一化塊濾波器 (Normalized Box Filter)?

  • 最簡單的濾波器, 輸出像素值是核窗口內像素值的 均值 ( 所有像素加權系數(shù)相等)

  • 核如下:

    K = \dfrac{1}{K_{width} \cdot K_{height}} \begin{bmatrix}
    1 & 1 & 1 & ... & 1 \    1 & 1 & 1 & ... & 1 \    . & . & . & ... & 1 \    . & . & . & ... & 1 \    1 & 1 & 1 & ... & 1
   \end{bmatrix}

高斯濾波器 (Gaussian Filter)?

  • 最有用的濾波器 (盡管不是最快的)。 高斯濾波是將輸入數(shù)組的每一個像素點與 高斯內核 卷積將卷積和當作輸出像素值。

  • 還記得1維高斯函數(shù)的樣子嗎?

    ../../../../_images/Smoothing_Tutorial_theory_gaussian_0.jpg

    假設圖像是1維的,那么觀察上圖,不難發(fā)現(xiàn)中間像素的加權系數(shù)是最大的, 周邊像素的加權系數(shù)隨著它們遠離中間像素的距離增大而逐漸減小。

Note

2維高斯函數(shù)可以表達為 :

G_{0}(x, y) = A  e^{ \dfrac{ -(x - \mu_{x})^{2} }{ 2\sigma^{2}_{x} } +  \dfrac{ -(y - \mu_{y})^{2} }{ 2\sigma^{2}_{y} } }

其中 \mu 為均值 (峰值對應位置), \sigma 代表標準差 (變量 x 和 變量 y 各有一個均值,也各有一個標準差)

中值濾波器 (Median Filter)?

中值濾波將圖像的每個像素用鄰域 (以當前像素為中心的正方形區(qū)域)像素的 中值 代替 。

雙邊濾波 (Bilateral Filter)?

  • 目前我們了解的濾波器都是為了 平滑 圖像, 問題是有些時候這些濾波器不僅僅削弱了噪聲, 連帶著把邊緣也給磨掉了。 為避免這樣的情形 (至少在一定程度上 ), 我們可以使用雙邊濾波。
  • 類似于高斯濾波器,雙邊濾波器也給每一個鄰域像素分配一個加權系數(shù)。 這些加權系數(shù)包含兩個部分, 第一部分加權方式與高斯濾波一樣,第二部分的權重則取決于該鄰域像素與當前像素的灰度差值。
  • 詳細的解釋可以查看 鏈接

源碼?

  • 本程序做什么?

    • 裝載一張圖像
    • 使用4種不同濾波器 (見原理部分) 并顯示平滑圖像
  • 下載代碼: 點擊 這里

  • 代碼一瞥:

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

using namespace std;
using namespace cv;

/// 全局變量
int DELAY_CAPTION = 1500;
int DELAY_BLUR = 100;
int MAX_KERNEL_LENGTH = 31;

Mat src; Mat dst;
char window_name[] = "Filter Demo 1";

/// 函數(shù)申明
int display_caption( char* caption );
int display_dst( int delay );

/**
 *  main 函數(shù)
 */
 int main( int argc, char** argv )
 {
   namedWindow( window_name, CV_WINDOW_AUTOSIZE );

   /// 載入原圖像
   src = imread( "../images/lena.jpg", 1 );

   if( display_caption( "Original Image" ) != 0 ) { return 0; }

   dst = src.clone();
   if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }

   /// 使用 均值平滑
   if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }

   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
       { blur( src, dst, Size( i, i ), Point(-1,-1) );
         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

    /// 使用高斯平滑
    if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { GaussianBlur( src, dst, Size( i, i ), 0, 0 );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

     /// 使用中值平滑
     if( display_caption( "Median Blur" ) != 0 ) { return 0; }

     for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
         { medianBlur ( src, dst, i );
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

     /// 使用雙邊平滑
     if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }

     for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
         { bilateralFilter ( src, dst, i, i*2, i/2 );
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

     /// 等待用戶輸入
     display_caption( "End: Press a key!" );

     waitKey(0);
     return 0;
 }

 int display_caption( char* caption )
 {
   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( window_name, dst );
   int c = waitKey( DELAY_CAPTION );
   if( c >= 0 ) { return -1; }
   return 0;
  }

  int display_dst( int delay )
  {
    imshow( window_name, dst );
    int c = waitKey ( delay );
    if( c >= 0 ) { return -1; }
    return 0;
  }

解釋?

  1. 下面看一看有關平滑的OpenCV函數(shù),其余部分大家已經很熟了。

  2. 歸一化塊濾波器:

    OpenCV函數(shù) blur 執(zhí)行了歸一化塊平滑操作。

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { blur( src, dst, Size( i, i ), Point(-1,-1) );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

    我們輸入4個實參 (詳細的解釋請參考 Reference):

    • src: 輸入圖像
    • dst: 輸出圖像
    • Size( w,h ): 定義內核大小( w 像素寬度, h 像素高度)
    • Point(-1, -1): 指定錨點位置(被平滑點), 如果是負值,取核的中心為錨點。
  3. 高斯濾波器:

    OpenCV函數(shù) GaussianBlur 執(zhí)行高斯平滑 :

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { GaussianBlur( src, dst, Size( i, i ), 0, 0 );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

我們輸入4個實參 (詳細的解釋請參考 Reference):

  • src: 輸入圖像
  • dst: 輸出圖像
  • Size(w, h): 定義內核的大小(需要考慮的鄰域范圍)。 wh 必須是正奇數(shù),否則將使用 \sigma_{x}\sigma_{y} 參數(shù)來計算內核大小。
  • \sigma_{x}: x 方向標準方差, 如果是 0\sigma_{x} 使用內核大小計算得到。
  • \sigma_{y}: y 方向標準方差, 如果是 0\sigma_{y} 使用內核大小計算得到。.
  1. 中值濾波器:

    OpenCV函數(shù) medianBlur 執(zhí)行中值濾波操作:

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { medianBlur ( src, dst, i );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

    我們用了3個參數(shù):

    • src: 輸入圖像
    • dst: 輸出圖像, 必須與 src 相同類型
    • i: 內核大小 (只需一個值,因為我們使用正方形窗口),必須為奇數(shù)。
  2. 雙邊濾波器

    OpenCV函數(shù) bilateralFilter 執(zhí)行雙邊濾波操作:

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { bilateralFilter ( src, dst, i, i*2, i/2 );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

    我們使用了5個參數(shù):

    • src: 輸入圖像
    • dst: 輸出圖像
    • d: 像素的鄰域直徑
    • \sigma_{Color}: 顏色空間的標準方差
    • \sigma_{Space}: 坐標空間的標準方差(像素單位)


    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多