Opencv basic template for image processing


foreword

In opencv, if we want to implement some APIs in opencv by ourselves, such as mean filtering, Laplacian operator, Sobel operator, etc. For the mean filter, Laplacian operator, Sobel operator, etc., there is a characteristic that the value of the convolution kernel is fixed. The goal of this article is to write a basic template that can be used by various operators (only for fixed convolution kernels).


1. How to write the basic convolution template

We may encounter problems such as how to construct a convolution kernel, how to convolve the convolution kernel with the original image, and how to deal with boundary pixel convolution? The construction of the convolution kernel Because we already know the weight of the convolution kernel in advance, we can directly use a one-dimensional array to store the weight value. As for how to convolve the convolution kernel with the original image, one idea is: if we use Mat to store the weight of the convolution kernel, we can directly multiply two Mats (convolution kernel Mat and image Mat) to obtain the result. Another idea is: if we use a one-dimensional array to store the weight values, we multiply the weights of the convolution kernel and the corresponding pixels of the original image and add them together (this is the method used in this article).

2. Some knowledge about Opencv

1. How to use opencv to access the pixel of a certain point in the image

See here for accessing the pixel value of a point in an image using opencv .

2. How to use opencv to access pixels in a certain area of ​​​​the image

The image in Opencv is stored in Mat type. If we want to take a certain area in the image, then the type of this area should also be Mat.

int main()
{
    
    
    cv::Mat image = cv::imread("Lena.bmp");
    cv::Mat img_Rect = image(cv::Range(0, 256), cv::Range(0, 512));  //第一个参数是row的范围,第二个参数是col的范围
    return 0;
}

insert image description here
insert image description here

3. Boundary pixel processing

关于边界像素处理的方法请看(https://blog.csdn.net/qq_41596730/article/details/127738714)。

3. C++ code

The C++ code is as follows:

int reflect(int M, int x)
{
    
    
    if (x < 0)
        return -x;
    if (x >= M)
        return 2 * M - x - 1;
    return x;
}
void Convolution(const cv::Mat input, const float *kernel, cv::Mat output, int width, int height, int ksize)
{
    
    
    int kH = ksize / 2;
    int kW = ksize / 2;

    for (int h = 0; h < height; h++)
    {
    
    
        
        for (int w = 0; w < width; w++)
        {
    
    
            float dot = 0;
            for (int k_h = -kH; k_h <= kH; k_h++)
            {
    
    
                for (int k_w = -kW; k_w <= kW; k_w++)
                {
    
    
                    int cur_h = reflect(height, h + k_h);  //边界像素处理
                    int cur_w = reflect(width, w + k_w);

                    dot += input.at<uchar>(cur_h, cur_w)*kernel[(k_h + kH)*ksize + (k_w + kW)];  //对应相乘然后相加
                }
            }
            output.at<uchar>(h, w) = (uchar)std::max(0, std::min(255, (int)dot));
        }
    }
}

The main function is as follows:

int main()
{
    
    
    cv::Mat image = cv::imread("Lena.bmp");
    //cv::Mat img_Rect = image(cv::Range(0, 256), cv::Range(0, 512));  
    cv::Mat src;
    cv::cvtColor(image, src, CV_BGR2GRAY);
    cv::Mat output = cv::Mat::zeros(src.size(), CV_8UC1);
    int width = src.cols;
    int height = src.rows;
    float gx[] = {
    
    
        -1,0,1,
        -2,0,2,
        -1,0,1
    };
    Convolution(src, gx, output, width, height, 3);
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_41596730/article/details/127762536