赞
踩
线性差值-反卷积-空洞卷积-上采样
等等一大堆名称,梳理梳理:
https://www.zhihu.com/question/63890195
https://blog.csdn.net/chaipp0607/article/details/95599218
我也问了作者一个问题
关于:
https://github.com/TimoSaemann/caffe-segnet-cudnn5/blob/master/src/caffe/layers/upsample_layer.cpp
和caffe-yolov3实现的upsample_layer.cpp有什么区别???
两个代码是不一样
caffe-yolov3中的:
https://pan.baidu.com/share/init?surl=3GpoYoqKSCeFX0m0ves_fQ
密码bwrd
https://blog.csdn.net/donkey_1993/article/details/81180059
https://blog.csdn.net/xizero00/article/details/74330652
https://www.cnblogs.com/wmr95/p/8715607.html
https://github.com/hszhao/PSPNet
pytorch中的上采样:
https://blog.csdn.net/qq_31622015/article/details/90573618
Pytorch - torch.nn.modules.upsampling 和 interpolate 函数
https://www.aiuai.cn/aifarm605.html
关于yolov3的上采样:
https://blog.csdn.net/qq_34199326/article/details/84072505
原始的darknet:
https://blog.csdn.net/Lin_Danny/article/details/86514126
- #include "upsample_layer.h"
- #include "cuda.h"
- #include "blas.h"
-
- #include <stdio.h>
-
- layer make_upsample_layer(int batch, int w, int h, int c, int stride)
- {
- layer l = {0};
- l.type = UPSAMPLE;
- l.batch = batch;
- l.w = w;
- l.h = h;
- l.c = c;
- l.out_w = w*stride;
- l.out_h = h*stride;
- l.out_c = c;
- if(stride < 0){
- stride = -stride;
- l.reverse=1;
- l.out_w = w/stride;
- l.out_h = h/stride;
- }
- l.stride = stride;
- l.outputs = l.out_w*l.out_h*l.out_c;
- l.inputs = l.w*l.h*l.c;
- l.delta = calloc(l.outputs*batch, sizeof(float));
- l.output = calloc(l.outputs*batch, sizeof(float));;
-
- l.forward = forward_upsample_layer;
- l.backward = backward_upsample_layer;
- #ifdef GPU
- l.forward_gpu = forward_upsample_layer_gpu;
- l.backward_gpu = backward_upsample_layer_gpu;
-
- l.delta_gpu = cuda_make_array(l.delta, l.outputs*batch);
- l.output_gpu = cuda_make_array(l.output, l.outputs*batch);
- #endif
- if(l.reverse) fprintf(stderr, "downsample %2dx %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c);
- else fprintf(stderr, "upsample %2dx %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c);
- return l;
- }
-
- void resize_upsample_layer(layer *l, int w, int h)
- {
- l->w = w;
- l->h = h;
- l->out_w = w*l->stride;
- l->out_h = h*l->stride;
- if(l->reverse){
- l->out_w = w/l->stride;
- l->out_h = h/l->stride;
- }
- l->outputs = l->out_w*l->out_h*l->out_c;
- l->inputs = l->h*l->w*l->c;
- l->delta = realloc(l->delta, l->outputs*l->batch*sizeof(float));
- l->output = realloc(l->output, l->outputs*l->batch*sizeof(float));
-
- #ifdef GPU
- cuda_free(l->output_gpu);
- cuda_free(l->delta_gpu);
- l->output_gpu = cuda_make_array(l->output, l->outputs*l->batch);
- l->delta_gpu = cuda_make_array(l->delta, l->outputs*l->batch);
- #endif
-
- }
-
- void forward_upsample_layer(const layer l, network net)
- {
- fill_cpu(l.outputs*l.batch, 0, l.output, 1);
- if(l.reverse){
- upsample_cpu(l.output, l.out_w, l.out_h, l.c, l.batch, l.stride, 0, l.scale, net.input);
- }else{
- upsample_cpu(net.input, l.w, l.h, l.c, l.batch, l.stride, 1, l.scale, l.output);
- }
- }
-
- void backward_upsample_layer(const layer l, network net)
- {
- if(l.reverse){
- upsample_cpu(l.delta, l.out_w, l.out_h, l.c, l.batch, l.stride, 1, l.scale, net.delta);
- }else{
- upsample_cpu(net.delta, l.w, l.h, l.c, l.batch, l.stride, 0, l.scale, l.delta);
- }
- }
-
- #ifdef GPU
- void forward_upsample_layer_gpu(const layer l, network net)
- {
- fill_gpu(l.outputs*l.batch, 0, l.output_gpu, 1);
- if(l.reverse){
- upsample_gpu(l.output_gpu, l.out_w, l.out_h, l.c, l.batch, l.stride, 0, l.scale, net.input_gpu);
- }else{
- upsample_gpu(net.input_gpu, l.w, l.h, l.c, l.batch, l.stride, 1, l.scale, l.output_gpu);
- }
- }
-
- void backward_upsample_layer_gpu(const layer l, network net)
- {
- if(l.reverse){
- upsample_gpu(l.delta_gpu, l.out_w, l.out_h, l.c, l.batch, l.stride, 1, l.scale, net.delta_gpu);
- }else{
- upsample_gpu(net.delta_gpu, l.w, l.h, l.c, l.batch, l.stride, 0, l.scale, l.delta_gpu);
- }
- }
- #endif
其中:
- void upsample_cpu(float *in, int w, int h, int c, int batch, int stride, int forward, float scale, float *out)
- {
- int i, j, k, b;
- for(b = 0; b < batch; ++b){
- for(k = 0; k < c; ++k){
- for(j = 0; j < h*stride; ++j){
- for(i = 0; i < w*stride; ++i){
- int in_index = b*w*h*c + k*w*h + (j/stride)*w + i/stride;
- int out_index = b*w*h*c*stride*stride + k*w*h*stride*stride + j*w*stride + i;
- if(forward) out[out_index] = scale*in[in_index];
- else in[in_index] += scale*out[out_index];
- }
- }
- }
- }
- }
来自:
- #include "blas.h"
-
- #include <math.h>
- #include <assert.h>
- #include <float.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- void reorg_cpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out)
- {
- int b,i,j,k;
- int out_c = c/(stride*stride);
-
- for(b = 0; b < batch; ++b){
- for(k = 0; k < c; ++k){
- for(j = 0; j < h; ++j){
- for(i = 0; i < w; ++i){
- int in_index = i + w*(j + h*(k + c*b));
- int c2 = k % out_c;
- int offset = k / out_c;
- int w2 = i*stride + offset % stride;
- int h2 = j*stride + offset / stride;
- int out_index = w2 + w*stride*(h2 + h*stride*(c2 + out_c*b));
- if(forward) out[out_index] = x[in_index];
- else out[in_index] = x[out_index];
- }
- }
- }
- }
- }
-
- void flatten(float *x, int size, int layers, int batch, int forward)
- {
- float *swap = calloc(size*layers*batch, sizeof(float));
- int i,c,b;
- for(b = 0; b < batch; ++b){
- for(c = 0; c < layers; ++c){
- for(i = 0; i < size; ++i){
- int i1 = b*layers*size + c*size + i;
- int i2 = b*layers*size + i*layers + c;
- if (forward) swap[i2] = x[i1];
- else swap[i1] = x[i2];
- }
- }
- }
- memcpy(x, swap, size*layers*batch*sizeof(float));
- free(swap);
- }
-
- void weighted_sum_cpu(float *a, float *b, float *s, int n, float *c)
- {
- int i;
- for(i = 0; i < n; ++i){
- c[i] = s[i]*a[i] + (1-s[i])*(b ? b[i] : 0);
- }
- }
-
- void weighted_delta_cpu(float *a, float *b, float *s, float *da, float *db, float *ds, int n, float *dc)
- {
- int i;
- for(i = 0; i < n; ++i){
- if(da) da[i] += dc[i] * s[i];
- if(db) db[i] += dc[i] * (1-s[i]);
- ds[i] += dc[i] * (a[i] - b[i]);
- }
- }
-
- void shortcut_cpu(int batch, int w1, int h1, int c1, float *add, int w2, int h2, int c2, float s1, float s2, float *out)
- {
- int stride = w1/w2;
- int sample = w2/w1;
- assert(stride == h1/h2);
- assert(sample == h2/h1);
- if(stride < 1) stride = 1;
- if(sample < 1) sample = 1;
- int minw = (w1 < w2) ? w1 : w2;
- int minh = (h1 < h2) ? h1 : h2;
- int minc = (c1 < c2) ? c1 : c2;
-
- int i,j,k,b;
- for(b = 0; b < batch; ++b){
- for(k = 0; k < minc; ++k){
- for(j = 0; j < minh; ++j){
- for(i = 0; i < minw; ++i){
- int out_index = i*sample + w2*(j*sample + h2*(k + c2*b));
- int add_index = i*stride + w1*(j*stride + h1*(k + c1*b));
- out[out_index] = s1*out[out_index] + s2*add[add_index];
- }
- }
- }
- }
- }
-
- void mean_cpu(float *x, int batch, int filters, int spatial, float *mean)
- {
- float scale = 1./(batch * spatial);
- int i,j,k;
- for(i = 0; i < filters; ++i){
- mean[i] = 0;
- for(j = 0; j < batch; ++j){
- for(k = 0; k < spatial; ++k){
- int index = j*filters*spatial + i*spatial + k;
- mean[i] += x[index];
- }
- }
- mean[i] *= scale;
- }
- }
-
- void variance_cpu(float *x, float *mean, int batch, int filters, int spatial, float *variance)
- {
- float scale = 1./(batch * spatial - 1);
- int i,j,k;
- for(i = 0; i < filters; ++i){
- variance[i] = 0;
- for(j = 0; j < batch; ++j){
- for(k = 0; k < spatial; ++k){
- int index = j*filters*spatial + i*spatial + k;
- variance[i] += pow((x[index] - mean[i]), 2);
- }
- }
- variance[i] *= scale;
- }
- }
-
- void l2normalize_cpu(float *x, float *dx, int batch, int filters, int spatial)
- {
- int b,f,i;
- for(b = 0; b < batch; ++b){
- for(i = 0; i < spatial; ++i){
- float sum = 0;
- for(f = 0; f < filters; ++f){
- int index = b*filters*spatial + f*spatial + i;
- sum += powf(x[index], 2);
- }
- sum = sqrtf(sum);
- for(f = 0; f < filters; ++f){
- int index = b*filters*spatial + f*spatial + i;
- x[index] /= sum;
- dx[index] = (1 - x[index]) / sum;
- }
- }
- }
- }
-
-
- void normalize_cpu(float *x, float *mean, float *variance, int batch, int filters, int spatial)
- {
- int b, f, i;
- for(b = 0; b < batch; ++b){
- for(f = 0; f < filters; ++f){
- for(i = 0; i < spatial; ++i){
- int index = b*filters*spatial + f*spatial + i;
- x[index] = (x[index] - mean[f])/(sqrt(variance[f]) + .000001f);
- }
- }
- }
- }
-
- void const_cpu(int N, float ALPHA, float *X, int INCX)
- {
- int i;
- for(i = 0; i < N; ++i) X[i*INCX] = ALPHA;
- }
-
- void mul_cpu(int N, float *X, int INCX, float *Y, int INCY)
- {
- int i;
- for(i = 0; i < N; ++i) Y[i*INCY] *= X[i*INCX];
- }
-
- void pow_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY)
- {
- int i;
- for(i = 0; i < N; ++i) Y[i*INCY] = pow(X[i*INCX], ALPHA);
- }
-
- void axpy_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY)
- {
- int i;
- for(i = 0; i < N; ++i) Y[i*INCY] += ALPHA*X[i*INCX];
- }
-
- void scal_cpu(int N, float ALPHA, float *X, int INCX)
- {
- int i;
- for(i = 0; i < N; ++i) X[i*INCX] *= ALPHA;
- }
-
- void fill_cpu(int N, float ALPHA, float *X, int INCX)
- {
- int i;
- for(i = 0; i < N; ++i) X[i*INCX] = ALPHA;
- }
-
- void deinter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT)
- {
- int i, j;
- int index = 0;
- for(j = 0; j < B; ++j) {
- for(i = 0; i < NX; ++i){
- if(X) X[j*NX + i] += OUT[index];
- ++index;
- }
- for(i = 0; i < NY; ++i){
- if(Y) Y[j*NY + i] += OUT[index];
- ++index;
- }
- }
- }
-
- void inter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT)
- {
- int i, j;
- int index = 0;
- for(j = 0; j < B; ++j) {
- for(i = 0; i < NX; ++i){
- OUT[index++] = X[j*NX + i];
- }
- for(i = 0; i < NY; ++i){
- OUT[index++] = Y[j*NY + i];
- }
- }
- }
-
- void copy_cpu(int N, float *X, int INCX, float *Y, int INCY)
- {
- int i;
- for(i = 0; i < N; ++i) Y[i*INCY] = X[i*INCX];
- }
-
- void mult_add_into_cpu(int N, float *X, float *Y, float *Z)
- {
- int i;
- for(i = 0; i < N; ++i) Z[i] += X[i]*Y[i];
- }
-
- void smooth_l1_cpu(int n, float *pred, float *truth, float *delta, float *error)
- {
- int i;
- for(i = 0; i < n; ++i){
- float diff = truth[i] - pred[i];
- float abs_val = fabs(diff);
- if(abs_val < 1) {
- error[i] = diff * diff;
- delta[i] = diff;
- }
- else {
- error[i] = 2*abs_val - 1;
- delta[i] = (diff < 0) ? 1 : -1;
- }
- }
- }
-
- void l1_cpu(int n, float *pred, float *truth, float *delta, float *error)
- {
- int i;
- for(i = 0; i < n; ++i){
- float diff = truth[i] - pred[i];
- error[i] = fabs(diff);
- delta[i] = diff > 0 ? 1 : -1;
- }
- }
-
- void softmax_x_ent_cpu(int n, float *pred, float *truth, float *delta, float *error)
- {
- int i;
- for(i = 0; i < n; ++i){
- float t = truth[i];
- float p = pred[i];
- error[i] = (t) ? -log(p) : 0;
- delta[i] = t-p;
- }
- }
-
- void logistic_x_ent_cpu(int n, float *pred, float *truth, float *delta, float *error)
- {
- int i;
- for(i = 0; i < n; ++i){
- float t = truth[i];
- float p = pred[i];
- error[i] = -t*log(p) - (1-t)*log(1-p);
- delta[i] = t-p;
- }
- }
-
- void l2_cpu(int n, float *pred, float *truth, float *delta, float *error)
- {
- int i;
- for(i = 0; i < n; ++i){
- float diff = truth[i] - pred[i];
- error[i] = diff * diff;
- delta[i] = diff;
- }
- }
-
- float dot_cpu(int N, float *X, int INCX, float *Y, int INCY)
- {
- int i;
- float dot = 0;
- for(i = 0; i < N; ++i) dot += X[i*INCX] * Y[i*INCY];
- return dot;
- }
-
- void softmax(float *input, int n, float temp, int stride, float *output)
- {
- int i;
- float sum = 0;
- float largest = -FLT_MAX;
- for(i = 0; i < n; ++i){
- if(input[i*stride] > largest) largest = input[i*stride];
- }
- for(i = 0; i < n; ++i){
- float e = exp(input[i*stride]/temp - largest/temp);
- sum += e;
- output[i*stride] = e;
- }
- for(i = 0; i < n; ++i){
- output[i*stride] /= sum;
- }
- }
-
-
- void softmax_cpu(float *input, int n, int batch, int batch_offset, int groups, int group_offset, int stride, float temp, float *output)
- {
- int g, b;
- for(b = 0; b < batch; ++b){
- for(g = 0; g < groups; ++g){
- softmax(input + b*batch_offset + g*group_offset, n, temp, stride, output + b*batch_offset + g*group_offset);
- }
- }
- }
-
- void upsample_cpu(float *in, int w, int h, int c, int batch, int stride, int forward, float scale, float *out)
- {
- int i, j, k, b;
- for(b = 0; b < batch; ++b){
- for(k = 0; k < c; ++k){
- for(j = 0; j < h*stride; ++j){
- for(i = 0; i < w*stride; ++i){
- int in_index = b*w*h*c + k*w*h + (j/stride)*w + i/stride;
- int out_index = b*w*h*c*stride*stride + k*w*h*stride*stride + j*w*stride + i;
- if(forward) out[out_index] = scale*in[in_index];
- else in[in_index] += scale*out[out_index];
- }
- }
- }
- }
- }
https://blog.csdn.net/weixin_43227685/article/details/88970457
- #include <string.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include<time.h>//时间相关头文件,可用其中函数计算图像处理速度
-
- #define WIDTHBYTES(bits) (((bits)+31)/32*4)//用于使图像宽度所占字节数为4byte的倍数
-
- //#define MYDRAW_HEIGHT 986 //目标图像高度
- //define MYDRAW_WIDTH 1572 //目标图像宽度
-
- #define MYDRAW_HEIGHT 246 //目标图像高度
- #define MYDRAW_WIDTH 393 //目标图像
-
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- typedef unsigned long DWORD;
- typedef long LONG;
-
-
-
- //位图文件头信息结构定义
- //其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)
-
- typedef struct tagBITMAPFILEHEADER {
- DWORD bfSize; //文件大小
- WORD bfReserved1; //保留字,不考虑
- WORD bfReserved2; //保留字,同上
- DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和
- } BITMAPFILEHEADER;
-
- //信息头BITMAPINFOHEADER,也是一个结构,其定义如下:
-
- typedef struct tagBITMAPINFOHEADER {
- //public:
- DWORD biSize; //指定此结构体的长度,为40
- LONG biWidth; //位图宽
- LONG biHeight; //位图高
- WORD biPlanes; //平面数,为1
- WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
- DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩
- DWORD biSizeImage; //实际位图数据占用的字节数
- LONG biXPelsPerMeter; //X方向分辨率
- LONG biYPelsPerMeter; //Y方向分辨率
- DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数)
- DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的
- } BITMAPINFOHEADER;
-
- void main()
- {
- long now = 0;
- now = clock();//存储图像处理开始时间
-
- BITMAPFILEHEADER bitHead, writebitHead;
- BITMAPINFOHEADER bitInfoHead, writebitInfoHead;
- FILE* pfile;//输入文件
- FILE* wfile;//输出文件
-
- char strFile[50] = "C:\\testpicture\\1.bmp";//打开图像路径,BMP图像必须为24位真彩色格式
- char strFilesave[50] = "C:\\testpicture\\3.bmp";//处理后图像存储路径
- fopen_s(&pfile, strFile, "rb");//文件打开图像
- fopen_s(&wfile, strFilesave, "wb");//打开文件为存储修改后图像做准备
- //读取位图文件头信息
- WORD fileType;
- fread(&fileType, 1, sizeof(WORD), pfile);
- fwrite(&fileType, 1, sizeof(WORD), wfile);
- if (fileType != 0x4d42)
- {
- printf("file is not .bmp file!");
- return;
- }
- //读取位图文件头信息
- fread(&bitHead, 1, sizeof(tagBITMAPFILEHEADER), pfile);
- writebitHead = bitHead;//由于截取图像头和源文件头相似,所以先将源文件头数据赋予截取文件头
- //读取位图信息头信息
- fread(&bitInfoHead, 1, sizeof(BITMAPINFOHEADER), pfile);
- writebitInfoHead = bitInfoHead;//同位图文件头相似
-
- writebitInfoHead.biHeight = MYDRAW_HEIGHT;//为截取文件重写位图高度
- writebitInfoHead.biWidth = MYDRAW_WIDTH;//为截取文件重写位图宽度
- int mywritewidth = WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//BMP图像实际位图数据区的宽度为4byte的倍数,在此计算实际数据区宽度
- writebitInfoHead.biSizeImage = mywritewidth*writebitInfoHead.biHeight;//计算位图实际数据区大小
-
- writebitHead.bfSize = 54 + writebitInfoHead.biSizeImage;//位图文件头大小为位图数据区大小加上54byte
- fwrite(&writebitHead, 1, sizeof(tagBITMAPFILEHEADER), wfile);//写回位图文件头信息到输出文件
- fwrite(&writebitInfoHead, 1, sizeof(BITMAPINFOHEADER), wfile);//写回位图信息头信息到输出文件
-
- int width = bitInfoHead.biWidth;
- int height = bitInfoHead.biHeight;
- //分配内存空间把源图存入内存
- int l_width = WIDTHBYTES(width*bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为4byte的倍数
- int write_width = WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//计算写位图的实际宽度并确保它为4byte的倍数
-
- BYTE *pColorData = (BYTE *)malloc(height*l_width);//开辟内存空间存储图像数据
- memset(pColorData, 0, height*l_width);
-
- BYTE *pColorDataMid = (BYTE *)malloc(mywritewidth*MYDRAW_HEIGHT);//开辟内存空间存储图像处理之后数据
- memset(pColorDataMid, 0, mywritewidth*MYDRAW_HEIGHT);
-
- long nData = height*l_width;
- long write_nData = mywritewidth*MYDRAW_HEIGHT;//截取的位图数据区长度定义
-
- //把位图数据信息读到数组里
- fread(pColorData, 1, nData, pfile);//图像处理可通过操作这部分数据加以实现
-
- /*******************图像处理部分******************/
- /*******************双线性插值******************/
- for (int hnum = 0; hnum < MYDRAW_HEIGHT; hnum++)
- for (int wnum = 0; wnum < MYDRAW_WIDTH; wnum++)
- {
- double d_original_img_hnum = hnum*height / (double)MYDRAW_HEIGHT;
- double d_original_img_wnum = wnum*width / (double)MYDRAW_WIDTH;
- int i_original_img_hnum = d_original_img_hnum;
- int i_original_img_wnum = d_original_img_wnum;
- double distance_to_a_x = d_original_img_wnum - i_original_img_wnum;//在原图像中与a点的水平距离
- double distance_to_a_y = d_original_img_hnum - i_original_img_hnum;//在原图像中与a点的垂直距离
-
- int original_point_a = i_original_img_hnum*l_width + i_original_img_wnum * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点A
- int original_point_b = i_original_img_hnum*l_width + (i_original_img_wnum + 1) * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点B
- int original_point_c = (i_original_img_hnum + 1)*l_width + i_original_img_wnum * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点C
- int original_point_d = (i_original_img_hnum + 1)*l_width + (i_original_img_wnum + 1) * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点D
- if (i_original_img_hnum +1== MYDRAW_HEIGHT - 1)
- {
- original_point_c = original_point_a;
- original_point_d = original_point_b;
- }
- if (i_original_img_wnum +1== MYDRAW_WIDTH - 1)
- {
- original_point_b = original_point_a;
- original_point_d = original_point_c;
- }
-
- int pixel_point = hnum*write_width + wnum * 3;//映射尺度变换图像数组位置偏移量
- pColorDataMid[pixel_point] =
- pColorData[original_point_a] * (1 - distance_to_a_x)*(1 - distance_to_a_y) +
- pColorData[original_point_b] * distance_to_a_x*(1 - distance_to_a_y) +
- pColorData[original_point_c] * distance_to_a_y*(1 - distance_to_a_x) +
- pColorData[original_point_c] * distance_to_a_y*distance_to_a_x;
- pColorDataMid[pixel_point + 1] =
- pColorData[original_point_a + 1] * (1 - distance_to_a_x)*(1 - distance_to_a_y) +
- pColorData[original_point_b + 1] * distance_to_a_x*(1 - distance_to_a_y) +
- pColorData[original_point_c + 1] * distance_to_a_y*(1 - distance_to_a_x) +
- pColorData[original_point_c + 1] * distance_to_a_y*distance_to_a_x;
- pColorDataMid[pixel_point + 2] =
- pColorData[original_point_a + 2] * (1 - distance_to_a_x)*(1 - distance_to_a_y) +
- pColorData[original_point_b + 2] * distance_to_a_x*(1 - distance_to_a_y) +
- pColorData[original_point_c + 2] * distance_to_a_y*(1 - distance_to_a_x) +
- pColorData[original_point_c + 2] * distance_to_a_y*distance_to_a_x;
-
- }
- /*******************双线性插值******************/
- /*******************图像处理部分******************/
-
- fwrite(pColorDataMid, 1, write_nData, wfile); //将处理完图像数据区写回文件
- fclose(pfile);
- fclose(wfile);
-
- printf("图像处理完成\n");
- printf("运行时间为:%dms\n", int(((double)(clock() - now)) / CLOCKS_PER_SEC * 1000));//输出图像处理花费时间信息
- }
https://blog.csdn.net/py184473894/article/details/90739167
- def bilinear_interpolation(img,scale):
- dst_cols=(int)(img.shape[0]*scale)
- dst_rows=(int)(img.shape[1]*scale)
- img_dst=np.zeros([dst_cols,dst_rows])
-
- for i in range(dst_cols-1):
- for j in range(dst_rows-1):
- #坐标转换
- scr_x=(i+0.5)/scale-0.5
- scr_y=(j+0.5)/scale-0.5
-
- #整数部分
- int_x=int(scr_x)
- #小数部分
- float_x=scr_x-int_x
-
- int_y=int(scr_y)
- float_y=scr_y-int_y
-
-
- if int_x==img.shape[0]-1:
- int_x_p=img.shape[0]-1
- else:
- int_x_p=int_x+1
-
- if int_y==img.shape[1]-1:
- int_y_p=img.shape[1]-1
- else:
- int_y_p=int_y+1
-
-
- img_dst[i][j]=(1-float_x)*(1-float_y)*img[int_x][int_y]+(1-float_x)*float_y*img[int_x][int_y_p]+\
- float_x*(1-float_y)*img[int_x_p][int_y]+float_x*float_y*img[int_x_p][int_y_p]
-
- return img_dst
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。