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

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

源码下载地址:利用三次样条插值算法更改鱼眼特效的扭曲程度资源-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(id, jd)[0] = src.at(is, js)[0];
                dst.at(id, jd)[1] = src.at(is, js)[1];
                dst.at(id, jd)[2] = src.at(is, js)[2];
            }
        }
    }
}

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

三次样条插值算法

可以查看以下博文:

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

    vector dstY;
    vector 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;
     }

将图片压缩成圆形

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

利用三次样条插值调整鱼眼扭曲程度_第1张图片

你可能感兴趣的:(OpenCV,C++,QT,计算机视觉,c++,Opencv)