【问题标题】:Warp Image by Diagonal Sine Wave对角正弦波的扭曲图像
【发布时间】:2020-10-23 10:48:01
【问题描述】:

我正在尝试使用 OpenCV 中的 sin 函数来扭曲彩色图像,并且我成功地这样做了。但是,如何使用正弦波进行“对角线”翘曲?

我的代码是这样的:

Mat result = src.clone();
    for (int i = 0; i < src.rows; i++) { // to y
        for (int j = 0; j < src.cols; j++) { // to x
            for (int ch = 0; ch < 3; ch++) { // each colour
                int offset_x = 0;
                int offset_y = (int)(25.0 * sin(3.14 * j / 150));
                if (i + offset_y < src.rows) {
                    result.at<Vec3b>(i, j)[ch] = src.at<Vec3b>((i + offset_y) % src.rows, j)[ch];
                }
                else
                    result.at<Vec3b>(i, j)[ch] = 0.0;
            }
        }
    }

    imshow("result", result);

我该怎么做?不是绘制正弦图,而是扭曲图像。

解决了这个问题!好几次之前,我都收到过有人告诉我图片被盗了。它实际上来自谷歌,但我已将其删除以履行不引起任何情况。谢谢!

【问题讨论】:

    标签: c++ opencv computer-vision


    【解决方案1】:

    我认为应该是这样的:

    void deform()
    {
        float alpha = 45 * CV_PI / 180.0; // wave direction
        float ox = cos(alpha);
        float oy = sin(alpha);
        
        cv::Mat src = cv::imread("F:/ImagesForTest/lena.jpg");
    
        for (int i = 0; i < src.rows; i+=8)
        { 
                cv::line(src, cv::Point(i, 0), cv::Point(i, src.rows),cv::Scalar(255,255,255));
        }
    
        for (int j = 0; j < src.cols; j += 8)
        { 
            cv::line(src, cv::Point(0,j), cv::Point(src.cols,j), cv::Scalar(255, 255, 255));
        }
    
    
        cv::Mat result = src.clone();
        for (int i = 0; i < src.rows; i++)
        { // to y
            for (int j = 0; j < src.cols; j++)
            { // to x
                float t =(i * oy)+ (j * ox); // wave parameter
                for (int ch = 0; ch < 3; ch++)
                { // each colour
                    int offset_x =ox* (int)(25.0 * (sin(3.14 * t/ 150)));
                    int offset_y =oy* (int)(25.0 * (sin(3.14 * t / 150)));
                    if (i + offset_y < src.rows && j + offset_x < src.rows && i + offset_y >=0 && j + offset_x>=0)
                    {
                        result.at<cv::Vec3b>(i, j)[ch] = src.at<cv::Vec3b>(i + offset_y, j + offset_x )[ch];
                    }
                    else
                        result.at<cv::Vec3b>(i, j)[ch] = 0.0;
                }
            }
        }
    
        cv:: imshow("result", result);
        cv::imwrite("result.jpg", result);
        cv::waitKey();
    }
    

    结果:

    顺便说一句,使用 cv::remap 可能会更好?

    【讨论】:

    • 感谢您的回复。我明天试试这个。你能解释一下为什么“重映射”在计算机视觉领域很有用吗?我正在自学,感到很沮丧
    • cv::remap 允许您根据 x 和 y 映射应用图像空间的几何变换。地图描述了当前地图坐标中的像素应放置在何处。 remap 也做插值并且它高度优化。经典用法是应用镜头不失真。但可用于应用失真效果,如您的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多