【问题标题】:Drawing Implicit functions in an image (Python,[OpenCV])在图像中绘制隐式函数(Python,[OpenCV])
【发布时间】:2020-10-14 19:03:16
【问题描述】:

我需要根据图像中的函数绘制曲线。像 x^2+y^2=1 这样的东西,没有将其转换为显式形式,因为并非我使用的所有函数都可以通过这种方式轻松转换。对于常规的隐式函数,我使用带有 x 和 y 点的 cv2.polylines 在我的图像中绘制曲线,我想知道你们是否有类似的显式函数解决方案。到目前为止,我发现所有使用 matplotlib 使用 plt.contour 绘制图形。但这对我来说似乎并没有真正有用。请帮忙

提前致谢

【问题讨论】:

  • matplotlib pyplot 为什么没用?似乎是最直接的方法。您还可以迭代 x 和 y 并从函数计算点,然后使用 cv2.polylines() 在图像或恒定背景上绘制结果。见docs.opencv.org/4.1.1/d6/d6e/…
  • 我在管道的其余部分在 opencv 中创建图像,并且这个函数必须在同一个图像中绘制。所以我想,除非你遍历每个像素,否则你无法真正写出图像

标签: python opencv image-processing computer-vision curve


【解决方案1】:

你可以这样渲染它,对不起,我是 C++ 粉丝)希望这个想法对 python 程序员来说是清楚的。

// Your function 
float func(float x, float y)
{
    // x * x * sin(x) + y * y = 1
    return (x * x * sin(x) + y * y - 1);
}
// render it 
void plotXY()
{
    // canvas size
    int height = 800;
    int width = 800;
    // plot scale
    float scale = 0.1;
    // cavas
    cv::Mat result=cv::Mat::zeros(height, width, CV_8UC3);
    // move origin to canvas center
    float cx = (float)width / 2.0f;
    float cy = (float)height / 2.0f;
    // precompute scale
    float sx = (scale * (float)width);
    float sy = (scale * (float)height);

    // scan for zero crossings
    for (uint32_t i = 1; i < height-1; ++i)
    {
        for (uint32_t j = 1; j < width-1; ++j)
        {
            // transform screen space to real space
            float x =  ((float)j -     cx) / sx;
            float x1 = ((float)(j-1) - cx) / sx;
            float x2 = ((float)(j+1) - cx) / sx;
            float y =  ((float)i -     cy) / sy;
            float y1 = ((float)(i-1) - cy) / sy;
            float y2 = ((float)(i+1) - cy) / sy;
            // if zero crossimg along x put pixel
            if ( func(x1,y)* func(x2, y) < 0)
            {
                result.at<cv::Vec3b>(i, j) = cv::Vec3b(255, 255, 255);
            }
            // if zero crossimg along y put pixel
            if (func(x, y1) * func(x, y2) < 0)
            {
                result.at<cv::Vec3b>(i, j) = cv::Vec3b(255, 255, 255);
            }
        }
    }

    // show and save result
    cv::imshow("plot", result);
    cv::imwrite("plot.jpg", result);
    cv::waitKey();
}

函数 x * x * sin(x) + y * y = 1 的结果将是:

【讨论】:

  • 感谢您的回答!我使用类似的实现。看来我不能没有嵌套的 for 循环。我想要一个更快的方法,但这个解决方案可以完成这项工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 2014-06-01
  • 2012-03-12
  • 1970-01-01
相关资源
最近更新 更多