当前位置:网站首页>Opencv interpolation mode
Opencv interpolation mode
2022-07-01 14:20:00 【Σίσυφος one thousand and nine hundred】
One 、 Interpolation method and resize() The relationship between
resize() Function contains several ways of interpolation :
void resize(InputArray src,// Input , Original image , The image to be changed ; OutputArray dst, // Output , Image after resizing , This image has the same content as the original image , It's just that the size is different from the original image ; Size dsize, // The size of the output image . If this parameter is not 0, So it means to zoom the original image to this Size(width,height) Specified size ; If this parameter is zero 0, Then the size of the original image after zooming should be calculated by the following formula : double fx=0, // width Scale in direction , If it is 0, Then it will follow (double)dsize.width/src.cols To calculate ; double fy=0, //height Scale in direction , If it is 0, Then it will follow (double)dsize.height/src.rows To calculate ; int interpolation=INTER_LINEAR// This is how to specify interpolation , After image zooming , Be sure to recalculate the pixels , It depends on this parameter to specify how pixels are recalculated , There are the following : INTER_NEAREST - Nearest neighbor interpolation INTER_LINEAR - Bilinear interpolation , If you don't specify the last parameter , This method is used by default INTER_AREA - Area interpolation resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method. INTER_CUBIC - 4x4 Bicubic interpolation in the neighborhood of a pixel INTER_LANCZOS4 - 8x8 Within the neighborhood of a pixel Lanczos interpolation );
Precautions for use :
dsize and fx/fy You can't do it at the same time 0,
Two 、 Nearest neighbor interpolation INTER_NEAREST
Nearest neighbor interpolation , Find the nearest neighbor ( Existing pixels , Black spot ), The assignment is the same .
Realization opencv Three interpolation algorithms commonly used in - Simple books
// Nearest neighborhood interpolation
// According to the pixel points of the target image ( Floating point coordinates ) Find... In the original image 4 Pixels , Take the original pixel value closest to the pixel point as the value of the point .
#include<opencv2/opencv.hpp>
#include<cassert>
namespace mycv {
void nearestIntertoplation(cv::Mat& src, cv::Mat& dst, const int rows, const int cols);
}//mycv
double distance(const double x1, const double y1, const double x2, const double y2);// Distance between two points , European distance is used here
int main() {
cv::Mat img = cv::imread("lena.jpg", 0);
if (img.empty()) return -1;
cv::Mat dst;
mycv::nearestIntertoplation(img, dst, 600, 600);
cv::imshow("img", img);
cv::imshow("dst", dst);
cv::waitKey(0);
return 0;
return 0;
}//main
void mycv::nearestIntertoplation(cv::Mat& src, cv::Mat& dst, const int rows, const int cols) {
// scale
const double scale_row = static_cast<double>(src.rows) / rows;
const double scale_col = static_cast<double>(src.rows) / cols;
// Expand src To dst
dst = cv::Mat(rows, cols, src.type());
assert(src.channels() == 1 && dst.channels() == 1);
for (int i = 0; i < rows; ++i)//dst The line of
for (int j = 0; j < cols; ++j)//dst The column of
{
// Find the four points of interpolation
double y = (i + 0.5) * scale_row + 0.5;
double x = (j + 0.5) * scale_col + 0.5;
int x1 = static_cast<int>(x);//col Corresponding x
if (x1 >= (src.cols - 2)) x1 = src.cols - 2;// To prevent cross-border
int x2 = x1 + 1;
int y1 = static_cast<int>(y);//row Corresponding y
if (y1 >= (src.rows - 2)) y1 = src.rows - 2;
int y2 = y1 + 1;
// According to the pixel points of the target image ( Floating point coordinates ) Find... In the original image 4 Pixels , Take the original pixel value closest to the pixel point as the value of the point .
assert(0 < x2 && x2 < src.cols && 0 < y2 && y2 < src.rows);
std::vector<double> dist(4);
dist[0] = distance(x, y, x1, y1);
dist[1] = distance(x, y, x2, y1);
dist[2] = distance(x, y, x1, y2);
dist[3] = distance(x, y, x2, y2);
int min_val = dist[0];
int min_index = 0;
for (int i = 1; i < dist.size(); ++i)
if (min_val > dist[i])
{
min_val = dist[i];
min_index = i;
}
switch (min_index)
{
case 0:
dst.at<uchar>(i, j) = src.at<uchar>(y1, x1);
break;
case 1:
dst.at<uchar>(i, j) = src.at<uchar>(y1, x2);
break;
case 2:
dst.at<uchar>(i, j) = src.at<uchar>(y2, x1);
break;
case 3:
dst.at<uchar>(i, j) = src.at<uchar>(y2, x2);
break;
default:
assert(false);
}
}
}
double distance(const double x1, const double y1, const double x2, const double y2)// Distance between two points , European distance is used here {
return (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);// Just compare the size , Just return the square of the distance
}3、 ... and 、 linear interpolation
Two known points ( Red ) , Giving a blue dot x coordinate , seek y.

