热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

y等于ax的平方加bx加c的图像(已知yax2十bx十c图像)

讲插值之前,首先讲像素重采样的概念。假设有图像A和图像B,其中A为源图像,B为目标图像,A与B的坐标具有对应关系f:(xa,yaf(xb,yb通过关系f,把A的像素值赋值给B中


在讨论插值之前,我们先来谈谈像素重采样的概念。假设有图像A和B,其中A为源图像,B为目标图像,A和B的坐标有对应关系F:


(xa,ya)=f(xb,yb)


通过关系F将A的像素值赋给B中对应像素点的过程称为图像A的像素重采样,图像B为重采样后的图像。例如,对于B的任意像素点(x,y),A的对应像素点为(x’,y’),则A中点(x’,y’)的像素值A(x’,y’)赋给B中点(x,y)的像素值B (x,y)。


(x ',y')=f(x,y)


B(x,y)=A(x ',y ')


像素重采样的常见应用场景是图像缩放和图像配准。在实际应用中,源图像A的对应坐标往往不是整数,而是浮点数据(如下图所示),因此像素值不能直接赋给目标图像上的对应点。这时,要得到点A(x’,y’)的像素值,插值算法就派上用场了。




插值是利用浮点坐标点周围整数点的像素值来计算浮点坐标点的像素值。例如,在上图中,点(x’,y’)是一个浮点坐标点,它的像素值A(x’,y’)是利用它周围的整数点p0、p1、p2和p3的像素值计算出来的。这个过程就是插值。


常见的插值算法包括最近邻插值、双线性插值和双三次插值。无论什么插值算法,其本质都是取浮点坐标点周围n*n个整数坐标点的像素值进行加权求和,从而得到浮点坐标点的像素值,如下:




不同插值算法的区别在于权重w的计算方式不同。下面将详细解释最近邻插值、双线性插值和双三次插值的计算原理和实现。


1.最近邻插值


最近插值以离浮点坐标点最近的点的像素值作为其像素值,也可以认为是利用浮点坐标点周围2*2个整数点的像素值计算其像素值,但只有最近的点权重为1,其他三个点的权重系数均为0。




插值计算如下:




重量计算如下:




最近邻插值的代码实现是最简单的。直接舍入浮点坐标就可以了。假设浮点坐标为(x_float,y_float),使用最近邻插值计算A(x_float,y_float)的代码实现如下:


int x=(int)(x _ float 0.5);//加0.5然后截断取整,相当于取整。


int y=(int)(y _ float 0.5);


ucharinner _ value=a . ptruchar(y)[x];//A(x ',y')=A(x,y)


2.双线性插值


双线性插值类似于最近邻插值。它还使用浮点坐标点周围2*2个整数点的像素值来计算它的像素值,但是它周围每个整数点的权重不是0,也就是说它的权重计算不同于最近邻插值:

mg.com/origin/pgc-image/cb274874e3ee4b2393939bf25771208b?from=pc">

浮点坐标点(x_float, y_float)双线性插值的代码实现如下:

int x0 = floor(x_float);
int x1 = x0 + 1;
int y0 = floor(y_float);
int y1 = y0 + 1;
float fracRow = y_float - y0;  //求浮点坐标的小数部分
float fracCol = x_float - x0;
float k0 = 1.0 - fracRow;
float k1 = 1.0 - fracCol;
float w0 = k0*k1;
float w1 = fracRow*k1;
float w2 = k0*fracCol;
float w3 = fracRow*fracCol;
uchar inner_value = (uchar)(w0 * A.ptr(y0)[x0] + w1 * A.ptr(y1)[x0] + w2 * A.ptr(y0)[x1] + w3 * A.ptr(y1)[x1]);

3. 双三次插值

双三次插值使用浮点型坐标点周围4*4个整型点的像素值来计算其像素值,如下图所示:

浮点型坐标点的插值为其周围4*4整型坐标点像素值的加权和:

其中权重W(i,j)的计算如下式,其中a取值范围-1~0之间,一般取固定值-0.5。

双三次插值的实现代码如下。

首先是权重函数的实现:

float cubic_coeff(float x, float a)
{
if(x <= 1)
{
return 1-(a+3)*x*x+(a+2)*x*x*x;
}
else if(x <2)
{
return -4*a+8*a*x-5*a*x*x+a*x*x*x;
}
    return 0.0;
}

接着是权重系数的计算实现:

void cal_cubic_coeff(float x, float y, float *coeff)
{
/*calc the coeff*/
    float u = x - floor(x);
    float v = y - floor(y);

u += 1;
v += 1;
    float a = -0.15;
float a_mul_4 = (a + a) + (a + a);
float a_mul_5 = a_mul_4 + a;
float a_mul_8 = a_mul_4 + a_mul_4;
float a_add_3 = a + 3;
   float a_add_2 = a + 2;
float A[4];
A[0] = cubic_coeff(abs(u), a);
A[1] = cubic_coeff(abs(u-1), a);
A[2] = cubic_coeff(abs(u-2), a);
A[3] = cubic_coeff(abs(u-3), a);
for (int s = 0; s <4; s++)
   {
float C = cubic_coeff(abs(v-s), a);
coeff[s*4] = A[0]*C;
coeff[s*4+1] = A[1]*C;
coeff[s*4+2] = A[2]*C;
coeff[s*4+3] = A[3]*C;
}
}

最后,是双三次插值代码:

uchar cubic_inner(Mat A, float x_float, float y_float, float a)
{
float coeff[16];
cal_cubic_coeff(x_float, y_float, coeff); //计算权重系数

float sum = 0.0;
int x0 = floor(x_float) - 1;
   int y0 = floor(y_float) - 1;
   
for(int i = 0; i <4; i++)
{
      for(int j = 0; j < 4; j++)
{
           sum += coeff[i*4+j]*A.ptr(y0+i)[x0+j];
}
}

uchar inner_value = (uchar)sum;
   return inner_value;
}

从插值效果来说:双三次插值>双线性插值>最邻近插值,从计算复杂度来说,同样是:双三次插值>双线性插值>最邻近插值。所以实际使用时,根据自己的需要选择合适的插值算法。


推荐阅读
  • 使用Matlab创建动态GIF动画
    动态GIF图可以有效增强数据表达的直观性和吸引力。本文将详细介绍如何利用Matlab软件生成动态GIF图,涵盖基本代码实现与高级应用技巧。 ... [详细]
  • 贡献转移在计算每个元素的作用的时候,我们可以通过反向枚举作用效果,添加到作用元素的身上,这种方法叫做贡献转移。更正式的说, ... [详细]
  • 本文将探讨一个经典算法问题——最大连续子数组和。我们将从问题定义出发,逐步深入理解其背后的逻辑,并通过实例分析加深理解。 ... [详细]
  • 本文介绍了多维缩放(MDS)技术,这是一种将高维数据映射到低维空间的方法,通过保持原始数据间的关系,以便于可视化和分析。文章详细描述了MDS的原理和实现过程,并提供了Python代码示例。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • Irish budget airline Ryanair announced plans to significantly increase its route network from Frankfurt Airport, marking a direct challenge to Lufthansa, Germany's leading carrier. ... [详细]
  • 在开发过程中,有时需要提供用户创建数据库的功能。本文介绍了如何利用 .NET 和 ADOX 在应用程序中实现创建 Access 数据库,并详细说明了创建数据库及表的具体步骤。 ... [详细]
  • 1、编写一个Java程序在屏幕上输出“你好!”。programmenameHelloworld.javapublicclassHelloworld{publicst ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 在C语言编程中,点操作符(.)和箭头操作符(->)用于访问结构体成员,但它们的使用场景和方式有所不同。本文将详细探讨这两种操作符的区别,并通过实例说明如何正确使用。 ... [详细]
  • 基于SSM框架的在线考试系统:随机组卷功能详解
    本文深入探讨了基于SSM(Spring, Spring MVC, MyBatis)框架构建的在线考试系统中,随机组卷功能的设计与实现方法。 ... [详细]
  • binlog2sql,你该知道的数据恢复工具
    binlog2sql,你该知道的数据恢复工具 ... [详细]
  • 深入解析 C++ 中的 String 和 Vector
    本文详细介绍了 C++ 编程语言中 String 和 Vector 的使用方法及特性,旨在帮助开发者更好地理解和应用这两个重要的容器。 ... [详细]
  • 在Android中实现黑客帝国风格的数字雨效果
    本文将详细介绍如何在Android平台上利用自定义View实现类似《黑客帝国》中的数字雨效果。通过实例代码,我们将探讨如何设置文字颜色、大小,以及如何控制数字下落的速度和间隔。 ... [详细]
author-avatar
温暖不醒的aprildRi-1965
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有