本文利用三次样条插值算法,改变鱼眼扭曲程度。效果如下图所示:
源码下载地址:利用三次样条插值算法更改鱼眼特效的扭曲程度资源-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是调用三次样条插值函数计算某点的对应值,详情可查看源码。
三次样条插值算法
可以查看以下博文:
三次样条插值https://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;
}
将图片压缩成圆形
通过点击转化成圆形按钮可实现将图片转化成圆形: