Image filtering

Image filtering means the processing of images using a filter. The term filter in computer vision usually means pixel values modification, which for the given pixel depends only on the pixel values in the neighborhood of the pixel and is independent of the pixel's position. The simplest filters are pixel operations, which transform each pixel value using a rule; for example, the multiplication of each image's pixel with some scalar value. So, += value, -= value, *= value and set( value ) functions, discussed in the Working with ofxCv images section, are pixel operations.

The ofxCv images contain the following filtering functions and pixel operations:

  • The blur( winSize ) function is a smoothing filter that averages the pixel values in a square window around the given pixel with size winSize × winSize pixels. Here, winSize must be an odd integer (that is winSize is equal to 2*rad+1 for some integer rad). Increasing the winSize parameter leads to more smoothing. This filter is very fast and gives a smoothing result of moderate quality.
  • The blurGaussian( winSize ) function is a smoothing filter that uses the Gaussian weight function for averaging. The window size is winSize × winSize pixels and winSize must be an odd integer. This filter is more accurate than blur (because blur adds artifacts such as moire due to its square averaging). However, blurGaussian() is more CPU-expensive.

    If you wish to compare the results of blur and blurGaussian(), you should use different window sizes. The size in blurGaussian() should be greater than blur() by at least twice; for example, blur( 11 ) and blurGaussian( 21 ).

  • The erode() function is a minimizing filter that sets the minimal value to a pixel from a square window of 3 × 3 pixels. This operation is called morphological erosion. It is often used for binary images where it is used for removing small noisy white areas.
  • The dilate() function is a maximizing filter that sets the maximal value to a pixel from a square window of 3 × 3 pixels. This operation is called morphological dilation. It is often used for binary images where it is used for filling small holes in the white areas.
  • The convertToRange( minValue, maxValue ) pixel operation maps pixel values from the range of the image class to the [minValue, maxValue] range. It is very useful for any linear transformation of pixel values; for example, floatImage.convertToRange( 0.5, 1.5 ) maps the pixel values from the range [0, 1] to the range [0.5, 1.5] so it acts on pixel values by formula value = 0.5 + value * (1.5 - 0.5).
  • The invert() function is a pixel operation that inverts every bit of the pixel value. It is useful for images of the type ofxCvGrayscaleImage where it acts by the formula value that equals 255-value, and so it transforms the pixel value from 0 to 255 and 255 to 0. Such an operation can be done using grayImage.convertToRange( 255, 0 ) but invert() works faster.
  • The ofxCvGrayscaleImage class has a very important pixel operation of thresholding threshold( threshValue ). It sets the pixel value to 255 for each pixel if its value is not less than threshValue or 0. Otherwise, there is the second optional parameter in the function, doInvert of the type bool. When it is true, that is threshold( threshValue, true ), the result is inverted.
  • Use of the threshold() function is a crucial step in many computer vision processing algorithms because it converts a grayscale halftone image to a binary image. These binary images are then used for detecting, recognizing, and measuring objects such as human fingers and objects on a table. The reason for this is that binary images are simple objects used for performing shape analysis, area and perimeter calculation, and other things. See the example in the An example for searching bright objects in video section.

Now we will consider examples of using filtering.

The image filtering example

Gaussian smoothing is probably the most used filter in computer vision because this filter optimally suppresses random noise in the image for the corresponding filter window size. Additionally, because smoothing gives a smoothed image, it is better suited for further processing such as binarization.

We will consider an example that demonstrates a smoothing effect using the Gaussian filter. You will see and compare the thresholded original image and the thresholded smoothed image.

Note

This is example 09-OpenCV/02-ImageFiltering.

Use the Project Generator wizard for creating an empty project with the linked ofxOpenCv addon (see the Using ofxOpenCv section). Then, copy the sunflower.png image into bin/data of the project.

In the testApp.h file, add a line that includes the addon's header just after the #include "ofMain.h" line:

#include "ofMain.h"
#include "ofxOpenCv.h"

Add the following members to the testApp class declaration:

ofxCvColorImage image;	            //Original image
ofxCvGrayscaleImage grayImage;     //Grayscaled original image
ofxCvGrayscaleImage filtered;      //Image used for filtering

In testApp.cpp, the setup() function loads an image from the file, copies it to the color image image, and creates its grayscaled copy grayImage. Note that for loading the image from the file, we use a temporary object imageOf as follows:

void testApp::setup(){
  ofImage imageOf;  //Temporary image for loading from the file
  imageOf.loadImage( "sunflower.png" );  //Load image from
                                         //the file

  //Set image pixels
  image.setFromPixels( imageOf.getPixelsRef() );

  //Convert to a grayscale image
  grayImage = image;
}

To obtain a shorter code, we perform the all image processing steps right in draw() and directly draw its results on the screen using just one filtered image. A more accurate approach is to declare a separate image for each image we want draw, and then process it once in update(). Also, in the example, the input image has not changed so we can do the processing right in setup(). So, the update() function is empty here, and the draw() function does all the image processing:

void testApp::draw(){
  ofBackground( 128, 128, 128 ); //Set the background color

  //Get image dimensions
  int w = image.width;
  int h = image.height;
  ofSetColor( 255, 255, 255 );  //Set a color for images drawing

  //Draw original image
  grayImage.draw( 0, 0, w, h );

  //Thresholding original image
  filtered = grayImage;         //Copy the image
  filtered.threshold( 128 );    //Thresholding original image
                                //using thresold 128
  filtered.draw( w+10, 0, w, h );  //Draw

  //Smoothing original image
  filtered = grayImage;            //Copy the image
  filtered.blurGaussian( 9 );      //Gaussian blurring
                                   //with window size 9x9
  filtered.draw( 0, h+10, w, h );  //Draw

  //Thresholding smoothed image
  filtered.threshold( 128 );     //Thresholding smoothed image
                                 //using thresold 128
  filtered.draw( w+10, h+10, w, h );  //Draw
}

Run the example and you will see four images:

The image filtering example

Note that the Thresholded smoothed image has more smooth contours.

Here are two parameters of the algorithm:

  • The size of the smoothing window that is equal to 9 as shown in the following line:
    filtered.blurGaussian( 9 );
  • The threshold value that is equal to 128 as outlined in the following two lines:
    filtered.threshold( 128 ); //Thresholding original image
    ...
    filtered.threshold( 128 ); //Thresholding smoothed image

Adjust these parameters and watch how the smoothness of the contours and the overall number of white pixels change. Now we will consider geometrical transformation of images.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset