Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement bicubic interpolation algorithm for C++ OpenCV

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "C++ OpenCV how to achieve image bicubic interpolation algorithm", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Next let the editor to take you to learn "C++ OpenCV how to achieve image bicubic interpolation algorithm" it!

1. The principle of image bicubic interpolation algorithm

First of all, the principle part. The principle of image bicubic interpolation is that each pixel of the target image is weighted by 4x4=16 pixels around the corresponding points on the original image and then added. The weighting here uses the cubic function, which is the origin of the name of the image bicubic interpolation algorithm (personal guess). The cubic function used is shown in the following figure:

The key question is what the input and output of this cubic function represent, respectively. To put it simply, the input is the coordinate values of the 4x4 size area around the corresponding point of the original image, the size is between 0 to 2, and the output is the weight of the Abscissa or ordinate of these points. Four Abscissa and four ordinates are multiplied by the weight matrix of 4x4 size, and then the pixels of the target map points can be obtained by multiplying and adding the corresponding regions of the original image.

The following picture can help you understand better

First of all, what are u and v? For example, for a grayscale image of 100x100, if you want to enlarge it to 500x500, then its scaling factor sx=500/100=5,sy=500/100=5. Now the target image is 500x500, and you need to fill the 500x500 space with the 100x100 pixel values of the original image. According to src_x=i/sx and src_y=j/sy, you can get the original image pixel coordinates (src_x, src_y) corresponding to the target pixel coordinates (src_x, src_y). The decimal parts of src_x and src_y are u and v in the image above.

With the understanding of u and v, we can use u and v to calculate the weight of the bicubic interpolation algorithm. It is said above that the input of the cubic function is the coordinate value of the 4x4 size area around the corresponding point of the original picture, for the above picture, the Abscissa has four inputs, which are 1fugu, uleast, 1ltel, and 2ltel, respectively, and there are also four inputs in the ordinate, which are 1qv, LV, vLV, LTV, and 2v, respectively. According to the cubic function, the pairwise multiplication is the corresponding 4x4-sized weight matrix.

Once you know how to find the weight matrix, you can traverse the entire image for interpolation. The following is based on my understanding of the principle of C++ opencv code, the code is not optimized, but can let you intuitively understand the image bicubic interpolation algorithm.

C++ OpenCV Code 1. Calculate the weight matrix

As mentioned earlier, the weight matrix is the multiplication of four outputs of Abscissa and four outputs of ordinate, so only eight output values corresponding to Abscissa and ordinate are required.

The code is as follows:

Std::vector getWeight (double c, double a = 0.5) {/ / c is u and v, and the output of Abscissa and ordinate is calculated in the same way as std::vector temp (4); temp [0] = 1 + c; temp [1] = c; temp [2] = 1-c; temp [3] = 2-c / / y (x) = (axi2) | x | * | x | * | x |-(axi3) | x | * | x | + 1 | x | 255) pix = 255; dst.at (I-1, j-1) = static_cast (pix) } / / process color image else if (src.channels () = = 3) {for (int I = 1; I)

< dst_rows + 1; ++i) { int src_y = (i + 0.5) / sy - 0.5; if (src_y < 0) src_y = 0; if (src_y >

Src.rows-1) src_y = src.rows-1; src_y + = 1; int i1 = std::floor (src_y); int i2 = std::ceil (src_y); int i0 = i1-1; int i3 = i2 + 1 Double u = src_y-static_cast (i1); std::vector weight_y = getWeight (u); for (int j = 1; j)

< dst_cols + 1; ++j) { int src_x = (j + 0.5) / sy - 0.5; if (src_x < 0) src_x = 0; if (src_x >

Src.rows-1) src_x = src.rows-1; src_x + = 1; int J1 = std::floor (src_x); int J2 = std::ceil (src_x); int J0 = J1-1 Int J3 = J2 + 1; double v = src_x-static_cast (J1); std::vector weight_x = getWeight (v); cv::Vec3b pix Pix [0] = weight_x [0] * weight_y [0] * border.at (i0, j0) [0] + weight_x [1] * weight_y [0] * border.at (i0, J1) [0] + weight_x [2] * weight_y [0] * border.at (i0 J2) [0] + weight_x [3] * weight_y [0] * border.at (i0, j3) [0] + weight_x [0] * weight_y [1] * border.at (i1, J0) [0] + weight_x [1] * weight_y [1] * border.at (i1) J1) [0] + weight_x [2] * weight_y [1] * border.at (i1, j2) [0] + weight_x [3] * weight_y [1] * border.at (i1, j3) [0] + weight_x [0] * weight_y [2] * border.at (i2) J0) [0] + weight_x [1] * weight_y [2] * border.at (i2, j1) [0] + weight_x [2] * weight_y [2] * border.at (i2, j2) [0] + weight_x [3] * weight_y [2] * border.at (i2 J3) [0] + weight_x [0] * weight_y [3] * border.at (i3, J0) [0] + weight_x [1] * weight_y [3] * border.at (i3, J1) [0] + weight_x [2] * weight_y [3] * border.at (i3 J2) [0] + weight_x [3] * weight_y [3] * border.at (i3, j3) [0] Pix [1] = weight_x [0] * weight_y [0] * border.at (i0, J0) [1] + weight_x [1] * weight_y [0] * border.at (i0, J1) [1] + weight_x [2] * weight_y [0] * border.at (i0 J2) [1] + weight_x [3] * weight_y [0] * border.at (i0, j3) [1] + weight_x [0] * weight_y [1] * border.at (i1, J0) [1] + weight_x [1] * weight_y [1] * border.at (i1) J1) [1] + weight_x [2] * weight_y [1] * border.at (i1, j2) [1] + weight_x [3] * weight_y [1] * border.at (i1, j3) [1] + weight_x [0] * weight_y [2] * border.at (i2) J0) [1] + weight_x [1] * weight_y [2] * border.at (i2, J1) [1] + weight_x [2] * weight_y [2] * border.at (i2, j2) [1] + weight_x [3] * weight_y [2] * border.at (i2 J3) [1] + weight_x [0] * weight_y [3] * border.at (i3, J0) [1] + weight_x [1] * weight_y [3] * border.at (i3, J1) [1] + weight_x [2] * weight_y [3] * border.at (i3 J2) [1] + weight_x [3] * weight_y [3] * border.at (i3, j3) [1] Pix [2] = weight_x [0] * weight_y [0] * border.at (i0, J0) [2] + weight_x [1] * weight_y [0] * border.at (i0, J1) [2] + weight_x [2] * weight_y [0] * border.at (i0 J2) [2] + weight_x [3] * weight_y [0] * border.at (i0, j3) [2] + weight_x [0] * weight_y [1] * border.at (i1, J0) [2] + weight_x [1] * weight_y [1] * border.at (i1) J1) [2] + weight_x [2] * weight_y [1] * border.at (i1, j2) [2] + weight_x [3] * weight_y [1] * border.at (i1, j3) [2] + weight_x [0] * weight_y [2] * border.at (i2) J0) [2] + weight_x [1] * weight_y [2] * border.at (i2, j1) [2] + weight_x [2] * weight_y [2] * border.at (i2, j2) [2] + weight_x [3] * weight_y [2] * border.at (i2 J3) [2] + weight_x [0] * weight_y [3] * border.at (i3, J0) [2] + weight_x [1] * weight_y [3] * border.at (i3, J1) [2] + weight_x [2] * weight_y [3] * border.at (i3 J2) [2] + weight_x [3] * weight_y [3] * border.at (i3, j3) [2] For (int I = 0; I

< src.channels(); ++i) { if (pix[i] < 0) pix = 0; if (pix[i] >

Pix = 255;} dst.at (I-1, j-1) = static_cast (pix);} 3. Test and result int main () {cv::Mat src = cv::imread ("C:\\ Users\\ Echo\\ Pictures\\ Saved Pictures\\ bilateral.png"); cv::Mat dst; bicubic (src, dst, 309x0.5); cv::imshow ("gray", dst); cv::imshow ("src", src); cv::waitKey (0);}

Color image (magnified twice)

At this point, I believe that "C++ OpenCV how to achieve image bicubic interpolation algorithm" have a deeper understanding, might as well to the actual operation of it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report