Goal

In this tutorial you will learn how to:

  • Use the OpenCV function  filter2D() to  create your own linear filters.
  • 使用OpenCV函数filter2D()创建自己的线性滤波器

Theory

Note

The explanation below belongs to the book Learning OpenCV by Bradski and Kaehler.

       理论来源于《Learning OpenCV》这本书

Correlation

In a very general sense, correlation is an operation between every part of an image and an operator (kernel).

correlation 是图像的每一部分与核的操作。

What is a kernel?

A kernel is essentially a fixed size array of numerical coefficients along with an anchor point in that array, which is typically located at the center.

                                                                               Image Processing9(Making your own linear filters)

内核本质上是一个固定大小的数值系数矩阵,并且其锚点通常位于矩阵的中心。

How does correlation with a kernel work?

Assume you want to know the resulting value of a particular location in the image. The value of the correlation is calculated in the following way:

  1. Place the kernel anchor on top of a determined pixel, with the rest of the kernel overlaying the corresponding local pixels in the image.(top 不应该是中心吗???)
  2. Multiply the kernel coefficients by the corresponding image pixel values and sum the result.(相乘,最后求和)
  3. Place the result to the location of the anchor in the input image.(给图像中与锚点对应的元素)
  4. Repeat the process for all pixels by scanning the kernel over the entire image.(内核与图像的其他部分重复上述计算)

Expressing the procedure above in the form of an equation we would have:

H(x,y)=i=0Mi1j=0Mj1I(x+iai,y+jaj)K(i,j)

Fortunately, OpenCV provides you with the function filter2D() so you do not have to code all these operations.

What does this program do?

  • Loads an image(加载图像)
  • Performs a normalized box filter. For instance, for a kernel of size size=3, the kernel would be:

    K=133111111111

The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.(归一化运算)

  • The filter output (with each kernel) will be shown during 500 milliseconds(输出结果将在500毫秒显示)

Code

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main ( int argc, char** argv )
{
    // Declare variables
    Mat src, dst;
    Mat kernel;
    Point anchor;
    double delta;
    int ddepth;
    int kernel_size;
    const char* window_name = "filter2D Demo";
    const char* imageName = argc >=2 ? argv[1] : "lena.jpg";
    // Loads an image
    src = imread( imageName, IMREAD_COLOR ); // Load an image
    if( src.empty() )
    {
        printf(" Error opening image\n"); //竟然可以用,没有C标准的头文件
        printf(" Program Arguments: [image_name -- default lena.jpg] \n"); //竟然可以用,没有C标准的头文件
        return -1;
    }
    // Initialize arguments for the filter
    anchor = Point( -1, -1 ); //就是中心
    delta = 0;
    ddepth = -1;
    // Loop - Will filter the image with different kernel sizes each 0.5 seconds
    int ind = 0;
    for(;;)
    {
        // Update kernel size for a normalized box filter
        kernel_size = 3 + 2*( ind%5 );
        kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
        // Apply filter
        filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
       //输入,输出,深度(-1表示于src相同),内核,锚点相对于内核的位置,加到每个像素上的值,边界
        imshow( window_name, dst );
        char c = (char)waitKey(500);
        // Press 'ESC' to exit the program
        if( c == 27 )
        { break; }
        ind++;
    }
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

set(CMAKE_CXX_FLAGS "-std=c++11")
project( DisplayImage )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage main.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )


install(TARGETS DisplayImage RUNTIME DESTINATION bin)

Results

结果是一个渐变的过程,同时没500ms,内核的大小也会变化一次。

Image Processing9(Making your own linear filters)

相关文章: