两次立方插值下限 [英] Bicubic interpolation for downscale

查看:307
本文介绍了两次立方插值下限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看来,双三次插值仅适用于高档。我曾尝试以下功能: http://jsperf.com/pixel-interpolation/4 http://www.reddit.com/r/javascript/comments/jxa8x/ bicubic_interpolation /

Seems that bicubic interpolation works only for upscale. I have tried these functions: http://jsperf.com/pixel-interpolation/4 and http://www.reddit.com/r/javascript/comments/jxa8x/bicubic_interpolation/

此外,我已经试过了算法双三次插值距离的Gernot霍夫曼的书插补图像变形。

Also I've tried an algorithm for Bicubic Interpolation from Gernot Hoffmann's book "Interpolations for Image Warping".

不过,缩小使用上面的方法看起来他们被近邻插值后的所有图像。

But all images after scaling down using above methods looks like they were interpolated by near neighbor.

也许我错了的东西?

我也注意到,在Photoshop中有对双三次插值两个不同的选择:双三次平滑(用于高档)和双三次锐利(用于下限)

I've also noticed that in Photoshop there are two separate options for bicubic interpolation: Bicubic Smoother (for upscale) and Bicubic Sharper (for downscale).

所以,也许有人知道双三次插值为下限的算法?

So maybe somebody knows an algorithm of bicubic interpolation for downscale?

推荐答案

我刚写了一个算法,双三次interpolition ... 我工作得很好。 在运行之前,根据你的形象改变了一些值;

I just wrote an algorithm for bicubic interpolition... I works well. before you run it, changes the some values according to your image;

ROW和放大器;列

#define ROW 218     //change 218 to your image's horizantol pixels 
#define COLUMN 329` //change 329 to your image's vertical pixels

ZOOM_RATE和放大器; ZOOM_NUM

ZOOM_RATE是图像的大小调整的速度,如果你想dublicate它,然后让​​它2

ZOOM_RATE is the rate of your image's resizing if you want to dublicate it then make it "2"

ZOOM_NUM = 1 / ZOOM_RATE - > ZOOM_NUM等于1以上ZOOM_RATE

ZOOM_NUM=1/ZOOM_RATE -> ZOOM_NUM is equal to 1 over ZOOM_RATE

的名名和扩展名形象

INT主要()职能转变

readPpm("irfan.ppm");    //change irfan to your image's name

下面是源$ C ​​$ C:(此codeS还具有双线性interpolition,这样你可以比较的结果)

here is the source code:(this codes has also bilinear interpolition, so you can compare your results)

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
#include <sstream>
#include <string.h>
#include <vector>
#include <math.h>

using namespace std;
#define ROW 218
#define COLUMN 329
#define ZOOM_RATE 2
#define ZOOM_NUM 1/2

struct POINT {   // Declare POINT structure
   int x;   // Define members x and y
   int y;
   int renk;
} ;    // Variable spot has
                        // values x = 20, y = 40

typedef struct POINT coordinate;     // Variable there has POINT type

int int_arr[ROW][COLUMN*3];
int int_arr_simple[ROW][COLUMN];
int zoom_photo[(int)(ROW*ZOOM_RATE)][(int)(COLUMN*ZOOM_RATE)];
int zoom_photo_bicubic[(int)(ROW*ZOOM_RATE)][(int)(COLUMN*ZOOM_RATE)];
string filetype;
string comment;
string size;
string colorrange;

int line_find(int ,int,int,int,float);
void save2Ppm(string filename,int pixel[ROW][COLUMN*3],int size);
void save2Pgm(string filename,int pixel[ROW][COLUMN],int size);
void save2Pgm_zoom(string filename,int pixel[ROW*ZOOM_RATE][COLUMN*ZOOM_RATE],int size);
void readPpm(string);
void zooming();
void zooming_bilinear();
void zooming_bicubic();
int bicubic_function(float x_cor,float y_cor);

