精华内容
下载资源
问答
  • Bilinear interpolation

    2021-09-27 11:09:19
    Bilinear interpolation Its compution procedure and provement:

    Bilinear interpolation

    Its compution procedure and provement:
    在这里插入图片描述

    展开全文
  • Bilinear Interpolation

    2019-03-17 22:08:00
    OpenCV ——双线性插值(Bilinear interpolation) [3] 双线性插值算法及需要注意事项 [4] OpenCV中resize函数五种插值算法的实现过程 转载于:https://www.cnblogs.com/leebxo/p/10549264.html

    转自:https://blog.csdn.net/xbinworld/article/details/65660665




    线性插值

    先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反过来也是一样,略):

    yy0xx0=y1y0x1x0y−y0x−x0=y1−y0x1−x0

    y=x1xx1x0y0+xx0x1x0y1y=x1−xx1−x0y0+x−x0x1−x0y1

    上面比较好理解吧,仔细看就是用x和x0,x1的距离作为一个权重,用于y0和y1的加权。双线性插值本质上就是在两个方向上做线性插值。

    双线性插值

    在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值[1]。见下图:

    这里写图片描述

    假如我们想得到未知函数 f 在点 P = (x, y) 的值,假设我们已知函数 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四个点的值。最常见的情况,f就是一个像素点的像素值。首先在 x 方向进行线性插值,得到

    这里写图片描述
    这里写图片描述

    然后在 y 方向进行线性插值,得到

    这里写图片描述

    综合起来就是双线性插值最后的结果:

    这里写图片描述
    这里写图片描述

    由于图像双线性插值只会用相邻的4个点,因此上述公式的分母都是1。opencv中的源码如下,用了一些优化手段,比如用整数计算代替float(下面代码中的*2048就是变11位小数为整数,最后有两个连乘,因此>>22位),以及源图像和目标图像几何中心的对齐
    SrcX=(dstX+0.5)* (srcWidth/dstWidth) -0.5
    SrcY=(dstY+0.5) * (srcHeight/dstHeight)-0.5

    这个要重点说一下,源图像和目标图像的原点(0,0)均选择左上角,然后根据插值公式计算目标图像每点像素,假设你需要将一幅5x5的图像缩小成3x3,那么源图像和目标图像各个像素之间的对应关系如下。如果没有这个中心对齐,根据基本公式去算,就会得到左边这样的结果;而用了对齐,就会得到右边的结果:

    这里写图片描述这里写图片描述

    cv::Mat matSrc, matDst1, matDst2;  
    
    matSrc = cv::imread("lena.jpg", 2 | 4);  
    matDst1 = cv::Mat(cv::Size(800, 1000), matSrc.type(), cv::Scalar::all(0));  
    matDst2 = cv::Mat(matDst1.size(), matSrc.type(), cv::Scalar::all(0));  
    
    double scale_x = (double)matSrc.cols / matDst1.cols;  
    double scale_y = (double)matSrc.rows / matDst1.rows;  
    
    uchar* dataDst = matDst1.data;  
    int stepDst = matDst1.step;  
    uchar* dataSrc = matSrc.data;  
    int stepSrc = matSrc.step;  
    int iWidthSrc = matSrc.cols;  
    int iHiehgtSrc = matSrc.rows;  
    
    for (int j = 0; j < matDst1.rows; ++j)  
    {  
        float fy = (float)((j + 0.5) * scale_y - 0.5);  
        int sy = cvFloor(fy);  
        fy -= sy;  
        sy = std::min(sy, iHiehgtSrc - 2);  
        sy = std::max(0, sy);  
    
        short cbufy[2];  
        cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);  
        cbufy[1] = 2048 - cbufy[0];  
    
        for (int i = 0; i < matDst1.cols; ++i)  
        {  
            float fx = (float)((i + 0.5) * scale_x - 0.5);  
            int sx = cvFloor(fx);  
            fx -= sx;  
    
            if (sx < 0) {  
                fx = 0, sx = 0;  
            }  
            if (sx >= iWidthSrc - 1) {  
                fx = 0, sx = iWidthSrc - 2;  
            }  
    
            short cbufx[2];  
            cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);  
            cbufx[1] = 2048 - cbufx[0];  
    
            for (int k = 0; k < matSrc.channels(); ++k)  
            {  
                *(dataDst+ j*stepDst + 3*i + k) = (*(dataSrc + sy*stepSrc + 3*sx + k) * cbufx[0] * cbufy[0] +   
                    *(dataSrc + (sy+1)*stepSrc + 3*sx + k) * cbufx[0] * cbufy[1] +   
                    *(dataSrc + sy*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[0] +   
                    *(dataSrc + (sy+1)*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[1]) >> 22;  
            }  
        }  
    }  
    cv::imwrite("linear_1.jpg", matDst1);  
    
    cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1);  
    cv::imwrite("linear_2.jpg", matDst2);  
    
    

    好了,本篇到这里,欢迎大家分享转载,注明出处即可。

    参考资料

    [1] 双线性插值(Bilinear Interpolation)
    [2] OpenCV ——双线性插值(Bilinear interpolation)
    [3] 双线性插值算法及需要注意事项
    [4] OpenCV中resize函数五种插值算法的实现过程

    转载于:https://www.cnblogs.com/leebxo/p/10549264.html

    展开全文
  • 该代码使用双线性插值缩小图像。 可以修改收缩因子以获得所需的收缩。
  • 双线性插值(Bilinear Interpolation

    千次阅读 2020-05-24 16:22:32
    双线性插值(Bilinear Interpolation) 文章目录双线性插值(Bilinear Interpolation)线性插值双线性插值基本原理图像双线性插值存在的问题坐标系的选择实际应用举例 Comparison of bilinear interpolation with ...

    双线性插值(Bilinear Interpolation)


    在这里插入图片描述

    Comparison of bilinear interpolation with some 1- and 2-dimensional interpolations. Black and red/yellow/green/blue dots correspond to the interpolated point and neighbouring samples, respectively. Their heights above the ground correspond to their values.

    线性插值

    已知坐标 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) ( x 1 , y 1 ) (x_1, y_1) (x1,y1),要得到 [ x 0 , x 1 ] [x_0, x_1] [x0,x1] 区间内某一位置 x x x在直线上的值。
    y − y 0 x − x 0 = y 1 − y 0 x 1 − x 0 \frac {y - y_0} {x - x_0} = \frac {y_1 - y_0} {x_1 - x_0} xx0yy0=x1x0y1y0
    由于 x x x值已知,所以可以从公式得到 y y y的值
    y = x 1 − x x 1 − x 0 y 0 + x − x 0 x 1 − x 0 y 1 y = \frac {x_1 - x} {x_1 - x_0} y_0 + \frac {x - x_0} {x_1 - x_0} y_1 y=x1x0x1xy0+x1x0xx0y1
    已知 y y y x x x的过程与以上过程相同,只是 x x x y y y要进行交换。

    x x x x 0 x_0 x0 x 1 x_1 x1的距离作为一个权重,用于 y 0 y_0 y0 y 1 y_1 y1的加权。双线性插值本质上就是在两个方向上做线性插值。

    双线性插值

    基本原理

    Suppose that we want to find the value of the unknown function f at the point (x, y). It is assumed that we know the value of f at the four points Q 11 = ( x 1 , y 1 ) Q_{11} = (x_1, y_1) Q11=(x1,y1), Q 12 = ( x 1 , y 2 ) Q_{12} = (x_1, y_2) Q12=(x1,y2), Q 21 = ( x 2 , y 1 ) Q_{21} = (x_2, y_1) Q21=(x2,y1), and Q 22 = ( x 2 , y 2 ) Q_{22} = (x_2, y_2) Q22=(x2,y2).

    最常见的情况,f就是一个像素点的像素值
    We first do linear interpolation in the x-direction. This yields
    f ( R 1 ) = f ( x , y 1 ) ≈ x 2 − x x 2 − x 1 f ( Q 11 ) + x − x 1 x 2 − x 1 f ( Q 21 ) , f ( R 2 ) = f ( x , y 2 ) ≈ x 2 − x x 2 − x 1 f ( Q 12 ) + x − x 1 x 2 − x 1 f ( Q 22 ) . {\displaystyle {\begin{aligned}f(R_1)=f(x,y_{1})&\approx {\frac {x_{2}-x}{x_{2}-x_{1}}}f(Q_{11})+{\frac {x-x_{1}}{x_{2}-x_{1}}}f(Q_{21}),\\f(R_2)=f(x,y_{2})&\approx {\frac {x_{2}-x}{x_{2}-x_{1}}}f(Q_{12})+{\frac {x-x_{1}}{x_{2}-x_{1}}}f(Q_{22}).\end{aligned}}} f(R1)=f(x,y1)f(R2)=f(x,y2)x2x1x2xf(Q11)+x2x1xx1f(Q21),x2x1x2xf(Q12)+x2x1xx1f(Q22).
    We proceed by interpolating in the y-direction to obtain the desired estimate:
    f ( x , y ) ≈ y 2 − y y 2 − y 1 f ( R 1 ) + y − y 1 y 2 − y 1 f ( R 2 ) = y 2 − y y 2 − y 1 ( x 2 − x x 2 − x 1 f ( Q 11 ) + x − x 1 x 2 − x 1 f ( Q 21 ) ) + y − y 1 y 2 − y 1 ( x 2 − x x 2 − x 1 f ( Q 12 ) + x − x 1 x 2 − x 1 f ( Q 22 ) ) = 1 ( x 2 − x 1 ) ( y 2 − y 1 ) ( f ( Q 11 ) ( x 2 − x ) ( y 2 − y ) + f ( Q 21 ) ( x − x 1 ) ( y 2 − y ) + f ( Q 12 ) ( x 2 − x ) ( y − y 1 ) + f ( Q 22 ) ( x − x 1 ) ( y − y 1 ) ) = 1 ( x 2 − x 1 ) ( y 2 − y 1 ) [ x 2 − x x − x 1 ] [ f ( Q 11 ) f ( Q 12 ) f ( Q 21 ) f ( Q 22 ) ] [ y 2 − y y − y 1 ] . {\displaystyle {\begin{aligned}f(x,y)&\approx {\frac {y_{2}-y}{y_{2}-y_{1}}}f(R_{1})+{\frac {y-y_{1}}{y_{2}-y_{1}}}f(R_{2})\\&={\frac {y_{2}-y}{y_{2}-y_{1}}}\left({\frac {x_{2}-x}{x_{2}-x_{1}}}f(Q_{11})+{\frac {x-x_{1}}{x_{2}-x_{1}}}f(Q_{21})\right)+{\frac {y-y_{1}}{y_{2}-y_{1}}}\left({\frac {x_{2}-x}{x_{2}-x_{1}}}f(Q_{12})+{\frac {x-x_{1}}{x_{2}-x_{1}}}f(Q_{22})\right)\\&={\frac {1}{(x_{2}-x_{1})(y_{2}-y_{1})}}{\big (}f(Q_{11})(x_{2}-x)(y_{2}-y)+f(Q_{21})(x-x_{1})(y_{2}-y)+f(Q_{12})(x_{2}-x)(y-y_{1})+f(Q_{22})(x-x_{1})(y-y_{1}){\big )}\\&={\frac {1}{(x_{2}-x_{1})(y_{2}-y_{1})}}{\begin{bmatrix}x_{2}-x&x-x_{1}\end{bmatrix}}{\begin{bmatrix}f(Q_{11})&f(Q_{12})\\f(Q_{21})&f(Q_{22})\end{bmatrix}}{\begin{bmatrix}y_{2}-y\\y-y_{1}\end{bmatrix}}.\end{aligned}}} f(x,y)y2y1y2yf(R1)+y2y1yy1f(R2)=y2y1y2y(x2x1x2xf(Q11)+x2x1xx1f(Q21))+y2y1yy1(x2x1x2xf(Q12)+x2x1xx1f(Q22))=(x2x1)(y2y1)1(f(Q11)(x2x)(y2y)+f(Q21)(xx1)(y2y)+f(Q12)(x2x)(yy1)+f(Q22)(xx1)(yy1))=(x2x1)(y2y1)1[x2xxx1][f(Q11)f(Q21)f(Q12)f(Q22)][y2yyy1].
    Note that we will arrive at the same result if the interpolation is done first along the y direction and then along the x direction.

    在这里插入图片描述

    图像双线性插值

    在图像双线性插值中,有时候我们需要知道一个位置的像素值,而这个位置恰好不在像素点上(对应坐标一般来说不是整数,而非整数的坐标是无法在图像这种离散数据上使用的),因此,要用该位置周围的4个像素点的值来估计该点的值,因为只会用相邻的4个点,所以上述公式的分母都是1。

    In computer vision and image processing, bilinear interpolation is used to resample images and textures. An algorithm is used to map a screen pixel location to a corresponding point on the texture map. A weighted average of the attributes (color, transparency, etc.) of the four surrounding texels is computed and applied to the screen pixel. This process is repeated for each pixel forming the object being textured. [2]

    When an image needs to be scaled up, each pixel of the original image needs to be moved in a certain direction based on the scale constant. However, when scaling up an image by a non-integral scale factor, there are pixels (i.e., holes) that are not assigned appropriate pixel values. In this case, those holes should be assigned appropriate RGB or grayscale values so that the output image does not have non-valued pixels.

    Bilinear interpolation can be used where perfect image transformation with pixel matching is impossible, so that one can calculate and assign appropriate intensity values to pixels. Unlike other interpolation techniques such as nearest-neighbor interpolation and bicubic interpolation, bilinear interpolation uses values of only the 4 nearest pixels, located in diagonal directions from a given pixel, in order to find the appropriate color intensity values of that pixel.

    Bilinear interpolation considers the closest 2 × 2 neighborhood of known pixel values surrounding the unknown pixel’s computed location. It then takes a weighted average of these 4 pixels to arrive at its final, interpolated value.[3]

    存在的问题

    坐标系的选择

    要通过双线性插值的方法算出dst中每一个像素点的像素值,是通过dst像素点的坐标对应到src图像当中的坐标;然后通过双线性插值的方法算出src中相应坐标的像素值。

    坐标对应关系:

    ➢按比例对应:

    S r c X = ( d s t X ) ∗ ( s r c W i d t h / d s t W i d t h ) SrcX=(dstX)*(srcWidth/dstWidth) SrcX=(dstX)(srcWidth/dstWidth)

    S r c Y = ( d s t Y ) ∗ ( s r c H e i g h t / d s t H e i g h t ) SrcY=(dstY)*(srcHeight/dstHeight) SrcY=(dstY)(srcHeight/dstHeight)

    如果源图像和目标图像的原点(0,0)均选择左上角,然后根据插值公式计算目标图像每点像素,假设你需要将一幅5x5的图像缩小成3x3,那么源图像和目标图像各个像素之间的对应关系如下:

    在这里插入图片描述

    只画了一行,用做示意,从图中可以很明显的看到,如果选择左上角为原点(0,0),那么最右边和最下边的像素实际上并没有参与计算,而且目标图像的每个像素点计算出的灰度值也相对于源图像偏左偏上。那么,让坐标加1或者选择右下角为原点怎么样呢?很不幸,还是一样的效果,不过这次得到的图像将偏右偏下。最好的方法就是,两个图像的几何中心重合,并且目标图像的每个像素之间都是等间隔的,并且都和两边有一定的边距。如下面的做法。

    ➢按比例对应最后一列没有办法参与计算,所以按几何中心对应:

    S r c X + 0.5 = ( d s t X + 0.5 ) ∗ ( s r c W i d t h / d s t W i d t h ) SrcX+0.5=(dstX+0.5)*(srcWidth/dstWidth) SrcX+0.5=(dstX+0.5)(srcWidth/dstWidth)

    S r c Y + 0.5 = ( d s t Y + 0.5 ) ∗ ( s r c H e i g h t / d s t H e i g h t ) SrcY+0.5=(dstY+0.5)*(srcHeight/dstHeight) SrcY+0.5=(dstY+0.5)(srcHeight/dstHeight)

    对于图片的几何中心,希望原图片和当前图片的几何中心重叠

    原 图 片 大 小 − 1 2 + 0.5 = ( 当 前 图 片 大 小 − 1 2 + 0.5 ) ∗ ( 原 图 片 大 小 当 前 图 片 大 小 ) \frac {原图片大小 - 1} {2} + 0.5 = \left( \frac {当前图片大小 - 1} {2} + 0.5 \right)*\left( \frac {原图片大小} {当前图片大小} \right) 21+0.5=(21+0.5)()

    在这里插入图片描述

    注:几何中心对应中,如果索引是负值,实际上是从一行像素值的末端取值

    实际应用举例

    x ( p ) = ∑ q G ( q , p ) ⋅ x ( q ) x(p) = \sum_{q} G(q, p)\cdot x(q) x(p)=qG(q,p)x(q)

    where p p p denotes an arbitrary (fractional) location, q q q enumerates all integral spatial locations in the feature map x x x, and G ( ⋅ , ⋅ ) G(\cdot, \cdot) G(,) is the bilinear interpolation kernel. Note that G G G is two dimensional. It is separated into two one dimensional kernels as
    G ( q , p ) = g ( q x , p x ) ⋅ g ( q y , p y ) G(q, p) = g(q_x, p_x) \cdot g(q_y, p_y) G(q,p)=g(qx,px)g(qy,py)
    where g ( a , b ) = max ⁡ ( 0 , 1 − ∣ a − b ∣ ) g(a,b)=\max(0, 1- \vert a-b\vert) g(a,b)=max(0,1ab)

    els as
    G ( q , p ) = g ( q x , p x ) ⋅ g ( q y , p y ) G(q, p) = g(q_x, p_x) \cdot g(q_y, p_y) G(q,p)=g(qx,px)g(qy,py)
    where g ( a , b ) = max ⁡ ( 0 , 1 − ∣ a − b ∣ ) g(a,b)=\max(0, 1- \vert a-b\vert) g(a,b)=max(0,1ab)

    该公式计算很快,因为只有位置 p p p周围的4个像素点的 G ( q , p ) G(q, p) G(q,p)值才不为0。

    展开全文
  • 线性插值,双线性插值Bilinear Interpolation算法 https://blog.csdn.net/xbinworld/article/details/65660665 https://blog.csdn.net/xjz18298268521/article/details/51220576 图像处理常用插值方法总结 ...

     

    线性插值,双线性插值Bilinear Interpolation算法

    https://blog.csdn.net/xbinworld/article/details/65660665

    https://blog.csdn.net/xjz18298268521/article/details/51220576

    图像处理常用插值方法总结

    https://cloud.tencent.com/developer/article/1082360

    http://www.1zlab.com/wiki/python-opencv-tutorial/opencv-interpolation-algrithm/

    1前言

    关于中心对齐,网上找到的资料都是错的,只好参考一下自己写吧。

     

    2线性插值

    这里写图片描述

    线性插值,即已知两点(x0,y0),(x1,y1)和之间某点的一维坐标x,求该点的另一维y。

    例如:

    (x0,y0)=(2,6),

    (x1,y1)=(5,15)

    求:

    (x, y)=(3, ?)

    公式1:斜率方式

    y=y_0 + \Delta x \cdot k \\ \\ \\ =y_0+(x-x_0)\frac{y_1 - y_0}{x_1 - x_0}

    =6+1*\frac{9}{3}=9

    公式2:距离比例方式

    y=\frac{x_1 - x}{x_1 - x_0}y_0+\frac{x - x_0}{x_1 - x_0}y_1

    =\frac{5 - 3}{5 - 2}\cdot 6+\frac{3 - 2}{5 - 2}\cdot 15 = 4+5=9

    小结

    两个公式结果相同,实际上两者是等价的。

    y=\frac{x_1 - x}{x_1 - x_0}y_0+\frac{x - x_0}{x_1 - x_0}y_1 \\ \\ \\ =\frac{x_1 - x+x_0-x_0}{x_1 - x_0}y_0+\frac{x - x_0}{x_1 - x_0}y_1 \\ \\ \\ =\frac{x_1-x_0}{x_1 - x_0}y_0+\frac{- x+x_0}{x_1 - x_0}y_0+\frac{x - x_0}{x_1 - x_0}y_1\\ \\ \\=y_0+\frac{x - x_0}{x_1 - x_0}(y_1-y_0)

     

    3双线性插值法

    原理

    双线性内插法是利用待求象素四个邻象素的灰度在两个方向上作线性内插,如下图所示:

    已知点四个:f(i,j), f(i+1,j),  f(i,j+1), f(i+1,j+1)

    待求点一个:f(i+u,j+v)

    图示四点是相邻的,实际上四点不相邻也没有关系。下面推导。

    公式

    clip_image001

    已知:四点(x1,y1,z11),(x2,y1,z21),(x1,y2,z12),(x2,y2,z22),和之间某点的一维坐标(x,y),

    求:该点的灰度z。

    首先在 x 方向进行线性插值,得到

    然后在 y 方向进行线性插值,得到

    这样就得到所要的结果 f(xy),

    理解

    这个式子怎么理解呢?

    拿第一项说。

    分母{(x_2-x_1)(y_2-y_1)}实际是计算了四点围成的矩形面积。

    第一项中的\frac{f(Q_{11})}{(x_2-x_1)(y_2-y_1)}实际上是计算点f(Q_{11})对平均单位面积的贡献

    乘数{(x_2-x)(y_2-y)}是计算了点(x,y)到f(Q_{11})的距离加权。由于越近,贡献越大,因此使用了(x_2,y_2)衡量。

    到这一步,是不是可以直接写出表达式了?

     

    单元格内的简化

    如果四点正好是单元格上的四点,则公式如下:

    f(x,y) \approx f(0,0) \, (1-x)(1-y) + f(1,0) \, x(1-y) + f(0,1) \, (1-x)y + f(1,1) xy.

    f(x,y) \approx \begin{bmatrix}1-x & x \end{bmatrix} \begin{bmatrix}f(0,0) & f(0,1) \\f(1,0) & f(1,1) \end{bmatrix} \begin{bmatrix}1-y \\y \end{bmatrix}

    这种插值方法的结果通常是线性的,线性插值的结果与插值的顺序无关。首先进行 y 方向的插值,然后进行 x 方向的插值,所得到的结果是一样的。

     

    4中心对齐

    在成熟库中,例如opencv和matlab,通常会有中心对齐等精操作和整数计算代替float等加速。

    假如要将5×5的图片resize成3×3。

       

    此处参考:含python代码,只是原文是3×3转5×5

    https://zhuanlan.zhihu.com/p/49832888

    要通过双线性插值的方法算出dst中每一个像素点的像素值,是通过dst像素点的坐标对应到src图像当中的坐标;然后通过双线性插值的方法算出src中相应坐标的像素值。

    原点对齐方法不可行

    坐标对应关系:

    ➢按比例对应:

    SrcX=(dstX)* (srcWidth/dstWidth)

    SrcY=(dstY) * (srcHeight/dstHeight)

    按照网上一些博客上写的,源图像和目标图像的原点(0,0)均选择左上角,然后根据插值公式计算目标图像每点像素,假设你需要将一幅5x5的图像缩小成3x3,那么源图像和目标图像各个像素之间的对应关系如下:

    只画了一行,用做示意,从图中可以很明显的看到,如果选择右上角为原点(0,0),那么最右边和最下边的像素实际上并没有参与计算,而且目标图像的每个像素点计算出的灰度值也相对于源图像偏左偏上。

    那么,让坐标加1或者选择右下角为原点怎么样呢?很不幸,还是一样的效果,不过这次得到的图像将偏右偏下。

    最好的方法就是,两个图像的几何中心重合,并且目标图像的每个像素之间都是等间隔的,并且都和两边有一定的边距,这也是matlab和openCV的做法。

     

    几何中心对齐:浮点坐标

    计算目标图像像素的单元格的几何中心在原图上的浮点坐标。

    图像双线性插值只会用相邻的4个点,只需要确定x0,x1,y0,y1即可。

    下面公式以计算x0,x1为例。

    src_x = (dstX+0.5)* (srcWidth/dstWidth)  # 找到目标图上像素格的几何中心在原图的浮点坐标

    x0 = src_x - 0.5 # 计算中心点的左边的浮点坐标

    x1 = src_x + 0.5 # 计算中心点的右边的浮点坐标

    几何中心对应原理如下图所示。只画出一行示意。

    左侧的红色框表示像素dst[0]的中心在src图上的左边和右边的。是浮点数。

    (同理,右侧的红色框表示像素dst[2]的中心在src图上的左边和右边的。是浮点数。)

    同理,按列,可以计算出上下边界y0, y1。

     

    找原图上的坐标:整形坐标

    以左侧边框为例,找到浮点数边界后,由于像素坐标都是整数存在的,如何找到相邻的四个坐标呢?

    就是取整。

    (np.floor(x0), np.floor(y0))就是点1的坐标

    (np.floor(x0)+1, np.floor(y1)+1)就是点2的坐标

    对应原理图,dst[0]的int[x0]即原图像素0。

    但是不能超过src的边界同时坐标必须是整型,综合起来有:

    src_x_0 = int(np.floor(srcX))
    src_y_0 = int(np.floor(srcY))
    src_x_1 = min(src_x_0 + 1, src_w - 1)
    src_y_1 = min(src_y_0 + 1, src_h - 1)

    即找到了四个点:(x0,y0),(x1,y0),(x0,y1),(x1,y1)。然后就可以双线性插值了。

    ============================================================

    代码示例:

    按channel循环遍历每一个坐标点:

    其中

    scale_x=src_x/dst_x

    完整代码:

    # use bilinear
    def bilinear(src, dst_h, dst_w):
        src_h, src_w = src.shape[:2]
        scale_x = src_w/dst_w
        scale_y = src_h/dst_h
    
        channel = src.shape[2]
        dst = np.zeros([dst_h, dst_w, channel])
        for c in range(channel):
            for dst_y in range(dst_h):  # 对height循环
                for dst_x in range(dst_w):  # 对width循环
                    if dst_x == dst_w-1:
                        a = 1
                    # 目标在源上的坐标
                    src_x = (dst_x + 0.5) * scale_x - 0.5
                    src_y = (dst_y + 0.5) * scale_y - 0.5
    
                    # 计算在源图上四个近邻点的位置
                    src_x_0 = max(int(np.floor(src_x)), 0)
                    src_y_0 = max(int(np.floor(src_y)), 0)
                    src_x_1 = min(src_x_0 + 1, src_w - 1)
                    src_y_1 = min(src_y_0 + 1, src_h - 1)
    
                    # 双线性插值
                    value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, c] + \
                             (src_x - src_x_0) * src[src_y_0, src_x_1, c]
                    value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, c] + \
                             (src_x - src_x_0) * src[src_y_1, src_x_1, c]
                    dst[dst_y, dst_x, c] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)
    
        return dst

    但是,这样处理会有黑边。

    改进代码如下:

    # use bilinear
    def bilinear(src, dst_h, dst_w):
        src_h, src_w = src.shape[:2]
        scale_x = src_w/dst_w
        scale_y = src_h/dst_h
    
        channel = src.shape[2]
        dst = np.zeros([dst_h, dst_w, channel])
        for c in range(channel):
            for dst_y in range(dst_h):  # 对height循环
                for dst_x in range(dst_w):  # 对width循环
                    if dst_x == dst_w-1:
                        a = 1
                    # 目标在源上的坐标
                    src_x = (dst_x + 0.5) * scale_x - 0.5
                    src_y = (dst_y + 0.5) * scale_y - 0.5
    
                    # 计算在源图上四个近邻点的位置
                    src_x_0 = max(int(np.floor(src_x)), 0)
                    src_y_0 = max(int(np.floor(src_y)), 0)
                    src_x_1 = min(src_x_0 + 1, src_w - 1)
                    src_y_1 = min(src_y_0 + 1, src_h - 1)
    
                    # 处理黑边问题(插值后边界值为0或近0)
                    # 处理方式是复制边界值
                    # x_0和x_1一定不能相等,同理y_0和y_1一定不能相等,否则会出现黑边
                    if src_x_0 == src_x_1 and src_x_0 == src_w - 1:
                        src_x_0 = max(src_x_0-1, 0)
                    if src_y_0 == src_y_1 and src_y_0 == src_h - 1:
                        src_y_0 = max(src_y_0-1, 0)
    
                    # 双线性插值
                    value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, c] + \
                             (src_x - src_x_0) * src[src_y_0, src_x_1, c]
                    value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, c] + \
                             (src_x - src_x_0) * src[src_y_1, src_x_1, c]
                    dst[dst_y, dst_x, c] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)
    
        return dst

     

     

    展开全文
  • 三十分钟理解:线性插值,双线性插值Bilinear Interpolation算法.pdf
  • Bilinear interpolation】双线性插值详解(转)[组图]08-08栏目:技术TAG:双线性插值双线性插值【Bilinear interpolation】双线性插值详解(转)最近在做视频拼接的项目,里面用到了图像的单应性矩阵变换,在最后的...
  • A Novel Approach to Real-time Bilinear Interpolation
  • Through this LAB, I have known the principle and formula of nearest neighbor interpolation and bilinear interpolation, and Use nearest neighbor interpolation and bilinear interpolation ...
  • 双线性插值(Bilinear Interpolation)

    千次阅读 2016-02-24 13:26:34
    双线性滤波 双线性插值(Bilinear Interpolation)
  • 【项目代码】影像壓縮4:2:0,以及bilinear interpolation的matlab code.rar
  • bilinear interpolation 是先在一个方向用linear interpolation。再在另外一个方向用linear interpolation。虽然每一步在采样值和方向上都是线性的。但是整体不是线性的。 看算法: 如果我们不知道 functio...
  • 线性插值(linear interpolation) 如下图有A,B两点,A(x0,y0),B(x1,y1)。在A和B之间线性插入一点C,这个是一维的,只要画个图...双线性插值(Bilinear interpolation) 双线性插值跟线性插值比,复杂一点,因为...
  • 文章目录DefinitionAlgorithmAlternative algorithmUnit ...In mathematics, bilinear interpolation is an extension of linear interpolation for interpolating functions of two variables (e.g. x
  • 双线性插值(Bilinear Interpolation),又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。图像的双线性插值放大算法中,目标图像中新...
  • 原文:An Alternative Bilinear Interpolation Method Between Spherical Grids 摘要 在地球科学研究中,传统的双线性插值已被广泛用于球体表面逻辑矩形网格之间的重新映射。最近,已经提出了包括测地线网格在内的...
  • interpolation": "bilinear", "name": "upscore_feat1", "size": [ 2, 2 ], "trainable": true }, "inbound_nodes": [ [ [ "score_feat1",...
  • Bilinear interpolation】双线性插值详解(转) 最近在做视频拼接的项目,里面用到了图像的单应性矩阵变换,在最后的图像重映射,由于目标图像的坐标是非整数的,所以需要用到插值的方法,用...
  • 双线性插值法(Bilinear interpolation)

    千次阅读 2016-04-10 15:00:11
    双线性插值法(Bilinear interpolation)是利用待求象素反变换到原图像对应的浮点坐标,邻近的四个象素在两个方向上作线性内插。四邻近像素值的加权平均即为待测点像素值,计算权重反比于浮点在双线性方向上的映射距离...
  • Zooming and Shrinking Images by Bilinear Interpolation Objective To manipulate another technique of zooming and shrinking images by bilinear interpolation. Main requirements:
  • 实验要求: Zooming and Shrinking Images by Bilinear Interpolation ... To manipulate another technique of zooming and shrinking images by bilinear interpolation. Main requiremen...
  • 线性插值 先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算...OpenCV ——双线性插值(Bilinear interpolation) [3] 双线性插值算法及需要注意事项 [4] OpenCV中resize函数五种插值算法的实现过程
  • 雙線性插值 Bilinear Interpolation 二、​最近鄰居插值 Nearest neighbor Interpolation 最近鄰居法的理念其實很簡單,顧名思義: 今天有一個點的數值不知道該填多少進去,去找離你最近的鄰居看它是多少你就填...
  • 线性插值 先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反过来也是一样,略): 上面比较好理解吧,仔细看就是用x和x0,x1的距离作为一个权重,用于y0和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,541
精华内容 2,216
关键字:

bilinearinterpolation