caffe实现上采样知识点总结
线性差值-反卷积-空洞卷积-上采样
等等一大堆名称,梳理梳理:
caffe中的deconvolution和upsample的区别?
https://www.zhihu.com/question/63890195
Caffe实现上采样(upsample)方法总结
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
在Caffe下自定义网络层 Interp层
https://blog.csdn.net/donkey_1993/article/details/81180059
caffe系列:deeplab中的插值网络层前传和反传的实现分析
https://blog.csdn.net/xizero00/article/details/74330652
Caffe中Interp层的使用
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];
-
}
-
}
-
}
-
}
-
}
【图像处理】双线性插值法实现图像的缩放(C实现)
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
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#csdnc-thumbsup"></use> </svg><span class="name">点赞</span> <span class="count">1</span> </a></li> <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-Collection-G"></use> </svg><span class="name">收藏</span></a></li> <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{"mod":"1582594662_002"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-fenxiang"></use> </svg>分享</a></li> <!--打赏开始--> <!--打赏结束--> <li class="tool-item tool-more"> <a> <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg> </a> <ul class="more-box"> <li class="item"><a class="article-report">文章举报</a></li> </ul> </li> </ul> </div> </div> <div class="person-messagebox"> <div class="left-message"><a href="https://blog.csdn.net/baidu_40840693"> <img src="https://profile.csdnimg.cn/6/0/1/3_baidu_40840693" class="avatar_pic" username="baidu_40840693"> <img src="https://g.csdnimg.cn/static/user-reg-year/1x/2.png" class="user-years"> </a></div> <div class="middle-message"> <div class="title"><span class="tit"><a href="https://blog.csdn.net/baidu_40840693" data-report-click="{"mod":"popu_379"}" target="_blank">知识在于分享</a></span> </div> <div class="text"><span>发布了327 篇原创文章</span> · <span>获赞 129</span> · <span>访问量 24万+</span></div> </div> <div class="right-message"> <a href="https://im.csdn.net/im/main.html?userName=baidu_40840693" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信 </a> <a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a> </div> </div> </div> </article>