// Linear interpolation ( Bilinear interpolation )
#include<opencv2/opencv.hpp>
#include<opencv2/core/matx.hpp>
#include<cassert>
namespace mycv {
void bilinearIntertpolatioin(cv::Mat& src, cv::Mat& dst, const int rows, const int cols);
}//mycv
int main() {
cv::Mat img = cv::imread("lena.jpg", 0);
if (img.empty()) return -1;
cv::Mat dst;
mycv::bilinearIntertpolatioin(img, dst, 600, 600);
cv::imshow("img", img);
cv::imshow("dst", dst);
cv::waitKey(0);
return 0;
}//main
void mycv::bilinearIntertpolatioin(cv::Mat& src, cv::Mat& dst, const int rows, const int cols) {
// scale
const double scale_row = static_cast<double>(src.rows) / rows;
const double scale_col = static_cast<double>(src.rows) / cols;
// Expand src To dst
dst = cv::Mat(rows, cols, src.type());
assert(src.channels() == 1 && dst.channels() == 1);
for(int i = 0; i < rows; ++i)//dst The line of
for (int j = 0; j < cols; ++j)//dst The column of
{
// Find the four points of interpolation
double y = (i + 0.5) * scale_row + 0.5;
double x = (j + 0.5) * scale_col + 0.5;
int x1 = static_cast<int>(x);//col Corresponding x
if (x1 >= (src.cols - 2)) x1 = src.cols - 2;// To prevent cross-border
int x2 = x1 + 1;
int y1 = static_cast<int>(y);//row Corresponding y
if (y1 >= (src.rows - 2)) y1 = src.rows - 2;
int y2 = y1 + 1;
assert(0 < x2 && x2 < src.cols && 0 < y2 && y2 < src.rows);
// Interpolation formula , Refer to Wikipedia matrix multiplication formula https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC
cv::Matx12d matx = { x2 - x, x - x1 };
cv::Matx22d matf = { static_cast<double>(src.at<uchar>(y1, x1)), static_cast<double>(src.at<uchar>(y2, x1)),
static_cast<double>(src.at<uchar>(y1, x2)), static_cast<double>(src.at<uchar>(y2, x2)) };
cv::Matx21d maty = {
y2 - y,
y - y1
};
auto val = (matx * matf * maty);
dst.at<uchar>(i, j) = val(0,0);
}
}Four 、 Bicubic interpolation
In the mathematical branch of numerical analysis , Bicubic interpolation ( English :Bicubic interpolation) It is the most commonly used interpolation method in two-dimensional space . In this way , function f At point (x, y) The value of can be obtained by the weighted average of the nearest 16 sampling points in the rectangular grid , Here we need to use two polynomials to interpolate cubic functions , Use one... In each direction
Bicubic interpolation calculation formula
So this a(i, j) It is the weighting coefficient mentioned in the introduction , So the key is to solve it .
The formula for solving the weighting coefficient is as follows
The code for solving the reinforcement coefficient is as follows :
std::vector<double> mycv::getW(double coor, double a)
{
std::vector<double> w(4);
int base = static_cast<int>(coor);// Take rounding as the benchmark
double e = coor - static_cast<double>(base);// More than the decimal part of the benchmark
std::vector<double> tmp(4);// Stored in formula |x| <= 1, 1 < |x| < 2 The four values
// 4 x 4 Of 16 A little bit , therefore tmp[0] and tmp[4] Far away , Values in [1, 2] Section
tmp[0] = 1.0 + e;// 1 < x < 2
tmp[1] = e;//x <= 1
tmp[2] = 1.0 - e;// x <= 1
tmp[3] = 2.0 - e;// 1 < x < 2
// according to bicubic Formula calculation coefficient w
// x <= 1
w[1] = (a + 2.0) * std::abs(std::pow(tmp[1], 3)) - (a + 3.0) * std::abs(std::pow(tmp[1], 2)) + 1;
w[2] = (a + 2.0) * std::abs(std::pow(tmp[2], 3)) - (a + 3.0) * std::abs(std::pow(tmp[2], 2)) + 1;
// 1 < x < 2
w[0] = a * std::abs(std::pow(tmp[0], 3)) - 5.0 * a * std::abs(std::pow(tmp[0], 2)) + 8.0*a*std::abs(tmp[0]) - 4.0*a;
w[3] = a * std::abs(std::pow(tmp[3], 3)) - 5.0 * a * std::abs(std::pow(tmp[3], 2)) + 8.0*a*std::abs(tmp[3]) - 4.0*a;
return w;
}
After solving it ,wx and wy Namely 4x4 Composed of 16 A coefficient of , And interpolation 4x4 Of 16 Points match . The key code of interpolation step
//4x4 Number of points (rr, cc) -> (y, x)
std::vector<std::vector<int> > src_arr = {
{ src.at<uchar>(rr - 1, cc - 1), src.at<uchar>(rr, cc - 1), src.at<uchar>(rr + 1, cc - 1), src.at<uchar>(rr + 2, cc - 1)},
{ src.at<uchar>(rr - 1, cc), src.at<uchar>(rr, cc), src.at<uchar>(rr + 1, cc), src.at<uchar>(rr + 2, cc)},
{ src.at<uchar>(rr - 1, cc + 1), src.at<uchar>(rr, cc + 1), src.at<uchar>(rr + 1, cc + 1), src.at<uchar>(rr + 2, cc + 1)},
{ src.at<uchar>(rr - 1, cc + 2), src.at<uchar>(rr, cc + 2), src.at<uchar>(rr + 1, cc + 2), src.at<uchar>(rr + 2, cc + 2)}
};
for(int p = 0; p < 3; ++p)
for (int q = 0; q < 3; ++q)
{
//val(p, q) = w(p,q) * src(p, q)
val += wr[p] * wc[q] * static_cast<double>(src_arr[p][q]);
}
assert(i < dst.rows && j < dst.cols);
dst.at<uchar>(i, j) = static_cast<int>(val);
// Bicubic interpolation
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
#include<cassert>
namespace mycv {
void bicubicInsterpolation(cv::Mat& src, cv::Mat& dst, const int rows, const int cols);
std::vector<double> getW(double coor, double a = -0.5);//a Default -0.5
}//mycv
int main(void)
{
cv::Mat img = cv::imread("lena.jpg", 0);
if (img.empty()) return -1;
cv::Mat dst;
mycv::bicubicInsterpolation(img, dst, 600, 600);
cv::imshow("img", img);
cv::imshow("dst", dst);
cv::waitKey(0);
return 0;
}//main
void mycv::bicubicInsterpolation(cv::Mat& src, cv::Mat& dst, const int rows, const int cols)
{
dst = cv::Mat(rows, cols, src.type(), cv::Scalar::all(0));// initialization dst
// scale
double row_scale = static_cast<double>(src.rows) / rows;
double col_scale = static_cast<double>(src.cols) / cols;
switch (src.channels())
{
case 1:// Grayscale
for(int i = 2; i < dst.rows - 2; ++i)
for (int j = 2; j < dst.cols - 2; ++j)
{
// Computing coefficients w
double r = static_cast<double>(i * row_scale);
double c = static_cast<double>(j * col_scale);
// To prevent cross-border
if (r < 1.0) r += 1.0;
if (c < 1.0) c += 1.0;
std::vector<double> wr = mycv::getW( r);
std::vector<double> wc = mycv::getW( c);
// Finally, calculate the gray value obtained by interpolation
double val = 0;
int cc = static_cast<int>(c);
int rr = static_cast<int>(r);
// To prevent cross-border
if (cc > src.cols - 3)
{
cc = src.cols - 3;
}
if (rr > src.rows - 3) rr = src.rows - 3;
assert(0 <= (rr - 1) && 0 <= (cc - 1) && (rr + 2) < src.rows && (cc + 2) < src.cols);
//4x4 Number of points (rr, cc) -> (y, x)
std::vector<std::vector<int> > src_arr = {
{ src.at<uchar>(rr - 1, cc - 1), src.at<uchar>(rr, cc - 1), src.at<uchar>(rr + 1, cc - 1), src.at<uchar>(rr + 2, cc - 1)},
{ src.at<uchar>(rr - 1, cc), src.at<uchar>(rr, cc), src.at<uchar>(rr + 1, cc), src.at<uchar>(rr + 2, cc)},
{ src.at<uchar>(rr - 1, cc + 1), src.at<uchar>(rr, cc + 1), src.at<uchar>(rr + 1, cc + 1), src.at<uchar>(rr + 2, cc + 1)},
{ src.at<uchar>(rr - 1, cc + 2), src.at<uchar>(rr, cc + 2), src.at<uchar>(rr + 1, cc + 2), src.at<uchar>(rr + 2, cc + 2)}
};
for(int p = 0; p < 3; ++p)
for (int q = 0; q < 3; ++q)
{
//val(p, q) = w(p,q) * src(p, q)
val += wr[p] * wc[q] * static_cast<double>(src_arr[p][q]);
}
assert(i < dst.rows && j < dst.cols);
dst.at<uchar>(i, j) = static_cast<int>(val);
}
break;
case 3:// colour ( The principle is the same, just two more channels )
break;
default:
break;
}
}
std::vector<double> mycv::getW(double coor, double a)
{
std::vector<double> w(4);
int base = static_cast<int>(coor);// Take rounding as the benchmark
double e = coor - static_cast<double>(base);// More than the decimal part of the benchmark
std::vector<double> tmp(4);// Stored in formula |x| <= 1, 1 < |x| < 2 The four values
// 4 x 4 Of 16 A little bit , therefore tmp[0] and tmp[4] Far away , Values in [1, 2] Section
tmp[0] = 1.0 + e;// 1 < x < 2
tmp[1] = e;//x <= 1
tmp[2] = 1.0 - e;// x <= 1
tmp[3] = 2.0 - e;// 1 < x < 2
// according to bicubic Formula calculation coefficient w
// x <= 1
w[1] = (a + 2.0) * std::abs(std::pow(tmp[1], 3)) - (a + 3.0) * std::abs(std::pow(tmp[1], 2)) + 1;
w[2] = (a + 2.0) * std::abs(std::pow(tmp[2], 3)) - (a + 3.0) * std::abs(std::pow(tmp[2], 2)) + 1;
// 1 < x < 2
w[0] = a * std::abs(std::pow(tmp[0], 3)) - 5.0 * a * std::abs(std::pow(tmp[0], 2)) + 8.0*a*std::abs(tmp[0]) - 4.0*a;
w[3] = a * std::abs(std::pow(tmp[3], 3)) - 5.0 * a * std::abs(std::pow(tmp[3], 2)) + 8.0*a*std::abs(tmp[3]) - 4.0*a;
return w;
}
边栏推荐
- Animesr: learnable degradation operator and new real world animation VSR dataset
- SWT/ANR问题--当发送ANR/SWT时候如何打开binder trace(BinderTraces)
- [IOT completion. Part 2] stm32+ smart cloud aiot+ laboratory security monitoring system
- Research Report on the development trend and competitive strategy of the global ultrasonic scalpel system industry
- Basic knowledge of C language
- Open source internship experience sharing: openeuler software package reinforcement test
- 【NLP】预训练模型——GPT1
- 【牛客网刷题系列 之 Verilog快速入门】~ 使用函数实现数据大小端转换
- App自动化测试开元平台Appium-runner
- 【Flask】Flask启程与实现一个基于Flask的最小应用程序
猜你喜欢

