双线性插值resize实现图片放缩
opencv的resize的双线性插值实现
简简单单两张图说明原理,仔细看一会原理就懂了,不要怕图二的数学公式,看明白就知道有多简单了。
原理看懂了的话,就来看实现吧。
这里实现的重点是要以两张图片的中心建立坐标系,进行计算。
图中黑点即为坐标原点,第一种在进行图片放缩时是错误的做法,正确做法第二种,以中心为坐标原点进行计算,并且需要注意一点的是,**当你用将浮点数截断转整,在不同的象限求x1,x2,y1,y2所做的操作是不同的。**例如 -3.5得到的是-3和-4 ,是x的x-1的值,而3.5得到的是3和4,是x和x+1的值。
附上我的代码
void resize(int srcH, int srcW, int dstH, int dstW, uchar src[], uchar dst[]) {
int ox = (srcW - 1) / 2.0;
int oy = (srcH - 1) / 2.0;
float sx = ox * 2.0 / dstW;
float sy = oy * 2.0 / dstH;
for (int i = 0; i < dstH; i++) {
for (int j = 0; j < dstW; j++) {
float rx = 1.0* j * sx - ox;
float ry = 1.0*i * sy - oy;
int x = rx;
int y = ry;
float q = 0;
int y1 = y + oy > srcH ? srcH : y + oy; y1 = y1 < 0 ? 0 : y1;
int y2 = y + oy + (y > 0 ? 1 : -1) > srcH ? srcH : y + oy + (y > 0 ? 1 : -1); y1 = y1 < 0 ? 0 : y1;
int x1 = x + ox > srcW ? srcW : x + ox; x1 = x1 < 0 ? 0 : x1;
int x2 = x + ox + (x > 0 ? 1 : -1) > srcW ? srcW : x + ox + (x > 0 ? 1 : -1); x2 = x2 < 0 ? 0 : x2;
float q1 = (x > 0 ? 1 : -1)*(x + (x > 0 ? 1 : -1) - rx)*src[y1*srcW + x1] + (x > 0 ? 1 : -1)*(rx - x)*src[y1*srcW + x2];
float q2 = (x > 0 ? 1 : -1)*(x + (x > 0 ? 1 : -1) - rx)*src[y2*srcW + x1] + (x > 0 ? 1 : -1)*(rx - x)*src[y2*srcW + x2];
q = (y > 0 ? 1 : -1)*(y + (y > 0 ? 1 : -1) - ry)*q1 + (y > 0 ? 1 : -1)*(ry - y)*q2;
//cout << rx << "\t" << ry << endl;
dst[i*dstW + j] = q;
}
}
}
请原谅我这鬼畜之极的代码,太晚了,懒得改了(我也不知道为什么会写成这样),对了,我偷懒了一点,使得边界会有像素损失。