Processing math: 100%
OpenCV  
Open Source Computer Vision
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Smoothing Images

Prev Tutorial: Random generator and text with OpenCV

Next Tutorial: Eroding and Dilating

Goal

In this tutorial you will learn how to apply diverse linear filters to smooth images using OpenCV functions such as:

Theory

Note
The explanation below belongs to the book Computer Vision: Algorithms and Applications by Richard Szeliski and to LearningOpenCV

Normalized Box Filter

Gaussian Filter

The median filter run through each element of the signal (in this case the image) and replace each pixel with the median of its neighboring pixels (located in a square neighborhood around the evaluated pixel).

Bilateral Filter

Code

  • Downloadable code: Click here
  • Code at glance:
    #include <iostream>
    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[] = "Smoothing Demo";
    int display_caption( const char* caption );
    int display_dst( int delay );
    int main( int argc, char ** argv )
    {
    namedWindow( window_name, WINDOW_AUTOSIZE );
    const char* filename = argc >=2 ? argv[1] : "lena.jpg";
    src = imread( samples::findFile( filename ), IMREAD_COLOR );
    if (src.empty())
    {
    printf(" Error opening image\n");
    printf(" Usage:\n %s [image_name-- default lena.jpg] \n", argv[0]);
    return EXIT_FAILURE;
    }
    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( "Done!" );
    return 0;
    }
    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);
    }
    int display_dst( int delay )
    {
    imshow( window_name, dst );
    int c = waitKey ( delay );
    if( c >= 0 ) { return -1; }
    return 0;
    }

Explanation

Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is already known by now.

Normalized Block Filter:

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;
}
}

Gaussian Filter:

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;
}
}

Median Filter:

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

Bilateral Filter

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;
}
}

Results