Quantcast

How to draw a bezier spline (opencv) c++

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
This is my code which when I run it, it shows a ready bazier spline which I can't edit on it



   #include "stdafx.h"
   #include <stdlib.h>
   #include <gl/glut.h>

   // 4 control points for our cubic bezier curve
   float Points[4][3] = {
{ 10,10,0 },
{  5,10,2 },
{ -5,0,0 },
{-10,5,-2}
 };

 // the level of detail of the curve
 unsigned int LOD=20;


   void OnKeyPress(unsigned char key,int,int) {
switch(key) {

// increase the LOD
case '+':
    ++LOD;
    break;

// decrease the LOD
case '-':
    --LOD;

    // have a minimum LOD value
    if (LOD<3)
        LOD=3;
    break;
default:
    break;
}

// ask glut to redraw the screen for us...
glutPostRedisplay();
  }

   void OnDraw() {

// clear the screen & depth buffer
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);

// clear the previous transform
glLoadIdentity();

// set the camera position
gluLookAt(  1,10,30,    //  eye pos
            0,0,0,  //  aim point
            0,1,0); //  up direction

glColor3f(1,0,1);

// we will draw lots of little lines to make our curve
glBegin(GL_LINE_STRIP);

for(int i=0;i!=LOD;++i) {

    // use the parametric time value 0 to 1
    float t = (float)i/(LOD-1);

    // nice to pre-calculate 1.0f-t because we will need it frequently
    float it = 1.0f-t;

    // calculate blending functions
    float b0 = t*t*t;
    float b1 = 3*t*t*it;
    float b2 = 3*t*it*it;
    float b3 =  it*it*it;

    // calculate the x,y and z of the curve point by summing
    // the Control vertices weighted by their respective blending
    // functions
    //
    float x = b0*Points[0][0] +
              b1*Points[1][0] +
              b2*Points[2][0] +
              b3*Points[3][0] ;

    float y = b0*Points[0][1] +
              b1*Points[1][1] +
              b2*Points[2][1] +
              b3*Points[3][1] ;

    float z = b0*Points[0][2] +
              b1*Points[1][2] +
              b2*Points[2][2] +
              b3*Points[3][2] ;

    // specify the point
    glVertex3f( x,y,z );
}
glEnd();

// draw the Control Vertices
glColor3f(0,1,0);
glPointSize(3);
glBegin(GL_POINTS);
    for(int i=0;i!=4;++i) {
        glVertex3fv( Points[i] );
    }
glEnd();

// draw the hull of the curve
glColor3f(0,1,1);
glBegin(GL_LINE_STRIP);
    for(int i=0;i!=4;++i) {
        glVertex3fv( Points[i] );
    }
glEnd();

// currently we've been drawing to the back buffer, we need
// to swap the back buffer with the front one to make the image visible
glutSwapBuffers();
}


   void OnInit() {
// enable depth testing
glEnable(GL_DEPTH_TEST);
   }


   void OnExit() {
   }


   void OnReshape(int w, int h)
   {
if (h==0)
    h=1;

// set the drawable region of the window
glViewport(0,0,w,h);

// set up the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

   // just use a perspective projection
    gluPerspective(45,(float)w/h,0.1,100);

    // go back to modelview matrix so we can move the objects about
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
     }


   int main(int argc,char** argv) {

// initialise glut
glutInit(&argc,argv);

// request a depth buffer, RGBA display mode, and we want double buffering
glutInitDisplayMode(GLUT_DEPTH|GLUT_RGBA|GLUT_DOUBLE);

// set the initial window size
glutInitWindowSize(640,480);

// create the window
glutCreateWindow("Bezier Curve: +/- to Change Level of Detail");

// set the function to use to draw our scene
glutDisplayFunc(OnDraw);

// set the function to handle changes in screen size
glutReshapeFunc(OnReshape);

// set the function for the key presses
glutKeyboardFunc(OnKeyPress);

// run our custom initialisation
OnInit();

// set the function to be called when we exit
atexit(OnExit);

// this function runs a while loop to keep the program running.
glutMainLoop();
return 0;
   }
I want make some edit in my code to make it from opengl to opencv ,so when I run it, I can draw the four points by myself ,and also I can control the curve like in this picture