【商业终端仿真解决方案】上海道宁为您带来Georgia介绍、试用、教程

Leetcode(69)——x 的平方根

Etcd summary mechanism and usage scenarios

After being laid off for three months, the interview ran into a wall everywhere, and the mentality has begun to collapse

Use of Oracle database objects

【Flask】Flask启程与实现一个基于Flask的最小应用程序

户外LED显示屏应该考虑哪些问题?
![[anwangbei 2021] Rev WP](/img/98/ea5c241e2b8f3ae4c76e1c75c9e0d1.png)
[anwangbei 2021] Rev WP

TDengine 连接器上线 Google Data Studio 应用商店

“国防七子”经费暴增,清华足足362亿元,甩第二名101亿 |全国高校2022预算大公开...
随机推荐
[flask] flask starts and implements a minimal application based on flask
C语言课程设计题目
Research Report on the development trend and competitive strategy of the global facial wrinkle removal and beauty instrument industry
Play with grpc - communication between different programming languages
Research Report on the development trend and competitive strategy of the global high temperature label industry
深度合作 | 涛思数据携手长虹佳华为中国区客户提供 TDengine 强大企业级产品与完善服务保障
Force deduction solution summary 241- design priority for operation expression
我们该如何保护自己的密码?
sqlilabs less13
Why did you win the first Taosi culture award of 20000 RMB if you are neither a top R & D expert nor a sales Daniel?
券商万1免5证券开户是合理安全的吗,怎么讲
QT学习管理系统
MySQL日志
基于算力驱动、数据与功能协同的分布式动态(协同)渲染/功能运行时
C language course design topic
How will the surging tide of digitalization overturn the future?
程序设计的基本概念
Scheme of printing statistical information in log
Après avoir été licencié pendant trois mois, l'entrevue s'est effondrée et l'état d'esprit a commencé à s'effondrer.
【NLP】预训练模型——GPT1