3种插值算法C++代码实现

最近邻插值算法

//最近邻插值
Vec3b INTER_NEAREST(double row, double col, const Mat& img) {
    int r = int(row + 0.5);
    int c = int(col + 0.5);
    Vec3b vec3b;
    if (r < 0 || r >= img.rows || c < 0 || c >= img.cols)
        vec3b[0] = vec3b[1] = vec3b[2] = 0;
    else
        vec3b = img.at<Vec3b>(r, c);
    return vec3b;
}

最近邻插值算法

//双线性插值
Vec3b INTER_LINEAR(double row, double col, const Mat& img) {
    Vec3b vec3b;
    double x = col, y = row;
    int x1 = int(col), y1 = int(row);
    if (y1 < 0 || y1 >= img.rows || x1 < 0 || x1 >= img.cols) {
        vec3b[0] = vec3b[1] = vec3b[2] = 0;
        return vec3b;
    }
    int x2 = min(x1 + 1, img.cols - 1), y2 = min(y1 + 1, img.rows - 1);
    Vec3b q11 = img.at<Vec3b>(y1, x1);
    Vec3b q12 = img.at<Vec3b>(y2, x1);
    Vec3b q21 = img.at<Vec3b>(y1, x2);
    Vec3b q22 = img.at<Vec3b>(y2, x2);

    for (int i = 0; i < 3; ++i) {
        double r1 = (x2 - x) * q11[i] / (x2 - x1) + (x - x1) * q21[i] / (x2 - x1);
        double r2 = (x2 - x) * q12[i] / (x2 - x1) + (x - x1) * q22[i] / (x2 - x1);
        double p = (y2 - y) * r1 / (y2 - y1) + (y - y1) * r2 / (y2 - y1);
        vec3b[i] = saturate_cast<uchar>(p);
    }
    return vec3b;
}

BiCubic插值算法

//BiCubic插值
Vec3b INTER_CUBIC(double row, double col, const Mat& img, double a) {
    Vec3b vec3b;
    int x = int(col + 0.5), y = int(row + 0.5);
    if (y < 0 || y >= img.rows || x < 0 || x >= img.cols) {
        vec3b[0] = vec3b[1] = vec3b[2] = 0;
        return vec3b;
    }

    static auto cubic_func = [&](double x)->double {
        if (abs(x) <= 1) return (a + 2) * pow(abs(x), 3) - (a + 3) * pow(abs(x), 2) + 1;
        if (abs(x) < 2) return a * pow(abs(x), 3) - 5 * a * pow(x, 2) + 8 * a * abs(x) - 4 * a;
        return 0.0;
    };

    vector<int>actions = { -1,0,1 };

    for (int k = 0; k < 3; ++k) {
        double tmp = 0;
        for (int i = 0; i < actions.size(); ++i) {
            for (int j = 0; j < actions.size(); ++j) {
                int x1 = min(max(0, x + actions[i]), img.cols);
                int y1 = min(max(0, y + actions[j]), img.rows);
                Vec3b f = img.at<Vec3b>(y1, x1);
                tmp += f[k] * cubic_func(x - x1) * cubic_func(y - y1);
            }
        }
        vec3b[k] = tmp;
    }
    return vec3b;
}
  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的样条插值算法C++实现,其中使用了STL的vector和map数据结构: ```cpp #include <iostream> #include <vector> #include <map> using namespace std; // 样条插值算法 double spline_interpolation(map<double, double>& data, double x) { // 首先将数据点按照x值从小到大排序 vector<double> x_data, y_data; for (auto it = data.begin(); it != data.end(); it++) { x_data.push_back(it->first); y_data.push_back(it->second); } // 计算一阶导数 int n = x_data.size(); vector<double> h(n), b(n), u(n), v(n), z(n); for (int i = 1; i < n; i++) { h[i] = x_data[i] - x_data[i-1]; b[i] = (y_data[i] - y_data[i-1]) / h[i]; } // 利用三边界条件求解二阶导数 u[1] = 0; v[1] = 0; u[n-1] = 0; v[n-1] = 0; for (int i = 2; i < n-1; i++) { u[i] = h[i] / (h[i] + h[i+1]); v[i] = 1 - u[i]; z[i] = 3 * (u[i] * b[i-1] + v[i] * b[i]); } z[1] = -z[2]; z[n-1] = -z[n-2]; // 利用二阶导数和已知条件求解样条函数 int k = 0; for (int i = 1; i < n; i++) { if (x >= x_data[i-1] && x <= x_data[i]) { k = i; break; } } double y = y_data[k-1] + b[k] * (x - x_data[k-1]) + (z[k] / 6.0) * pow(x - x_data[k-1], 3) / h[k] - (z[k-1] / 6.0) * pow(x - x_data[k], 3) / h[k] + (y_data[k] - y_data[k-1] - z[k-1] * h[k] / 6.0 - z[k] * h[k] / 3.0) * (x - x_data[k-1]) / h[k]; return y; } int main() { // 构造数据点 map<double, double> data; data[1.0] = 1.0; data[2.0] = 3.0; data[3.0] = 2.0; data[4.0] = 4.0; // 对x=2.5的值进行插值 double x = 2.5; double y = spline_interpolation(data, x); cout << "f(" << x << ") = " << y << endl; return 0; } ``` 在上述代码中,我们首先将输入的数据点按照x值从小到大排序,然后计算一阶导数,利用三边界条件求解二阶导数,接着利用二阶导数和已知条件求解样条函数,在最后得到x=2.5时的插值结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值