and draw curves as many as I can like in this picture


So my question is what is the missing in my code to do what I want above?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn

/*
 COOL!
I got your code work in Linux:)


 With a few changes:

gcc p.c -lGL -lGLU -lGLEW -lglut -o p -std=gnu99


*/


   #include <GL/freeglut.h>
   #include <GL/gl.h>

//   #include "stdafx.h"
   #include <stdlib.h>
//   #include <gl/glut.h>

   // 4 control points for our cubic bezier curve
   float Points[4][3] = {
{ 10,10,0 },
{  5,10,2 },
{ -5,0,0 },
{-10,5,-2}
 };

 // the level of detail of the curve
 unsigned int LOD=20;


   void OnKeyPress(unsigned char key,int xmouse, int ymouse) {
switch(key) { //..........................................


// Yes, openCV will do it all you want with -(x^2) and -(x^3) polynomial graphs. Maybe on the one first one that is
not a math function. may have to piece wise it together.


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
In reply to this post by faho0odywbas

/*

http://opencvexamples.blogspot.com/2013/10/basic-drawing-examples.html

g++ pro.cpp -o pro `pkg-config --cflags --libs opencv`

*/


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
 
int main( )
{    
  // Create black empty images
  Mat image = Mat::zeros( 400, 400, CV_8UC3 );
   
  // Draw a ellipse ellipse
  ellipse( image, Point( 200, 200 ), Size( 100.0, 160.0 ), 45, 33, 199, Scalar( 0, 0, 255 ), 1, 8 );
//C++: void ellipse(Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0)¶

  ellipse( image, Point( 200, 200 ), Size( 100.0, 160.0 ), 135, 0, 360, Scalar( 255, 0, 0 ), 10, 8 );
  ellipse( image, Point( 200, 200 ), Size( 150.0, 50.0 ), 135, 0, 360, Scalar( 0, 255, 0 ), 1, 8 );
  imshow("Image",image);
 
  waitKey( 0 );
  return(0);
}


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn







 Can you break me off something simpler. So i can do real quick?







Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

opencv-users mailing list
I had to use inagemagick convert function within opencv (executing a host command)

1) by passing the coordinates as points 

2) frame the convert command to be executed as a string

3) execute the host command with the string in #2 having the command for bezier curve. The output will be an image that you can incorporate back into your  open CV project.

Not the quickest... But worked for me.


Sent from Yahoo Mail on Android

From:"keghn [hidden email] [OpenCV]" <[hidden email]>
Date:Tue, 6 Oct, 2015 at 1:48 am
Subject:[OpenCV] Re: How to draw a bezier spline (opencv) c++

 



Can you break me off something simpler. So i can do real quick?

--
View this message in context: http://opencv-users.1802565.n2.nabble.com/How-to-draw-a-bezier-spline-opencv-c-tp7585724p7585727.html
Sent from the opencv-users mailing list archive at Nabble.com.



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
I don't want the output be a ready bezier spline like in my code,
 I just want the output will be an empty image and I click 4 input points and the curve will be drawn itself

Thanks
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
This post was updated on .



 cool, Like a CAD program would do.

 I will work it out in OpenCV. and if it ease for me to make or find i will post it.
 Cheers,
    keghn.






Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
great, I post to you the requirements of this assignments to help you understand what I mean, and do whatever easy for you from them, thanks again

1) Correct Bezier spline drawing

-Draw the curve based on user’s 4 points input.

- Use Bezier matrix to multiple the 4 points to obtain the correct coefficients (a_x, b_x, c_x, d_x, a_y, b_y, c_y, d_y).

- Correctly plot the curves based on the coefficients.

- As long as one Bezier spline is drawn correctly, you will get the credits.

(2) Bezier controlling point (the 2nd and 3rd points) editing

- User can drag the controlling points freely to change the point position.

- The two corresponding straight lines change dynamically according to the new positions of the controlling points.

- The curve spline’s shape changes dynamically according to the new positions of the controlling points.

- Again, as long as you can have the controlling points of one Bezier spline work, you will get the credits.

(3) Multiple spline drawing

- Your code allows user to draw as many splines as needed.

(4) Correct mouse operations

- Left click to select a point.

- Right click to remove last point.

- Left key down and hold it to drag the mouse to change the positions of controlling points.

