利用三次样条插值调整鱼眼扭曲程度

23 篇文章 1 订阅
19 篇文章 1 订阅

         本文利用三次样条插值算法,改变鱼眼扭曲程度。效果如下图所示:

源码下载地址:利用三次样条插值算法更改鱼眼特效的扭曲程度资源-CSDN文库

(说明:源码基于QT和opencv )

主要代码

鱼眼扭曲

void fisheye(const Mat &src, Mat &dst)
{
    dst.create(src.rows, src.cols, CV_8UC3);
    dst.setTo(0);

    if (srcX.size() == 0 || srcX.size() != dstY.size() || cubicCoeffs == nullptr)
        return;

    Point2f center;
    center.x = src.cols / 2.0;
    center.y = src.rows / 2.0;
    double rr = sqrt(center.x * center.x + center.y * center.y);
    for (int id = 1; id < src.rows - 1; id++) {
        for (int jd = 1; jd < src.cols - 1; jd++) {
            double xd = 1.0 * (jd - center.x) / rr;//nomalize to -1 --- 1
            double yd = 1.0 * (id - center.y) / rr;
            double rd = sqrt(xd * xd + yd * yd);
            double phid = atan2(yd, xd);
            //double xs = asin(rd) * 2 / PI * cos(phid) * rr * sqrt(2);
            //double ys = asin(rd) * 2 / PI * sin(phid) * rr * sqrt(2);

            double nr = 0;
            if (rd>0 && rd <= 1)
                cubicSpline.cubicSplineInterpolation2(cubicCoeffs, srcX, rd, nr);
            double xs = nr * cos(phid) * rr * sqrt(2);
            double ys = nr * sin(phid) * rr * sqrt(2);

            int is = round(ys +  center.y);
            int js = round(xs + center.x);
            if (is > dst.rows - 1 || is < 1 || js>dst.cols - 1 || js < 1){
                //is = id;
                //js = jd;
            }
            else{
                dst.at<Vec3b>(id, jd)[0] = src.at<Vec3b>(is, js)[0];
                dst.at<Vec3b>(id, jd)[1] = src.at<Vec3b>(is, js)[1];
                dst.at<Vec3b>(id, jd)[2] = src.at<Vec3b>(is, js)[2];
            }
        }
    }
}

其中cubicSpline.cubicSplineInterpolation2是调用三次样条插值函数计算某点的对应值,详情可查看源码。

三次样条插值算法

可以查看以下博文:

三次样条插值icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/134171633插值初始化如下:

    vector<double> dstY;
    vector<double> srcX;

    //srcX(not change after initialize)
    srcX.push_back(0.0f);
    srcX.push_back(0.2f);
    srcX.push_back(0.4f);
    srcX.push_back(0.6f);
    srcX.push_back(0.8f);
    srcX.push_back(1.0f);

    //dstY
    for (int i = 0;i < (int)srcX.size();i++)
    {
        float v = asin(srcX.at(i)) * 2 / PI;
        if (v > 1.0f)
            v = 1.0f;
     }

将图片压缩成圆形

通过点击转化成圆形按钮可实现将图片转化成圆形:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

视图猿人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值