少高潮爽了在观看奂费_奶水无码专区_欧美亚洲三级日韩_91精品国产综合香蕉_秋霞伦理电影在线_GOGO亚洲肉体艺术欣赏图片_一本一道a√无码中文字幕_免费看一级毛片无码区_内射视频网站在线观看_国产激情视频精品中文

圖像處理
新聞詳情

常見圖像插值算法的原理與C++實(shí)現(xiàn)

發(fā)布時(shí)間:2021-03-25 09:33:52 最后更新:2021-03-25 10:11:37 瀏覽次數(shù):3877

講插值之前,首先講像素重采樣的概念。假設(shè)有圖像A和圖像B,其中A為源圖像,B為目標(biāo)圖像,A與B的坐標(biāo)具有對(duì)應(yīng)關(guān)系f:

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

通過關(guān)系f,把A的像素值賦值給B中對(duì)應(yīng)像素點(diǎn)的過程,叫做圖像A的像素重采樣,圖像B為重采樣之后的圖像。比如對(duì)于B的任意像素點(diǎn)(x, y),其對(duì)應(yīng)的A的像素點(diǎn)為(x', y'),那么則把A中點(diǎn)(x', y')的像素值A(chǔ)(x', y')賦值給B中點(diǎn)(x, y)的像素值B(x, y)。

(x‘, y’)=f(x, y)

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

像素重采樣的常見應(yīng)用場(chǎng)景為圖像縮放和圖像配準(zhǔn)。在實(shí)際應(yīng)用過程中,源圖像A的對(duì)應(yīng)坐標(biāo)往往不是整數(shù),而是浮點(diǎn)型數(shù)據(jù)(如下圖所示),因此不能直接取其像素值賦值給目標(biāo)圖像上的對(duì)應(yīng)點(diǎn)。此時(shí)要獲取點(diǎn)A(x', y')的像素值,插值算法就派上用場(chǎng)了。


所謂插值,就是使用浮點(diǎn)型坐標(biāo)點(diǎn)的周圍整型點(diǎn)的像素值來計(jì)算該浮點(diǎn)型坐標(biāo)點(diǎn)的像素值。比如上圖中,點(diǎn)(x', y')為浮點(diǎn)型坐標(biāo)點(diǎn),使用其周圍整型點(diǎn)p0、p1、p2、p3的像素值來計(jì)算其像素值A(chǔ)(x', y'),這個(gè)過程就是插值。

常見的插值算法有最鄰近插值、雙線性插值、雙三次插值,不管什么插值算法,其本質(zhì)都是取浮點(diǎn)型坐標(biāo)點(diǎn)周圍的n*n個(gè)整型坐標(biāo)點(diǎn)的像素值進(jìn)行加權(quán)和,從而得到該浮點(diǎn)型坐標(biāo)點(diǎn)的像素值,如下式:


不同插值算法的區(qū)別在于權(quán)重W的計(jì)算不一樣,下文將分別詳細(xì)講解最鄰近插值、雙線性插值、雙三次插值的計(jì)算原理與實(shí)現(xiàn)。

1. 最鄰近插值

最鄰近插值取離浮點(diǎn)型坐標(biāo)點(diǎn)的最近點(diǎn)的像素值作為其像素值,也可以看成使用浮點(diǎn)型坐標(biāo)點(diǎn)周圍2*2個(gè)整型點(diǎn)的像素值來計(jì)算其像素值,不過只有最靠近的那個(gè)點(diǎn)權(quán)重為1,其余3個(gè)點(diǎn)權(quán)重系數(shù)都為0。


插值的計(jì)算如下式:


其權(quán)重計(jì)算如下式:


最鄰近插值的代碼實(shí)現(xiàn)最簡(jiǎn)單,直接對(duì)浮點(diǎn)型坐標(biāo)進(jìn)行四舍五入取整即可,假設(shè)浮點(diǎn)坐標(biāo)為(x_float, y_float),那么使用最鄰近插值計(jì)算A(x_float, y_float)的代碼實(shí)現(xiàn)如下:

int x = (int)(x_float + 0.5);  //加0.5再截?cái)嗳≌?,與四舍五入取整等效
int y = (int)(y_float + 0.5);
uchar inner_value = A.ptr(y)[x];  //A(x',y')=A(x,y)


2. 雙線性插值

雙線性插值與最鄰近插值類似,同樣使用浮點(diǎn)型坐標(biāo)點(diǎn)周圍2*2個(gè)整型點(diǎn)的像素值來計(jì)算其像素值,不過其周圍每個(gè)整型點(diǎn)的權(quán)重都不為0,也就是說,其權(quán)重計(jì)算與最鄰近插值不一樣:


浮點(diǎn)坐標(biāo)點(diǎn)(x_float, y_float)雙線性插值的代碼實(shí)現(xiàn)如下:

int x0 = floor(x_float);
int x1 = x0 + 1;
int y0 = floor(y_float);
int y1 = y0 + 1;


float fracRow = y_float - y0;  //求浮點(diǎn)坐標(biāo)的小數(shù)部分
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. 雙三次插值

雙三次插值使用浮點(diǎn)型坐標(biāo)點(diǎn)周圍4*4個(gè)整型點(diǎn)的像素值來計(jì)算其像素值,如下圖所示:


浮點(diǎn)型坐標(biāo)點(diǎn)的插值為其周圍4*4整型坐標(biāo)點(diǎn)像素值的加權(quán)和:


其中權(quán)重W(i,j)的計(jì)算如下式,其中a取值范圍-1~0之間,一般取固定值-0.5。




雙三次插值的實(shí)現(xiàn)代碼如下。

首先是權(quán)重函數(shù)的實(shí)現(xiàn):

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;
}


接著是權(quán)重系數(shù)的計(jì)算實(shí)現(xiàn):

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);  //計(jì)算權(quán)重系數(shù)
   
   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;
}


從插值效果來說:雙三次插值>雙線性插值>最鄰近插值,從計(jì)算復(fù)雜度來說,同樣是:雙三次插值>雙線性插值>最鄰近插值。所以實(shí)際使用時(shí),根據(jù)自己的需要選擇合適的插值算法。


如涉及侵權(quán),請(qǐng)相關(guān)權(quán)利人與我司聯(lián)系刪除

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13822267203