尝试使用OpenCV C ++绘制简单函数 [英] Trying to plot simple function using opencv c++

查看:93
本文介绍了尝试使用OpenCV C ++绘制简单函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这就是我为方程式生成数据点的方式:

This is how I am generating data points for the equation :

  struct Sine_point {
  double  x;
  double  y;
};


    Sine_point graph[2000];

for(int i = 0; i < 2000; i++) {
  float x = (i - 1000.0) / 100.0;
  graph[i].x = x;
  graph[i].y = sin(x * 10.0) / (1.0 + x * x);
  cout<<graph[i].x<<graph[i].y<<endl;

}

现在,我想根据这些点绘制一个图形.到目前为止,我尝试过的是绘制直线的程序:

Now I want to plot a graph based on these points. What I have tried so far is a program for plotting a straight line:

#include <vector>
#include "opencv2/highgui/highgui.hpp"
#include <opencv\cv.h>
#include <iostream>
#include<conio.h>


using namespace cv;
using namespace std;


int main()

{


    std::vector<char> dataPtr(40000, 200);
    cv::Point p1(0,0);
    cv::Point p2(200, 200);
    cv::Size size(200,200); 
    cv::Mat image(size, CV_8U, &(dataPtr[0]));
    if (image.empty()) //check whether the image is valid or not 
     {
          cout << "Error : Image cannot be created..!!" << endl;
          system("pause"); //wait for a key press
          return -1;
     }

    cv::line(image, p1, p2, 'r', 5, 8, 0); 

    namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); //create a window with the name "MyWindow"

    imshow("MyWindow", image); //display the image which is stored in the 'img' in the "MyWindow" window

    waitKey(0); //wait infinite time for a keypress
    destroyWindow("MyWindow"); //destroy the window with the name, "MyWindow"
    return 0;
}

这使用cv:line来连接我提供的端点.但是如何处理我的功能数据?

This uses cv:line, that connects the end points I provided. But how do I proceed for my functions data?

更新

这是我现在的操作方式:

Here is how I am doing this now:

int main()

{

    std::vector<char> dataPtr(40000, 200);

    cv::Size s(200,200); 
    cv::Mat image(s,  CV_8U,  &(dataPtr[0]));

    if (image.empty()) //check whether the image is valid or not 
     {
          cout << "Error : Image cannot be created..!!" << endl;
          system("pause"); //wait for a key press
          return -1;
     }

  struct Sine_point {
  double  x;
  double  y;
};


    Sine_point graph[2000];

for(int i = 0; i < 2000; i++) {
  float x = (i - 1000.0) / 100.0;
  graph[i].x = x;
  graph[i].y = sin(x * 10.0) / (1.0 + x * x);

cv::Point p1(graph[i].x,graph[i].y);
cv::Point p2(graph[i+1].x, graph[i+1].y);

  cv::line(image, p1, p2, Scalar(0,0,255), 5, 8, 0);
}


namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); //create a window with the name "MyWindow"

    imshow("MyWindow", image); //display the image which is stored in the 'img' in the "MyWindow" window

    waitKey(0); //wait infinite time for a keypress
    destroyWindow("MyWindow"); //destroy the window with the name, "MyWindow"
    return 0;
}

但是现在我得到的是空白图像.

But now I am getting blank image.

推荐答案

这是我的解决方案.对代码进行了一些更改并增加了缩放比例:

Here's my solution. Made some changes to your code and added scaling:

struct Sine_point {
  double  x;
  double  y;
};

int main()
{

    unsigned int nSamples = 2000;

    // use float precision?!?
    Sine_point min;
    Sine_point max;

    Sine_point graph[nSamples];
    for(unsigned int i = 0; i < nSamples; i++)
    {
        //using double precision:

        // sample to confirm y-axis mirroring: simple line
        //double x = (i - 1000.0) / 100.0;
        //double y = x;

        double x = (i - 1000.0) / 100.0;
        double y = sin(x * 10.0) / (1.0 + x * x);

        Sine_point sample; sample.x = x; sample.y = y;

        graph[i] = sample;
        std::cout<<graph[i].x<<graph[i].y<<std::endl;

        if(sample.x < min.x ) min.x = sample.x;
        if(sample.y < min.y ) min.y = sample.y;

        if(sample.x > max.x ) max.x = sample.x;
        if(sample.y > max.y ) max.y = sample.y;

    }

    cv::Size imageSize(640,480); // your window size
    cv::Mat image(imageSize, CV_8UC1);

    if (image.empty()) //check whether the image is valid or not
     {
          std::cout << "Error : Image cannot be created..!!" << std::endl;
          system("pause"); //wait for a key press
          return -1;
     }

    //now scale your points to fit inside the image:
    Sine_point dataOffset;
    // here you could define the offsets by yourself, I just use image borders and scale the values to fit inside the image
    dataOffset.x = -min.x;
    // we have to mirror the y axis!
    dataOffset.y = min.y;

    Sine_point dataScale;
    dataScale.x = (double)imageSize.width / (max.x - min.x);
    // remember to mirror the y axis
    dataScale.y = - (double)imageSize.height/ (max.y - min.y);

    // scale the samples
    for(unsigned int i=0; i<nSamples; ++i)
    {
        graph[i].x = (graph[i].x + dataOffset.x) * dataScale.x;
        graph[i].y = (graph[i].y + dataOffset.y) * dataScale.y;

    }

    // draw the samples
    for(unsigned int i=1; i<nSamples; ++i)
    {

        cv::Point2f p1; p1.x = graph[i-1].x; p1.y = graph[i-1].y;
        cv::Point2f p2; p2.x = graph[i].x;   p2.y = graph[i].y;
        cv::line(image, p1, p2, 'r', 5, 8, 0);
    }

    cv::namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); //create a window with the name "MyWindow"

    cv::imshow("MyWindow", image); //display the image which is stored in the 'img' in the "MyWindow" window

    cv::imwrite("sinusDraw.png", image);

    cv::waitKey(0); //wait infinite time for a keypress

    return 0;
}

给我这个结果:

这篇关于尝试使用OpenCV C ++绘制简单函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