(5) Correct key board

- Hit “s” or “S” to save the image

- Hit “r” or “R” to remove points and only keep the curves

Regards
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
How is the code until now ?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
 
/*
I am have made a rough program generating from 2 point and up to 5 points. And i believe it can go up to may more points.
 It is really rough and messy but it works. Now i have to clean it up and make it more user friendly.

 it is doing the 5 point curves on the wiki page that are 3/4 of the way down:

https://en.wikipedia.org/wiki/B%C3%A9zier_curve


 It is in OpenCV:
*/


/*
Bézier curve:
https://en.wikipedia.org/wiki/B%C3%A9zier_curve


http://opencvexamples.blogspot.com/2013/10/basic-drawing-examples.html
http://docs.opencv.org/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html

compile:
g++ pro.cpp -o pro `pkg-config --cflags --libs opencv`

To run:

./pro

*/




#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
 
  Point2i a(0, 0), b(0, 0), c(0, 0), d(33, 0), e(0, 1), f(0, 0);// general purpose scratch registers.


int main( )
{    
  // Create black empty images
  Mat image = Mat::zeros( 300, 500, CV_8UC3 );
   

//  Point2i a(0, 0), b(0, 0), c(22, 222), d(33, 33);// general purpose scratch registers.

  vector<Point2i> P(20);
  vector<Point2i> Pp(20);
  vector<Point2i> Ppp(20);

  unsigned int Np = 5;// number of P points. P0 to P4 is 5 points
  Np = Np -1;
  P[0] = { 22, 200};
  P[1] = { 1, 66};
  P[2] = { 233, 22};
  P[3] = { 222, 255};
  P[4] = { 388, 100};
//  P() = { , };
//  P() = { , };
//  P(55) = { , };


//cout<<" Pp is "<< Pp << endl;
//cout<<" Ppppppppppp[] is="<< Pp[0]<<"\n\n";

        for ( float ppercent = 0.00; ppercent < 1.0;ppercent = ppercent + 0.01)
          {///
//    cout<<" Pppppp[] is="<< Pp[0]<<"\n\n";
            Pp = P;
            int c2ccount = Np;
            for (int c1ccount = 0 ; c1ccount < Np; c1ccount = c1ccount + 1)
                   {//

// cout<<" Pppp[] is="<< Pp[0]<<"\n\n";

                        for (int cccount = 0 ; cccount < c2ccount; cccount = cccount + 1)
                                {
                                  a = Pp[cccount] - Pp[cccount + 1];
                                  cout<<" ppercent is="<< ppercent ;
                                  cout<<"  c1ccount " << c1ccount;
                                  cout<<"  cccount " << cccount;

                                  cout<<"  Pp[+1]"<< Pp[cccount + 1];
                                  cout<<"  Pp[]"<< Pp[cccount];
                                  a = Pp[cccount + 1] - Pp[cccount];
                                  cout<<" a is="<< a ;
                                  b = ppercent * a;
                                  cout<<" b is="<< b;
//  c = Pp[0] + b;
                                  c = Pp[cccount] + b;
                                  Ppp[cccount] = c;
                                  cout<<"  c is="<< c ;
                                  cout<<"  Ppp[0]is="<< Ppp[0] << endl;
                                 }
                        c2ccount = c2ccount - 1;
                        Pp = Ppp;

                  }//

// cout<<"cccccc is "<< c << endl;
// a = c + d;

                f = c + e;

// line( image, Point( 15, 111 ), Point( 70, 50), Scalar( 200, 200, 200 ),  2, 8 );
                line( image, c, f, Scalar( 200, 200, 200 ),  2, 8 );
           }///


        line( image, Point( 15, 20 ), Point( 70, 50), Scalar( 110, 220, 0 ),  2, 8 );
// line( image, Point( 15, 111 ), Point( 70, 50), Scalar( 0, 0, 110 ),  2, 8 );



/*

        for (int ccount = 1;ccount < 2; ccount = ccount + 1)
          {
//    line( image, Point( 15 * ccount, 30 * ccount ), Point( 70 * ccount, 50 * ccount), Scalar( 110, 220, 0 ),  2, 8 );
            line( image, a, b, Scalar( 110, 220, 0 ),  2, 8 );
           }
//  line( image, Point( 15, 20 ), Point( 70, 50), Scalar( 110, 220, 0 ),  8, 8 );
//  line( image, Point( 115, 120 ), Point( 170, 150), Scalar( 110, 220, 0 ),  8, 8 );

*/
        imshow("Image",image);
        waitKey( 0 );
        cout <<"done\n";
        return(0);
}

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
Hi,


