From 13317bdfda691d25aef22376bfd9cbb87f244f4d Mon Sep 17 00:00:00 2001 From: tribta Date: Fri, 18 Aug 2017 21:33:28 +0100 Subject: [PATCH] Tutorial Basic Geometric Drawing --- .../basic_geometric_drawing.markdown | 287 +++++++++++++----- .../core/table_of_content_core.markdown | 2 + .../tutorial_code/core/Matrix/Drawing_1.cpp | 21 +- .../BasicGeometricDrawing.java | 186 ++++++++++++ .../basic_geometric_drawing.py | 115 +++++++ 5 files changed, 524 insertions(+), 87 deletions(-) create mode 100644 samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java create mode 100644 samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py diff --git a/doc/tutorials/core/basic_geometric_drawing/basic_geometric_drawing.markdown b/doc/tutorials/core/basic_geometric_drawing/basic_geometric_drawing.markdown index c27e3293a4..ec3a2ffadc 100644 --- a/doc/tutorials/core/basic_geometric_drawing/basic_geometric_drawing.markdown +++ b/doc/tutorials/core/basic_geometric_drawing/basic_geometric_drawing.markdown @@ -1,19 +1,21 @@ Basic Drawing {#tutorial_basic_geometric_drawing} ============= +@prev_tutorial{tutorial_basic_linear_transform} +@next_tutorial{tutorial_random_generator_and_text} + Goals ----- In this tutorial you will learn how to: -- Use @ref cv::Point to define 2D points in an image. -- Use @ref cv::Scalar and why it is useful -- Draw a **line** by using the OpenCV function @ref cv::line -- Draw an **ellipse** by using the OpenCV function @ref cv::ellipse -- Draw a **rectangle** by using the OpenCV function @ref cv::rectangle -- Draw a **circle** by using the OpenCV function @ref cv::circle -- Draw a **filled polygon** by using the OpenCV function @ref cv::fillPoly +- Draw a **line** by using the OpenCV function **line()** +- Draw an **ellipse** by using the OpenCV function **ellipse()** +- Draw a **rectangle** by using the OpenCV function **rectangle()** +- Draw a **circle** by using the OpenCV function **circle()** +- Draw a **filled polygon** by using the OpenCV function **fillPoly()** +@add_toggle_cpp OpenCV Theory ------------- @@ -42,86 +44,217 @@ Point pt = Point(10, 8); Scalar( a, b, c ) @endcode We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c* +@end_toggle + +@add_toggle_java +OpenCV Theory +------------- + +For this tutorial, we will heavily use two structures: @ref cv::Point and @ref cv::Scalar : + +### Point + +It represents a 2D point, specified by its image coordinates \f$x\f$ and \f$y\f$. We can define it as: +@code{.java} +Point pt = new Point(); +pt.x = 10; +pt.y = 8; +@endcode +or +@code{.java} +Point pt = new Point(10, 8); +@endcode +### Scalar + +- Represents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel + values. +- In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is + not necessary to define the last argument if it is not going to be used. +- Let's see an example, if we are asked for a color argument and we give: + @code{.java} + Scalar( a, b, c ) + @endcode + We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c* +@end_toggle Code ---- +@add_toggle_cpp - This code is in your OpenCV sample folder. Otherwise you can grab it from - [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp) + [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp) @include samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp +@end_toggle + +@add_toggle_java +- This code is in your OpenCV sample folder. Otherwise you can grab it from + [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java) + @include samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java +@end_toggle + +@add_toggle_python +- This code is in your OpenCV sample folder. Otherwise you can grab it from + [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py) + @include samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py +@end_toggle Explanation ----------- --# Since we plan to draw two examples (an atom and a rook), we have to create two images and two - windows to display them. - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp create_images - --# We created functions to draw different geometric shapes. For instance, to draw the atom we used - *MyEllipse* and *MyFilledCircle*: - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_atom - --# And to draw the rook we employed *MyLine*, *rectangle* and a *MyPolygon*: - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_rook - --# Let's check what is inside each of these functions: - - *MyLine* - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp myline - - As we can see, *MyLine* just call the function @ref cv::line , which does the following: - - - Draw a line from Point **start** to Point **end** - - The line is displayed in the image **img** - - The line color is defined by **Scalar( 0, 0, 0)** which is the RGB value correspondent - to **Black** - - The line thickness is set to **thickness** (in this case 2) - - The line is a 8-connected one (**lineType** = 8) - - *MyEllipse* - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp myellipse - - From the code above, we can observe that the function @ref cv::ellipse draws an ellipse such - that: - - - The ellipse is displayed in the image **img** - - The ellipse center is located in the point **(w/2, w/2)** and is enclosed in a box - of size **(w/4, w/16)** - - The ellipse is rotated **angle** degrees - - The ellipse extends an arc between **0** and **360** degrees - - The color of the figure will be **Scalar( 255, 0, 0)** which means blue in BGR value. - - The ellipse's **thickness** is 2. - - *MyFilledCircle* - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp myfilledcircle - - Similar to the ellipse function, we can observe that *circle* receives as arguments: - - - The image where the circle will be displayed (**img**) - - The center of the circle denoted as the Point **center** - - The radius of the circle: **w/32** - - The color of the circle: **Scalar(0, 0, 255)** which means *Red* in BGR - - Since **thickness** = -1, the circle will be drawn filled. - - *MyPolygon* - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp mypolygon - - To draw a filled polygon we use the function @ref cv::fillPoly . We note that: - - - The polygon will be drawn on **img** - - The vertices of the polygon are the set of points in **ppt** - - The total number of vertices to be drawn are **npt** - - The number of polygons to be drawn is only **1** - - The color of the polygon is defined by **Scalar( 255, 255, 255)**, which is the BGR - value for *white* - - *rectangle* - @snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp rectangle - - Finally we have the @ref cv::rectangle function (we did not create a special function for - this guy). We note that: - - - The rectangle will be drawn on **rook_image** - - Two opposite vertices of the rectangle are defined by *\* Point( 0, 7*w/8 )*\* - andPoint( w, w)*\* - - The color of the rectangle is given by **Scalar(0, 255, 255)** which is the BGR value - for *yellow* - - Since the thickness value is given by **FILLED (-1)**, the rectangle will be filled. +Since we plan to draw two examples (an atom and a rook), we have to create two images and two +windows to display them. +@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp create_images +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java create_images +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py create_images +@end_toggle + +We created functions to draw different geometric shapes. For instance, to draw the atom we used +**MyEllipse** and **MyFilledCircle**: +@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_atom +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_atom +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_atom +@end_toggle + +And to draw the rook we employed **MyLine**, **rectangle** and a **MyPolygon**: +@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_rook +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_rook +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_rook +@end_toggle + + +Let's check what is inside each of these functions: +@add_toggle_cpp +@end_toggle + +

MyLine

+@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_line +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_line +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_line +@end_toggle + +- As we can see, **MyLine** just call the function **line()** , which does the following: + - Draw a line from Point **start** to Point **end** + - The line is displayed in the image **img** + - The line color is defined by ( 0, 0, 0 ) which is the RGB value correspondent + to **Black** + - The line thickness is set to **thickness** (in this case 2) + - The line is a 8-connected one (**lineType** = 8) + +

MyEllipse

+@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_ellipse +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_ellipse +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_ellipse +@end_toggle + +- From the code above, we can observe that the function **ellipse()** draws an ellipse such + that: + + - The ellipse is displayed in the image **img** + - The ellipse center is located in the point (w/2, w/2) and is enclosed in a box + of size (w/4, w/16) + - The ellipse is rotated **angle** degrees + - The ellipse extends an arc between **0** and **360** degrees + - The color of the figure will be ( 255, 0, 0 ) which means blue in BGR value. + - The ellipse's **thickness** is 2. + +

MyFilledCircle

+@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_filled_circle +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_filled_circle +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_filled_circle +@end_toggle + +- Similar to the ellipse function, we can observe that *circle* receives as arguments: + + - The image where the circle will be displayed (**img**) + - The center of the circle denoted as the point **center** + - The radius of the circle: **w/32** + - The color of the circle: ( 0, 0, 255 ) which means *Red* in BGR + - Since **thickness** = -1, the circle will be drawn filled. + +

MyPolygon

+@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_polygon +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_polygon +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_polygon +@end_toggle + +- To draw a filled polygon we use the function **fillPoly()** . We note that: + + - The polygon will be drawn on **img** + - The vertices of the polygon are the set of points in **ppt** + - The color of the polygon is defined by ( 255, 255, 255 ), which is the BGR + value for *white* + +

rectangle

+@add_toggle_cpp +@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp rectangle +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java rectangle +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py rectangle +@end_toggle + +- Finally we have the @ref cv::rectangle function (we did not create a special function for + this guy). We note that: + + - The rectangle will be drawn on **rook_image** + - Two opposite vertices of the rectangle are defined by ( 0, 7*w/8 ) + and ( w, w ) + - The color of the rectangle is given by ( 0, 255, 255 ) which is the BGR value + for *yellow* + - Since the thickness value is given by **FILLED (-1)**, the rectangle will be filled. Result ------ diff --git a/doc/tutorials/core/table_of_content_core.markdown b/doc/tutorials/core/table_of_content_core.markdown index c0453dd611..af040b9145 100644 --- a/doc/tutorials/core/table_of_content_core.markdown +++ b/doc/tutorials/core/table_of_content_core.markdown @@ -58,6 +58,8 @@ understanding how to manipulate the images on a pixel level. - @subpage tutorial_basic_geometric_drawing + *Languages:* C++, Java, Python + *Compatibility:* \> OpenCV 2.0 *Author:* Ana Huamán diff --git a/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp b/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp index 7e184ddc1d..3f23a0b6c5 100644 --- a/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp +++ b/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp @@ -1,8 +1,8 @@ /** * @file Drawing_1.cpp - * @brief Simple sample code + * @brief Simple geometric drawing + * @author OpenCV team */ - #include #include #include @@ -83,11 +83,11 @@ int main( void ){ /// Function Declaration -//![myellipse] /** * @function MyEllipse * @brief Draw a fixed-size ellipse with different angles */ +//![my_ellipse] void MyEllipse( Mat img, double angle ) { int thickness = 2; @@ -103,13 +103,13 @@ void MyEllipse( Mat img, double angle ) thickness, lineType ); } -//![myellipse] +//![my_ellipse] -//![myfilledcircle] /** * @function MyFilledCircle * @brief Draw a fixed-size filled circle */ +//![my_filled_circle] void MyFilledCircle( Mat img, Point center ) { circle( img, @@ -119,13 +119,13 @@ void MyFilledCircle( Mat img, Point center ) FILLED, LINE_8 ); } -//![myfilledcircle] +//![my_filled_circle] -//![mypolygon] /** * @function MyPolygon * @brief Draw a simple concave polygon (rook) */ +//![my_polygon] void MyPolygon( Mat img ) { int lineType = LINE_8; @@ -163,17 +163,18 @@ void MyPolygon( Mat img ) Scalar( 255, 255, 255 ), lineType ); } -//![mypolygon] +//![my_polygon] -//![myline] /** * @function MyLine * @brief Draw a simple line */ +//![my_line] void MyLine( Mat img, Point start, Point end ) { int thickness = 2; int lineType = LINE_8; + line( img, start, end, @@ -181,4 +182,4 @@ void MyLine( Mat img, Point start, Point end ) thickness, lineType ); } -//![myline] +//![my_line] diff --git a/samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java b/samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java new file mode 100644 index 0000000000..d59d99030e --- /dev/null +++ b/samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java @@ -0,0 +1,186 @@ +import org.opencv.core.*; +import org.opencv.core.Point; +import org.opencv.highgui.HighGui; +import org.opencv.imgproc.Imgproc; + +import java.util.*; +import java.util.List; + +class GeometricDrawingRun{ + + private static final int W = 400; + + public void run(){ + //! [create_images] + /// Windows names + String atom_window = "Drawing 1: Atom"; + String rook_window = "Drawing 2: Rook"; + + /// Create black empty images + Mat atom_image = Mat.zeros( W, W, CvType.CV_8UC3 ); + Mat rook_image = Mat.zeros( W, W, CvType.CV_8UC3 ); + //! [create_images] + + //! [draw_atom] + /// 1. Draw a simple atom: + /// ----------------------- + MyEllipse( atom_image, 90.0 ); + MyEllipse( atom_image, 0.0 ); + MyEllipse( atom_image, 45.0 ); + MyEllipse( atom_image, -45.0 ); + + /// 1.b. Creating circles + MyFilledCircle( atom_image, new Point( W/2, W/2) ); + //! [draw_atom] + + //! [draw_rook] + /// 2. Draw a rook + /// ------------------ + /// 2.a. Create a convex polygon + MyPolygon( rook_image ); + + //! [rectangle] + /// 2.b. Creating rectangles + Imgproc.rectangle( rook_image, + new Point( 0, 7*W/8 ), + new Point( W, W), + new Scalar( 0, 255, 255 ), + -1, + 8, + 0 ); + //! [rectangle] + + /// 2.c. Create a few lines + MyLine( rook_image, new Point( 0, 15*W/16 ), new Point( W, 15*W/16 ) ); + MyLine( rook_image, new Point( W/4, 7*W/8 ), new Point( W/4, W ) ); + MyLine( rook_image, new Point( W/2, 7*W/8 ), new Point( W/2, W ) ); + MyLine( rook_image, new Point( 3*W/4, 7*W/8 ), new Point( 3*W/4, W ) ); + //! [draw_rook] + + /// 3. Display your stuff! + HighGui.imshow( atom_window, atom_image ); + HighGui.moveWindow( atom_window, 0, 200 ); + HighGui.imshow( rook_window, rook_image ); + HighGui.moveWindow( rook_window, W, 200 ); + + HighGui.waitKey( 0 ); + System.exit(0); + } + + /// Function Declaration + + /** + * @function MyEllipse + * @brief Draw a fixed-size ellipse with different angles + */ + //! [my_ellipse] + private void MyEllipse( Mat img, double angle ) { + int thickness = 2; + int lineType = 8; + int shift = 0; + + Imgproc.ellipse( img, + new Point( W/2, W/2 ), + new Size( W/4, W/16 ), + angle, + 0.0, + 360.0, + new Scalar( 255, 0, 0 ), + thickness, + lineType, + shift ); + } + //! [my_ellipse] + /** + * @function MyFilledCircle + * @brief Draw a fixed-size filled circle + */ + //! [my_filled_circle] + private void MyFilledCircle( Mat img, Point center ) { + int thickness = -1; + int lineType = 8; + int shift = 0; + + Imgproc.circle( img, + center, + W/32, + new Scalar( 0, 0, 255 ), + thickness, + lineType, + shift ); + } + //! [my_filled_circle] + /** + * @function MyPolygon + * @function Draw a simple concave polygon (rook) + */ + //! [my_polygon] + private void MyPolygon( Mat img ) { + int lineType = 8; + int shift = 0; + + /** Create some points */ + Point[] rook_points = new Point[20]; + rook_points[0] = new Point( W/4, 7*W/8 ); + rook_points[1] = new Point( 3*W/4, 7*W/8 ); + rook_points[2] = new Point( 3*W/4, 13*W/16 ); + rook_points[3] = new Point( 11*W/16, 13*W/16 ); + rook_points[4] = new Point( 19*W/32, 3*W/8 ); + rook_points[5] = new Point( 3*W/4, 3*W/8 ); + rook_points[6] = new Point( 3*W/4, W/8 ); + rook_points[7] = new Point( 26*W/40, W/8 ); + rook_points[8] = new Point( 26*W/40, W/4 ); + rook_points[9] = new Point( 22*W/40, W/4 ); + rook_points[10] = new Point( 22*W/40, W/8 ); + rook_points[11] = new Point( 18*W/40, W/8 ); + rook_points[12] = new Point( 18*W/40, W/4 ); + rook_points[13] = new Point( 14*W/40, W/4 ); + rook_points[14] = new Point( 14*W/40, W/8 ); + rook_points[15] = new Point( W/4, W/8 ); + rook_points[16] = new Point( W/4, 3*W/8 ); + rook_points[17] = new Point( 13*W/32, 3*W/8 ); + rook_points[18] = new Point( 5*W/16, 13*W/16 ); + rook_points[19] = new Point( W/4, 13*W/16 ); + + MatOfPoint matPt = new MatOfPoint(); + matPt.fromArray(rook_points); + + List ppt = new ArrayList(); + ppt.add(matPt); + + Imgproc.fillPoly(img, + ppt, + new Scalar( 255, 255, 255 ), + lineType, + shift, + new Point(0,0) ); + } + //! [my_polygon] + /** + * @function MyLine + * @brief Draw a simple line + */ + //! [my_line] + private void MyLine( Mat img, Point start, Point end ) { + int thickness = 2; + int lineType = 8; + int shift = 0; + + Imgproc.line( img, + start, + end, + new Scalar( 0, 0, 0 ), + thickness, + lineType, + shift ); + } + //! [my_line] +} + +public class BasicGeometricDrawing { + public static void main(String[] args) { + // Load the native library. + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + new GeometricDrawingRun().run(); + } +} diff --git a/samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py b/samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py new file mode 100644 index 0000000000..a6f4098785 --- /dev/null +++ b/samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py @@ -0,0 +1,115 @@ +import cv2 +import numpy as np + +W = 400 +## [my_ellipse] +def my_ellipse(img, angle): + thickness = 2 + line_type = 8 + + cv2.ellipse(img, + (W / 2, W / 2), + (W / 4, W / 16), + angle, + 0, + 360, + (255, 0, 0), + thickness, + line_type) +## [my_ellipse] +## [my_filled_circle] +def my_filled_circle(img, center): + thickness = -1 + line_type = 8 + + cv2.circle(img, + center, + W / 32, + (0, 0, 255), + thickness, + line_type) +## [my_filled_circle] +## [my_polygon] +def my_polygon(img): + line_type = 8 + + # Create some points + ppt = np.array([[W / 4, 7 * W / 8], [3 * W / 4, 7 * W / 8], + [3 * W / 4, 13 * W / 16], [11 * W / 16, 13 * W / 16], + [19 * W / 32, 3 * W / 8], [3 * W / 4, 3 * W / 8], + [3 * W / 4, W / 8], [26 * W / 40, W / 8], + [26 * W / 40, W / 4], [22 * W / 40, W / 4], + [22 * W / 40, W / 8], [18 * W / 40, W / 8], + [18 * W / 40, W / 4], [14 * W / 40, W / 4], + [14 * W / 40, W / 8], [W / 4, W / 8], + [W / 4, 3 * W / 8], [13 * W / 32, 3 * W / 8], + [5 * W / 16, 13 * W / 16], [W / 4, 13 * W / 16]], np.int32) + ppt = ppt.reshape((-1, 1, 2)) + cv2.fillPoly(img, [ppt], (255, 255, 255), line_type) + # Only drawind the lines would be: + # cv2.polylines(img, [ppt], True, (255, 0, 255), line_type) +## [my_polygon] +## [my_line] +def my_line(img, start, end): + thickness = 2 + line_type = 8 + + cv2.line(img, + start, + end, + (0, 0, 0), + thickness, + line_type) +## [my_line] +## [create_images] +# Windows names +atom_window = "Drawing 1: Atom" +rook_window = "Drawing 2: Rook" + +# Create black empty images +size = W, W, 3 +atom_image = np.zeros(size, dtype=np.uint8) +rook_image = np.zeros(size, dtype=np.uint8) +## [create_images] +## [draw_atom] +# 1. Draw a simple atom: +# ----------------------- + +# 1.a. Creating ellipses +my_ellipse(atom_image, 90) +my_ellipse(atom_image, 0) +my_ellipse(atom_image, 45) +my_ellipse(atom_image, -45) + +# 1.b. Creating circles +my_filled_circle(atom_image, (W / 2, W / 2)) +## [draw_atom] +## [draw_rook] + +# 2. Draw a rook +# ------------------ +# 2.a. Create a convex polygon +my_polygon(rook_image) +## [rectangle] +# 2.b. Creating rectangles +cv2.rectangle(rook_image, + (0, 7 * W / 8), + (W, W), + (0, 255, 255), + -1, + 8) +## [rectangle] + +# 2.c. Create a few lines +my_line(rook_image, (0, 15 * W / 16), (W, 15 * W / 16)) +my_line(rook_image, (W / 4, 7 * W / 8), (W / 4, W)) +my_line(rook_image, (W / 2, 7 * W / 8), (W / 2, W)) +my_line(rook_image, (3 * W / 4, 7 * W / 8), (3 * W / 4, W)) +## [draw_rook] +cv2.imshow(atom_window, atom_image) +cv2.moveWindow(atom_window, 0, 200) +cv2.imshow(rook_window, rook_image) +cv2.moveWindow(rook_window, W, 200) + +cv2.waitKey(0) +cv2.destroyAllWindows()