2014-07-02 64 views
4

這是我如何的公式產生的數據點繪製簡單的函數:嘗試使用OpenCV的C++

enter image description here

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; 

} 

現在我要繪製基於這些點的圖形。什麼到目前爲止,我已經試過是繪製一條直線的程序:

#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:線,連接我公司提供的終點。但是如何繼續我的功能數據呢?

更新

這裏是我怎麼現在這樣做:

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; 
} 

但現在我越來越空白圖像。

+0

可以了'graph'陣列從'i'畫線'我在簡單地重複+ 1',其中'i'從零到N-2,N = 2000。 –

+1

cv :: line(image,p1,p2,Scalar(0,0,255),5,8,0); // b,g,r值 – berak

+0

@berak我有空白圖片。請看我的更新。 – user2799508

回答

7

這是我的解決方案。做了一些修改你的代碼,並添加比例:

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; 
} 

給我這樣的結果:

enter image description here

+0

太棒了!順便說一句,你能告訴我哪一行代碼處理了我正面臨的擴展問題嗎? – user2799508

+2

很快就能解決這個問題(很高興我現在可以停下來)。剩下1個問題:y軸仍然指向下方(因爲原點是左上角) – berak

+0

@Micka sample()的文檔在哪裏。谷歌正在引導我對opencv程序進行示例:-( – user2799508