when I do build the solution, it shows to me this error
error C1083: Cannot open include file: 'opencv2/imgproc.hpp': No such file or directory

What I have to do, and what about the command lines that you made ?

Should I uncommand it or not ?

Thanks


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
 You have OpenCV installed?:

http://opencv.org/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
yes I have
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
In reply to this post by keghn
Now I fix the error which I have to change
#include <opencv2/imgproc.hpp> to
#include <opencv2/imgproc/imgproc.hpp>

but when I run the program, it just keep running and calculating numbers !!

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
 Remove the "cout<<....."  All of them with "//" or delete them. Printing to the CLI take a lot of time.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
After I delete 'em and run the program, it shows to me this image



But I want the program be when it's run, it shows to me a blank image and after that I click 4 points
and show curve like this



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn
  OK you are getting close. That is my 5 point curve i copied from the wiki page. Generated here.

 Next i will smooth out curve better and put in the straight P lines in.

 keyboard and mouse interface will be the last thing to do.
  Cheers:)
    keghn
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

faho0odywbas
This post has NOT been accepted by the mailing list yet.
great, can you do it just by 4 points ?

Because the requirements is just for 4 points.


Thanks
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to draw a bezier spline (opencv) c++

keghn

/*
bazier spline
http://opencvexamples.blogspot.com/2013/10/basic-drawing-examples.html
http://docs.opencv.org/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
compile:

g++ pro.cpp -o ppro `pkg-config --cflags --libs opencv` -std=gnu++11

run:

./pro

*/

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main( )
{    
  // Create black empty images
  Mat image = Mat::zeros( 500, 800, CV_8UC3 );  

  Point2i Lp(0, 0);

  vector<Point2i> P(20);
  vector<Point2i> Pp(20);
  vector<Point2i> Ppp(20);
  Point2i a(0, 0), b(0, 0), c(0, 0), d(33, 0), e(0, 1), f(0, 0);// general purpose scratch registers.
  unsigned int Np; // number of P points. P0 to P4 is 5 points

  Np = 4;
  P[0] = { 133, 300};
  P[1] = { 260, 400};
  P[2] = { 555, 111};
  P[3] = { 700, 111};

//  P(5) = { , };
//  P(6) = { , };
//  P(55) = { , };
        Np = Np -1;

        Lp = P[0];
        for ( float ppercent = 0.00; ppercent < 1.0;ppercent = ppercent + 0.01)
          {///
            Pp = P;
            int c2ccount = Np;
            for (int c1ccount = 0 ; c1ccount < Np; c1ccount = c1ccount + 1)
                   {//
                        for (int cccount = 0 ; cccount < c2ccount; cccount = cccount + 1)
                                {
                                  a = Pp[cccount] - Pp[cccount + 1];
                                  a = Pp[cccount + 1] - Pp[cccount];
                                  b = ppercent * a;
                                  c = Pp[cccount] + b;
                                  Ppp[cccount] = c;
                                 }
                        c2ccount = c2ccount - 1;
                        Pp = Ppp;
                  }//

                line( image, c, Lp, Scalar( 110, 220, 0 ),  1, 1 );
                Lp = c;
           }///

// P straight line generator.
        for(int c3ccount = 0 ; c3ccount < Np ; c3ccount = c3ccount + 1)
                {
                  line( image, P[c3ccount], P[c3ccount + 1], Scalar( 200, 200, 200 ),  2, 8 );
                  a = P[c3ccount] + e;
                  line( image, P[c3ccount], a, Scalar( 55, 55, 200 ),  9, 8 );
                  a = P[c3ccount + 1] + e;
                  line( image, P[c3ccount + 1], a, Scalar( 55, 55, 200 ),  9, 8 );
                 }

        imshow("Bezier_curve",image);
        waitKey( 0 );
        cout <<"done\n";
        return(0);
}
Loading...