Text and drawing
In the previous section, we used a simple user interface to get input values by a trackbar. However, in many applications, the user has to point locations and regions on the image and mark them with text labels. For this purpose, the highgui
module provides a set of drawing functions along with mouse event handling.
The drawThings
code example shows an easy application to mark positions on an input image. The positions are marked with a red circle and a black text label next to it. The following screenshot displays the window with the input image and the marked positions on it. To mark each position on the image, the user uses has to click the left mouse button over it. In other application, the marked position could be the obtained points or regions from an algorithm applied to the input image.
Next, we show the example code where some pieces of code have been omitted for simplicity, since they are duplicated in other previous examples:
// (omitted for simplicity) #define IN_WIN "Drawing..." Mat img; // CallBack Function for mouse events void cbMouse(int event, int x, int y, int flags, void* userdata) { static int imark=0; char textm[] = "mark999"; if (event == EVENT_LBUTTONDOWN) { // Left mouse button pressed circle(img, Point(x, y), 4, Scalar(0,0,255), 2); imark++;// Increment the number of marks sprintf(textm, "mark %d", imark);// Set the mark text putText(img, textm, Point(x+6, y), FONT_HERSHEY_PLAIN, 1, Scalar(0,0,0),2); imshow(IN_WIN, img); // Show final image } return; } int main(int argc, char* argv[]) { // (omitted for brevity) img = imread(argv[1]); //open and read the image // (omitted for brevity) namedWindow(IN_WIN); setMouseCallback(IN_WIN, cbMouse, NULL); imshow(IN_WIN, img); cout << "Pres any key to exit..." << endl; waitKey(); return 0; }
The code explanation is given as follows:
void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata=0)
: This function sets an event mouse handler for the specified window. In this function, the second argument is the callback function executed whenever a mouse event occurs. The final argument is avoid
pointer to the data passed as argument to that function. In our code, this function is used as follows:setMouseCallback(IN_WIN, cbMouse, NULL);
In this case, rather than use a global variable for the name of the window, a defined symbol with global scope has been preferred (
IN_WIN
).The mouse handler itself is declared as follows:
void cbMouse(int event, int x, int y, int flags, void* userdata)
Here,
event
indicates the mouse event type,x
andy
are the coordinates for the location of the event at the window, andflags
is the specific condition whenever an event occurs. In this example, the unique captured mouse event is the left mouse click (EVENT_LBUTTONDOWN
).The following enumerations define the events and flags handled in the mouse callback functions:
enum{ EVENT_MOUSEMOVE =0, EVENT_LBUTTONDOWN =1, EVENT_RBUTTONDOWN =2, EVENT_MBUTTONDOWN =3, EVENT_LBUTTONUP =4, EVENT_RBUTTONUP =5, EVENT_MBUTTONUP =6, EVENT_LBUTTONDBLCLK =7, EVENT_RBUTTONDBLCLK =8, EVENT_MBUTTONDBLCLK =9}; enum { EVENT_FLAG_LBUTTON =1, EVENT_FLAG_RBUTTON =2, EVENT_FLAG_MBUTTON =4, EVENT_FLAG_CTRLKEY =8, EVENT_FLAG_SHIFTKEY =16, EVENT_FLAG_ALTKEY =32};
void circle(Mat& img, Point center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
: This function draws a circle over the image with the specifiedradius
(in pixels) andcolor
at the position marked by itscenter
. Moreover, athickness
value for the line and other additional parameters can be set. The usage of this function in the example is as follows:circle(img, Point(x, y), 4, Scalar(0,0,255), 2);
The center of the circle is the point where the mouse is clicked. The radius has
4
pixels and the color is pure red (Scalar(0, 0, 255)
) with a line thickness of2
pixels.Other drawing functions included in the
highgui
module allow us to draw ellipses, lines, rectangles, and polygons.void putText(Mat& image, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false)
: This function draws atext
string in theimage
at the specified position (org
) with the properties set by the argumentsfontFace
,fontScale
,color
,thickness
, andlineType
. It is possible to set the coordinates origin at the bottom-left corner with the last argument (bottomLeftOrigin
). In the example, this function is used as follows:imark++; // Increment the number of marks sprintf(textm, "mark %d", imark); // Set the mark text putText(img, textm, Point(x+6, y), FONT_HERSHEY_PLAIN, 1.0, Scalar(0,0,0),2);
In the
drawThings
example, we draw a text"mark"
followed by an increasing number that points out the mark order. To store the mark order, we used astatic
variable (imark
) that maintains its value between the calls. TheputText
function draws the text at the location where the mouse click occurs with a 6-pixels shift on x axis. The font face is specified by the flagFONT_HERSHEY_PLAIN
and is drawn without scale (1.0
), black color (Scalar(0, 0, 0)
), and2
pixels thickness.The available flags for the font face are defined by the enumeration:
enum{ FONT_HERSHEY_SIMPLEX = 0, FONT_HERSHEY_PLAIN = 1, FONT_HERSHEY_DUPLEX = 2, FONT_HERSHEY_COMPLEX = 3, FONT_HERSHEY_TRIPLEX = 4, FONT_HERSHEY_COMPLEX_SMALL = 5, FONT_HERSHEY_SCRIPT_SIMPLEX = 6, FONT_HERSHEY_SCRIPT_COMPLEX = 7, FONT_ITALIC = 16};