ImageWarping--反距离加权插值(IDW)方法实现及报告

反距离加权插值(IDW)

根据给定的控制点对和控制点的位移矢量(方向和距离),实现图像每一个像素点的位移。反距离加权插值的方法是通过得到每一个像素点和选定控制点对的逼近关系,以及相对应的权重关系,求得像素点相对应的变化关系,逼近函数可以理解为对像素点p的影响程度,而权重函数则可以看成是对距离的权重,距离越远,权重越小。

主函数
该函数f(p)传入一个像素点的坐标,通过已选定的控制点实现计算插值。f函数返回像素点坐标,fi函数为逼近函数,即
逼近函数
这里T的求解我未进行方程组的计算求解,T是一个2*2矩阵,T可以取近似值1。将控制点数据代入可以求出每一个局部插值函数。
而wi权重函数,理解为对距离越远,权重越小,这里通过
权重函数
这里d(p,pi)为p和pi的距离,指数μ可以取>0的数,这里测试取2最优。通过公式求取权重函数,求和体现多组控制点共同产生影响。

部分代码

我通过c++对IDW方法进行编写,通过封装IDW类的方法实现。类的接口如下:

```
class ImW_IDW
{
public:
    ImW_IDW();
    ImW_IDW(vector<QPoint> &m_point_p, vector<QPoint> &m_point_q);

public:
    QPoint f_func(QPoint p);

private:
    double wi_func(QPoint p, int i);
    double delta(QPoint p, QPoint pi);
    double distance(QPoint p, QPoint pi);
    QPoint fi_func(QPoint p, int i);


private:
    double u;
    vector<QPoint> p_points;
    vector<QPoint> q_points;

};

对于各部分接口的实现:

#include "ImW_IDW.h"
#include <math.h>

ImW_IDW::ImW_IDW()
{

}

ImW_IDW::ImW_IDW(vector<QPoint> &m_point_p, vector<QPoint> &m_point_q)
{
    u = 2.0;
    p_points = m_point_p;
    q_points = m_point_q;
}

double ImW_IDW::wi_func(QPoint p, int i)
{
    double tmp_sum = 0;
    double result;

    if (p == p_points[i])
        return 1;

    for (size_t j=0; j < p_points.size(); j++)
    {
        tmp_sum += delta(p, p_points[j]);
    }

    result = delta(p, p_points[i])/tmp_sum;
    return result;
}

double ImW_IDW::distance(QPoint p, QPoint pi)
{
    double m_result;

    //在这里返回不开方的值精度会更高吧
    m_result =(p.rx()-pi.rx())*(p.rx()-pi.rx()) + (p.ry()-pi.ry())*(p.ry()-pi.ry()) ;
    return m_result;
}

double ImW_IDW::delta(QPoint p, QPoint pi)
{
    double m_result;

    m_result = pow(1.0/distance(p, pi), u/2.0);
    return m_result;
}

QPoint ImW_IDW::fi_func(QPoint p, int i)
{
    QPoint result = q_points[i];

    result.rx() += (p.rx()-p_points[i].rx());
    result.ry() += (p.ry()-p_points[i].ry());

    return result;
}

QPoint ImW_IDW::f_func(QPoint p)
{
    QPoint result(0, 0);
    double x = 0, y = 0;

    for (size_t i=0; i < p_points.size(); i++)
    {
        x += fi_func(p, i).rx() * wi_func(p, i); 
        y += fi_func(p, i).ry() * wi_func(p, i);
    }

    result.rx() = x;
    result.ry() = y;

    return result;
}

有些需要注意的点,我在这里使用的是qt的编程,由于坐标点及像素点都是整数值,但我们计算时需要的步骤全是浮点型,所以一定要注意使用double型进行计算,如果出现图像结果非常模糊的情况,则需要检查你自己的函数中是否不小心使用了整形计算,导致精度丢失。

实现结果

挤压挤压图
拉伸拉伸
四角挤压死角挤压
旋转这里写图片描述

问题后期工作

这里出现像素丢失问题,我认为是计算上的误差以及未优化的问题。当然最重要的应该是图像拉伸时出现的像素丢失。这里后期需要我们用其他方法去补全所有像素,在后期的博客中会提到。

参考资料:C&G95_Image Warping with Scattered Data Interpolation
整个工作的完成基本上是参考如上论文的,从网上可以很方便找到他。由于我是初学者,实验报告的写作上还有很多问题,以及实现代码也有很多不够优的地方,希望谅解。也希望能多提意见,与我交流。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值