void save2Pgm_zoom(string filename,int pixel[ROW*ZOOM_RATE][COLUMN*ZOOM_RATE],int size){
    ofstream Picture;
    Picture.open(filename);
    Picture<<"P2\n#"<<filename<<"\n"<<(int)(COLUMN*ZOOM_RATE)<<" "<<(int)(ROW*ZOOM_RATE)<<"\n"<<size<<"\n";    

    for(int i=0 ; i<ROW*ZOOM_RATE ; i++)
    {
        for(int j=0; j<COLUMN*ZOOM_RATE; j++){
            Picture<<pixel[i][j]<<" ";
        }
    }
    Picture.close();
}
void zooming(){
    for(int i=0;i<ROW*ZOOM_RATE;i++){
        for(int j=0;j<COLUMN*ZOOM_RATE;j++){
            zoom_photo[i][j]=int_arr_simple[i*ZOOM_NUM][j*ZOOM_NUM];
        }
    }   
}
void save2Pgm(string filename,int pixel[ROW][COLUMN],int size){
    ofstream Picture;
    Picture.open(filename);
    Picture<<"P2\n#"<<filename<<"\n"<<COLUMN<<" "<<ROW<<"\n"<<size<<"\n";    

    for(int i=0 ; i<ROW ; i++)
    {
        for(int j=0; j<COLUMN; j++){
            Picture<<pixel[i][j]<<" ";
        }
    }
    Picture.close();
}
void save2Ppm(string filename,int pixel[ROW][COLUMN*3],int size){
    ofstream Picture;
    Picture.open(filename);
    Picture<<"P3\n#"<<filename<<"\n"<<COLUMN<<" "<<ROW<<"\n"<<size<<"\n";    

    for(int i=0 ; i<ROW ; i++)
    {
        for(int j=0; j<COLUMN*3; j++){
            Picture<<pixel[i][j]<<" ";
        }
    }
    Picture.close();
}
void readPpm(string filename){
    ifstream Picture(filename);
    //Picture.open(filename);
    char take[10000];

    if(!Picture)
        printf("FILE NOT OPEN!!!!!!\n");
    else
    {
        Picture.getline( take, 10000 ); 
        for(int i = 0; take[i] != 0; i++)
            filetype += take[i];
        Picture.getline( take, 10000 );
        for(int i = 0; take[i] != 0; i++)
            comment += take[i];
        Picture.getline( take, 10000 );
        for(int i = 0; take[i] != 0; i++)
            size += take[i];
        Picture.getline( take, 10000 ); 
        for(int i = 0; take[i] != 0; i++)
            colorrange += take[i];

        Picture.getline( take, 10000 ,' ');
        int_arr[0][0]=atoi(take);
        for(int i=1,j=0,t=0;i<ROW*COLUMN*3;i++){    
            Picture.getline( take, 10000 ,' ');
            t=i%(COLUMN*3);
            if(i%(COLUMN*3)==0)
                j++;
            int_arr[j][t]=atoi(take);
            int_arr_simple[j][t/3]=int_arr[j][t];
        }
        Picture.close();
    }
}
void zooming_bilinear(){
    double x,y;
    double result_x,result_y,result;
    double x_1,x1;
    double y_1,y1;
    for(int i=0;i<ROW*ZOOM_RATE;i++){
        for(int j=0;j<COLUMN*ZOOM_RATE;j++){
            y=(double)ZOOM_NUM*i;
            x=(double)ZOOM_NUM*j;

            x_1 = (int)x;       y_1 = (int)y;
            x1  = (int)(x+1);    y1 = (int)(y+1);

            result_x=(double)(x1-x)*int_arr_simple[(int)y_1][(int)x_1]/(double)(x1-x_1) + (double)(x-x_1)*int_arr_simple[(int)y_1][(int)x1]/(double)(x1-x_1);
            result_y=(double)(x1-x)*int_arr_simple[(int)y1][(int)x_1] /(double)(x1-x_1) + (double)(x-x_1)*int_arr_simple[(int)y1][(int)x_1]/(double)(x1-x_1);
            result=(double)(y1-y)*result_x/(double)(y1-y_1)                   + (double)(y-y_1)*result_y /(double)(y1-y_1   );

            zoom_photo[i][j]=result;
        }
    }   

}
void zooming_bicubic(){
    double x,y;
    double result_x,result_y,result;
    double x_1,x1;
    double y_1,y1;

    //zoom 16 pixel arasında olduğu için verileri atmaya 2,2 den başlıyor   ve 2 birim önce bitiyor...
    for(int i=1;i<ROW*ZOOM_RATE-1;i++){
        for(int j=1;j<COLUMN*ZOOM_RATE-1;j++){
            zoom_photo_bicubic[i][j]=bicubic_function((float)ZOOM_NUM*j,(float)ZOOM_NUM*i);
        }
    }   
}
int bicubic_function(float x_cor,float y_cor){//bicubic yöntemle renk döndürmek için kullanılan fonksiyon
    coordinate nokta[4][4];
    int result;//en sonunda rengi döndüren variable
    nokta[0][0].x=(int)y_cor-1;             nokta[0][0].y=(int)x_cor-1;
    nokta[0][1].x=(int)y_cor-1;             nokta[0][1].y=(int)x_cor;
    nokta[0][2].x=(int)y_cor-1;             nokta[0][2].y=(int)x_cor+1;
    nokta[0][3].x=(int)y_cor-1;             nokta[0][3].y=(int)x_cor+2;
    nokta[1][0].x=(int)y_cor;               nokta[1][0].y=(int)x_cor-1;
    nokta[1][1].x=(int)y_cor;               nokta[1][1].y=(int)x_cor;
    nokta[1][2].x=(int)y_cor;               nokta[1][2].y=(int)x_cor+1;
    nokta[1][3].x=(int)y_cor;               nokta[1][3].y=(int)x_cor+2;
    nokta[2][0].x=(int)y_cor+1;             nokta[2][0].y=(int)x_cor-1;
    nokta[2][1].x=(int)y_cor+1;             nokta[2][1].y=(int)x_cor;
    nokta[2][2].x=(int)y_cor+1;             nokta[2][2].y=(int)x_cor+1;
    nokta[2][3].x=(int)y_cor+1;             nokta[2][3].y=(int)x_cor+2;
    nokta[3][0].x=(int)y_cor+2;             nokta[3][0].y=(int)x_cor-1;
    nokta[3][1].x=(int)y_cor+2;             nokta[3][1].y=(int)x_cor;
    nokta[3][2].x=(int)y_cor+2;             nokta[3][2].y=(int)x_cor+1;
    nokta[3][3].x=(int)y_cor+2;             nokta[3][3].y=(int)x_cor+2;

    float xline_1,xline_2,xline_3,xline_4;

    int P00,P01,P02,P03;
    P00=int_arr_simple[nokta[0][0].x][nokta[0][0].y-1];
    P01=int_arr_simple[nokta[0][1].x][nokta[0][1].y-1];
    P02=int_arr_simple[nokta[0][2].x][nokta[0][2].y-1];
    P03=int_arr_simple[nokta[0][3].x][nokta[0][3].y-1];



    int P10,P11,P12,P13;
    P10=int_arr_simple[nokta[1][0].x][nokta[1][0].y-1];
    P11=int_arr_simple[nokta[1][1].x][nokta[1][1].y-1];
    P12=int_arr_simple[nokta[1][2].x][nokta[1][2].y-1];
    P13=int_arr_simple[nokta[1][3].x][nokta[1][3].y-1];


    int P20,P21,P22,P23;
    P20=int_arr_simple[nokta[2][0].x][nokta[2][0].y-1];
    P21=int_arr_simple[nokta[2][1].x][nokta[2][1].y-1];
    P22=int_arr_simple[nokta[2][2].x][nokta[2][2].y-1];
    P23=int_arr_simple[nokta[2][3].x][nokta[2][3].y-1];


    int P30,P31,P32,P33;
    P30=int_arr_simple[nokta[3][0].x][nokta[3][0].y-1];
    P31=int_arr_simple[nokta[3][1].x][nokta[3][1].y-1];
    P32=int_arr_simple[nokta[3][2].x][nokta[3][2].y-1];
    P33=int_arr_simple[nokta[3][3].x][nokta[3][3].y-1];


                    xline_1=line_find(P00,P01,P02,P03, x_cor-(int)x_cor);
                    xline_2=line_find(P10,P11,P12,P13, x_cor-(int)x_cor);
                    xline_3=line_find(P20,P21,P22,P23, x_cor-(int)x_cor);
                    xline_4=line_find(P30,P31,P32,P33, x_cor-(int)x_cor);
      result=line_find(xline_1,xline_2,xline_3,xline_4,y_cor-(int)y_cor);

    return result;

}
int line_find(int P0,int P1,int P2,int P3, float x) {   // bir denklemin "rengini" çevirmek için kullanılır....
    float A,B,C,D,result;
    A=(float)(-(float)1/2)*(float)P0 + ((float)3/2)*(float)P1       + (-(float)3/2)*(float)P2 + ((float)1/2)*(float)P3   ;
    B=(float)P0     + (-(float)5/2)*(float)P1       + (2)*(float)P2 + (-(float)1/2)*(float)P3           ;
    C=(-(float)1/2)*(float)P0   + ((float)1/2)*(float)P2                                        ;
    D=(float)P1                                                     ;
    result=A*x*x*x + B*x*x + C*x + D ;
    return result;
}
int main (){
    readPpm("irfan.ppm");
    save2Ppm("ppm",int_arr,255);
    save2Pgm("pgm",int_arr_simple,255);
    zooming_bilinear();
    save2Pgm_zoom("zoom_bilinear",zoom_photo,255);
    zooming_bicubic();
    save2Pgm_zoom("zoom_bicubic",zoom_photo_bicubic,255);
    return 0;
}

这篇关于两次立方插值下限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