mercredi 13 février 2013

Draw an Arrow with OpenCV (and python version too)

OpenCV does not provide functions to draw an arrow. We will introduce a simple way to do it!
First, we draw a simple line (easy). Then, we plot the two segments that represent the arrow. These segments present an angle of 45 degrees (pi / 4) with the main line.
Here is the code for that:
#include <stdio.h>
#include <cv.h>
#include <highgui.h>


void drawArrow(IplImage *image, CvPoint p, CvPoint q, CvScalar color, int arrowMagnitude = 9, int thickness=1, int line_type=8, int shift=0) 

{
    //Draw the principle line
    cvLine(image, p, q, color, thickness, line_type, shift);
    const double PI = 3.141592653;
    //compute the angle alpha
    double angle = atan2((double)p.y-q.y, (double)p.x-q.x);
    //compute the coordinates of the first segment
    p.x = (int) ( q.x +  arrowMagnitude * cos(angle + PI/4));
    p.y = (int) ( q.y +  arrowMagnitude * sin(angle + PI/4));
    //Draw the first segment
    cvLine(image, p, q, color, thickness, line_type, shift);
    //
compute the coordinates of the second segment
    p.x = (int) ( q.x +  arrowMagnitude * cos(angle – PI/4));
    p.y = (int) ( q.y +  arrowMagnitude * sin(angle – PI/4));
    //
Draw the second segment
    cvLine(image, p, q, color, thickness, line_type, shift);
}  


//How to call this function
int main()

 {
    

   IplImage *canvas = cvCreateImage(cvSize(320, 240), IPL_DEPTH_8U, 3);
    cvNamedWindow(“win”);  
    drawArrow(canvas, cvPoint(10, 20), cvPoint(100, 150), CV_RGB(100, 0, 255), 20);
    cvShowImage(“win”, canvas);
    cvWaitKey();
    cvReleaseImage(&canvas);
    cvDestroyAllWindows();
    return 1;

} 

4 commentaires:

  1. Thank you for posting your function it saved me a lot of time when I needed to do the same thing in python. Here is my python version in case anybody reading your page can make use of it.

    def draw_arrow(image, p, q, color, arrow_magnitude=9, thickness=1, line_type=8, shift=0):
    # adapted from http://mlikihazar.blogspot.com.au/2013/02/draw-arrow-opencv.html

    # draw arrow tail
    cv2.line(image, p, q, color, thickness, line_type, shift)
    # calc angle of the arrow
    angle = np.arctan2(p[1]-q[1], p[0]-q[0])
    # starting point of first line of arrow head
    p = (int(q[0] + arrow_magnitude * np.cos(angle + np.pi/4)),
    int(q[1] + arrow_magnitude * np.sin(angle + np.pi/4)))
    # draw first half of arrow head
    cv2.line(image, p, q, color, thickness, line_type, shift)
    # starting point of second line of arrow head
    p = (int(q[0] + arrow_magnitude * np.cos(angle - np.pi/4)),
    int(q[1] + arrow_magnitude * np.sin(angle - np.pi/4)))
    # draw second half of arrow head
    cv2.line(image, p, q, color, thickness, line_type, shift)

    RépondreSupprimer
  2. Thank you both, you have saved me time.
    Please give me your bitcoin address, I would like you to have a beer on me.

    RépondreSupprimer
  3. Thank you so much for this code :)

    RépondreSupprimer