Image Processing1 (Smoothing Images)

Goal

    blur():均值滤波
    GaussianBlur():高斯滤波
    medianBlur():中值滤波

    bilateralFilter():双边滤波

Theory

理论来源于:《计算机视觉:算法与应用》

均值滤波,高斯滤波以及中值滤波都比较简单,这里不再介绍。

双边滤波用的较少,详细介绍下。

双边介绍的权重有两个部分,其中第一部分的权重与高斯滤波使用的权重相同,第二部分的权重则是用于评估像素之间强度的差异。高斯滤波的思想:在大部分情况下,离中心像素的距离越近,则其权重越大;一般情况下,的确是这个样子,由于图像像素的缓慢变换,然而在图像的额边缘处,由于像素信息较为丰富,并不是这样子;继续使用空域高斯滤波则可能导致图像边缘模糊,因而这里应该根据像素的差异进行评估权重,若是像素颜色,纹理较为相似,则权重赢较大。因而双边滤波添加了另外的一个权重。具体公式如下(毛星云 《OpenCV3编程入门》):

不是俺不放公式,一放公式就待审查。公式上面提高书上的177-178页。

Code

/**
 * file Smoothing.cpp
 * brief Sample code for simple filters
 * author OpenCV team
 */


#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;

// Global Variables
int DELAY_CAPTION = 1500;
int DELAY_BLUR = 100;
int MAX_KERNEL_LENGTH = 31;

Mat src; Mat dst;
char window_name[] = "Smoothing Demo";

// Function headers
int display_caption( const char* caption );
int display_dst( int delay );


/**
 * function main
 */

int main( int argc, char ** argv )
{
    namedWindow( window_name, WINDOW_AUTOSIZE );

     // Load the source image
    const char* filename = argc >=2 ? argv[1] : "./lena.jpg";

    src = imread( filename, IMREAD_COLOR );
    if(src.empty()){
        printf(" Error opening image\n");
        printf(" Usage: ./Smoothing [image_name -- default ./lena.jpg] \n");
        return -1;
    }

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

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


    // Applying Homogeneous blur
    if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }

     //![blur]
    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; } }
    //![blur]

    // Applying Gaussian blur
    if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }

    //![gaussianblur]
    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; } }
    //![gaussianblur]

     // Applying Median blur
    if( display_caption( "Median Blur" ) != 0 ) { return 0; }

    //![medianblur]
    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
    { medianBlur ( src, dst, i );//原图想,目标图像,相当于size(i,i)
        if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    //![medianblur]

    // Applying Bilateral Filter
    if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }

     //![bilateralfilter]
    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; } }
    //![bilateralfilter]

    // Done
    display_caption( "Done!" );

    return 0;
}

/**
 * @function display_caption
 */

int display_caption( const char* caption )
{
    dst = Mat::zeros( src.size(), src.type() );
    // 图片,文本,点,字体类型,比例因子,颜色
    putText( dst, caption,
             Point( src.cols/4, src.rows/2),
             FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

    return display_dst(DELAY_CAPTION);
}

/**
 * @function display_dst
 */

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

}

添加了更详细的注释,这里不再解释。

CMakeLists.txt文件同上一篇,不用修改。

测试结果是一个渐变的过程。放一个中间过程的截图。


猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80221033