You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对图像矩形ROI区域实现自然的抛物线曲线形变

抛物线ROI形变调整方案

核心问题排查

  • 映射逻辑错误:当前使用正向映射,容易出现像素空洞、重叠问题,应该改为反向映射:遍历输出图像的每个坐标,反向计算对应原图的采样位置,保证每个输出像素都有有效值
  • 公式变量匹配错误:你需要的是「垂直中线(ROI水平方向中点)处弯曲最大,向左右两侧衰减」,所以偏移量的核心变量应该是x和ROI水平中点的距离,而非y和ROI垂直中点的距离
  • 参数硬编码问题:当前a和rate_change是固定值,没有和ROI尺寸绑定,不同大小的ROI效果差异极大,需要归一化参数适配任意尺寸ROI
  • 边界判断语法错误:if(r.x < nearestNeighborX < r.x + r.width)是C++语法错误,连续比较符不会按预期执行,需改为逻辑与连接的两个判断

调整后的实现逻辑

  1. 先计算ROI的核心参数:水平中点、垂直中点,最大偏移量按ROI宽度比例设置,适配不同大小ROI
  2. 用反向映射遍历输出图像ROI范围内的每个(x,y)
  3. 计算x方向的归一化偏移:偏移量和(x - 水平中点)的平方成正比,同时可配置y方向上下边缘衰减,保证边缘和原图衔接自然没有断层
  4. 计算采样的原图坐标,用最近邻插值赋值

修正后代码

#include <iostream>
#include <opencv2/opencv.hpp>
#include <cmath>

using namespace std;
using namespace cv;

int main() {
    Mat originalImage = imread("../dog.jpeg",IMREAD_GRAYSCALE);
    if(originalImage.empty()) {
        cout << "读取图像失败" << endl;
        return -1;
    }
    Mat outPutImage = originalImage.clone();

    // 选择ROI
    Rect2d r = selectROI("选择ROI后按回车/空格",originalImage);
    destroyWindow("选择ROI后按回车/空格");
    if(r.width == 0 || r.height == 0) {
        cout << "ROI选择无效" << endl;
        return -1;
    }

    // 核心参数,可调整:max_offset是ROI中线位置的最大像素偏移量,值越大弯曲越明显
    double max_offset = r.width * 0.08; // 按ROI宽度比例设置,适配不同大小ROI
    double x_c = r.x + r.width / 2.0; // ROI水平中线
    double y_c = r.y + r.height / 2.0; // ROI垂直中线

    // 反向映射:遍历输出图像的每个像素
    for(int y = r.y; y < r.y + r.height ; y++){
        // y方向衰减系数:上下边缘处为0,垂直中线处为1,保证ROI上下边缘和原图衔接自然
        double y_factor = 1.0 - abs(y - y_c) / (r.height / 2.0);
        y_factor = pow(y_factor, 2); // 加平方让衰减更平滑,不需要衰减可以直接设为1

        for(int x = r.x; x < r.x + r.width; x++){
            // 计算x方向的偏移:离水平中线越远偏移越大,乘以y方向衰减系数
            double delta_x = max_offset * pow( (x - x_c)/(r.width/2.0), 2 ) * y_factor;
            // 反向映射:输出的(x,y)对应原图的(x + delta_x, y),弯曲方向反过来就把加号改减号
            double src_x = x + delta_x;

            // 边界判断
            int nearestX = round(src_x);
            if(nearestX >= r.x && nearestX < r.x + r.width) {
                outPutImage.at<uchar>(y, x) = originalImage.at<uchar>(y, nearestX);
            } else {
                // 超出范围的保持原图即可
                outPutImage.at<uchar>(y, x) = originalImage.at<uchar>(y, x);
            }
        }
    }

    imshow("形变结果", outPutImage);
    waitKey(0);
    imwrite("../result.jpg", outPutImage);
    return 0;
}

参数调整说明

  • 调整max_offset的比例系数即可控制弯曲程度:系数越大弯曲越明显,建议取值范围是r.width * 0.03到r.width * 0.15
  • 如果想要弯曲方向反过来,把double src_x = x + delta_x;里的加号改成减号即可
  • 如果不需要y方向的衰减(上下边缘也保持弯曲),直接把y_factor设为1即可

内容的提问来源于stack exchange,提问作者Roy Amoyal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:24:06