mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Tutorial Basic Geometric Drawing
This commit is contained in:
parent
c4c1e94088
commit
13317bdfda
@ -1,19 +1,21 @@
|
|||||||
Basic Drawing {#tutorial_basic_geometric_drawing}
|
Basic Drawing {#tutorial_basic_geometric_drawing}
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@prev_tutorial{tutorial_basic_linear_transform}
|
||||||
|
@next_tutorial{tutorial_random_generator_and_text}
|
||||||
|
|
||||||
Goals
|
Goals
|
||||||
-----
|
-----
|
||||||
|
|
||||||
In this tutorial you will learn how to:
|
In this tutorial you will learn how to:
|
||||||
|
|
||||||
- Use @ref cv::Point to define 2D points in an image.
|
- Draw a **line** by using the OpenCV function **line()**
|
||||||
- Use @ref cv::Scalar and why it is useful
|
- Draw an **ellipse** by using the OpenCV function **ellipse()**
|
||||||
- Draw a **line** by using the OpenCV function @ref cv::line
|
- Draw a **rectangle** by using the OpenCV function **rectangle()**
|
||||||
- Draw an **ellipse** by using the OpenCV function @ref cv::ellipse
|
- Draw a **circle** by using the OpenCV function **circle()**
|
||||||
- Draw a **rectangle** by using the OpenCV function @ref cv::rectangle
|
- Draw a **filled polygon** by using the OpenCV function **fillPoly()**
|
||||||
- Draw a **circle** by using the OpenCV function @ref cv::circle
|
|
||||||
- Draw a **filled polygon** by using the OpenCV function @ref cv::fillPoly
|
|
||||||
|
|
||||||
|
@add_toggle_cpp
|
||||||
OpenCV Theory
|
OpenCV Theory
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@ -42,86 +44,217 @@ Point pt = Point(10, 8);
|
|||||||
Scalar( a, b, c )
|
Scalar( a, b, c )
|
||||||
@endcode
|
@endcode
|
||||||
We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c*
|
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
|
Code
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@add_toggle_cpp
|
||||||
- This code is in your OpenCV sample folder. Otherwise you can grab it from
|
- 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
|
@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
|
Explanation
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
-# Since we plan to draw two examples (an atom and a rook), we have to create two images and two
|
Since we plan to draw two examples (an atom and a rook), we have to create two images and two
|
||||||
windows to display them.
|
windows to display them.
|
||||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp create_images
|
@add_toggle_cpp
|
||||||
|
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp create_images
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
-# We created functions to draw different geometric shapes. For instance, to draw the atom we used
|
@add_toggle_java
|
||||||
*MyEllipse* and *MyFilledCircle*:
|
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java create_images
|
||||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_atom
|
@end_toggle
|
||||||
|
|
||||||
-# And to draw the rook we employed *MyLine*, *rectangle* and a *MyPolygon*:
|
@add_toggle_python
|
||||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_rook
|
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py create_images
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
-# Let's check what is inside each of these functions:
|
We created functions to draw different geometric shapes. For instance, to draw the atom we used
|
||||||
- *MyLine*
|
**MyEllipse** and **MyFilledCircle**:
|
||||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp myline
|
@add_toggle_cpp
|
||||||
|
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_atom
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
As we can see, *MyLine* just call the function @ref cv::line , which does the following:
|
@add_toggle_java
|
||||||
|
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_atom
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
- Draw a line from Point **start** to Point **end**
|
@add_toggle_python
|
||||||
- The line is displayed in the image **img**
|
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_atom
|
||||||
- The line color is defined by **Scalar( 0, 0, 0)** which is the RGB value correspondent
|
@end_toggle
|
||||||
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
|
And to draw the rook we employed **MyLine**, **rectangle** and a **MyPolygon**:
|
||||||
that:
|
@add_toggle_cpp
|
||||||
|
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_rook
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
- The ellipse is displayed in the image **img**
|
@add_toggle_java
|
||||||
- The ellipse center is located in the point **(w/2, w/2)** and is enclosed in a box
|
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_rook
|
||||||
of size **(w/4, w/16)**
|
@end_toggle
|
||||||
- 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:
|
@add_toggle_python
|
||||||
|
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_rook
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
- 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:
|
Let's check what is inside each of these functions:
|
||||||
|
@add_toggle_cpp
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
- The polygon will be drawn on **img**
|
<H4>MyLine</H4>
|
||||||
- The vertices of the polygon are the set of points in **ppt**
|
@add_toggle_cpp
|
||||||
- The total number of vertices to be drawn are **npt**
|
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_line
|
||||||
- The number of polygons to be drawn is only **1**
|
@end_toggle
|
||||||
- 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
|
@add_toggle_java
|
||||||
this guy). We note that:
|
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_line
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
- The rectangle will be drawn on **rook_image**
|
@add_toggle_python
|
||||||
- Two opposite vertices of the rectangle are defined by *\* Point( 0, 7*w/8 )*\*
|
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_line
|
||||||
andPoint( w, w)*\*
|
@end_toggle
|
||||||
- The color of the rectangle is given by **Scalar(0, 255, 255)** which is the BGR value
|
|
||||||
for *yellow*
|
- As we can see, **MyLine** just call the function **line()** , which does the following:
|
||||||
- Since the thickness value is given by **FILLED (-1)**, the rectangle will be filled.
|
- Draw a line from Point **start** to Point **end**
|
||||||
|
- The line is displayed in the image **img**
|
||||||
|
- The line color is defined by <B>( 0, 0, 0 )</B> 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)
|
||||||
|
|
||||||
|
<H4>MyEllipse</H4>
|
||||||
|
@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 <B>(w/2, w/2)</B> and is enclosed in a box
|
||||||
|
of size <B>(w/4, w/16)</B>
|
||||||
|
- The ellipse is rotated **angle** degrees
|
||||||
|
- The ellipse extends an arc between **0** and **360** degrees
|
||||||
|
- The color of the figure will be <B>( 255, 0, 0 )</B> which means blue in BGR value.
|
||||||
|
- The ellipse's **thickness** is 2.
|
||||||
|
|
||||||
|
<H4>MyFilledCircle</H4>
|
||||||
|
@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: <B>( 0, 0, 255 )</B> which means *Red* in BGR
|
||||||
|
- Since **thickness** = -1, the circle will be drawn filled.
|
||||||
|
|
||||||
|
<H4>MyPolygon</H4>
|
||||||
|
@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 <B>( 255, 255, 255 )</B>, which is the BGR
|
||||||
|
value for *white*
|
||||||
|
|
||||||
|
<H4>rectangle</H4>
|
||||||
|
@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 <B>( 0, 7*w/8 )</B>
|
||||||
|
and <B>( w, w )</B>
|
||||||
|
- The color of the rectangle is given by <B>( 0, 255, 255 )</B> which is the BGR value
|
||||||
|
for *yellow*
|
||||||
|
- Since the thickness value is given by **FILLED (-1)**, the rectangle will be filled.
|
||||||
|
|
||||||
Result
|
Result
|
||||||
------
|
------
|
||||||
|
@ -58,6 +58,8 @@ understanding how to manipulate the images on a pixel level.
|
|||||||
|
|
||||||
- @subpage tutorial_basic_geometric_drawing
|
- @subpage tutorial_basic_geometric_drawing
|
||||||
|
|
||||||
|
*Languages:* C++, Java, Python
|
||||||
|
|
||||||
*Compatibility:* \> OpenCV 2.0
|
*Compatibility:* \> OpenCV 2.0
|
||||||
|
|
||||||
*Author:* Ana Huamán
|
*Author:* Ana Huamán
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* @file Drawing_1.cpp
|
* @file Drawing_1.cpp
|
||||||
* @brief Simple sample code
|
* @brief Simple geometric drawing
|
||||||
|
* @author OpenCV team
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <opencv2/core.hpp>
|
#include <opencv2/core.hpp>
|
||||||
#include <opencv2/imgproc.hpp>
|
#include <opencv2/imgproc.hpp>
|
||||||
#include <opencv2/highgui.hpp>
|
#include <opencv2/highgui.hpp>
|
||||||
@ -83,11 +83,11 @@ int main( void ){
|
|||||||
|
|
||||||
/// Function Declaration
|
/// Function Declaration
|
||||||
|
|
||||||
//![myellipse]
|
|
||||||
/**
|
/**
|
||||||
* @function MyEllipse
|
* @function MyEllipse
|
||||||
* @brief Draw a fixed-size ellipse with different angles
|
* @brief Draw a fixed-size ellipse with different angles
|
||||||
*/
|
*/
|
||||||
|
//![my_ellipse]
|
||||||
void MyEllipse( Mat img, double angle )
|
void MyEllipse( Mat img, double angle )
|
||||||
{
|
{
|
||||||
int thickness = 2;
|
int thickness = 2;
|
||||||
@ -103,13 +103,13 @@ void MyEllipse( Mat img, double angle )
|
|||||||
thickness,
|
thickness,
|
||||||
lineType );
|
lineType );
|
||||||
}
|
}
|
||||||
//![myellipse]
|
//![my_ellipse]
|
||||||
|
|
||||||
//![myfilledcircle]
|
|
||||||
/**
|
/**
|
||||||
* @function MyFilledCircle
|
* @function MyFilledCircle
|
||||||
* @brief Draw a fixed-size filled circle
|
* @brief Draw a fixed-size filled circle
|
||||||
*/
|
*/
|
||||||
|
//![my_filled_circle]
|
||||||
void MyFilledCircle( Mat img, Point center )
|
void MyFilledCircle( Mat img, Point center )
|
||||||
{
|
{
|
||||||
circle( img,
|
circle( img,
|
||||||
@ -119,13 +119,13 @@ void MyFilledCircle( Mat img, Point center )
|
|||||||
FILLED,
|
FILLED,
|
||||||
LINE_8 );
|
LINE_8 );
|
||||||
}
|
}
|
||||||
//![myfilledcircle]
|
//![my_filled_circle]
|
||||||
|
|
||||||
//![mypolygon]
|
|
||||||
/**
|
/**
|
||||||
* @function MyPolygon
|
* @function MyPolygon
|
||||||
* @brief Draw a simple concave polygon (rook)
|
* @brief Draw a simple concave polygon (rook)
|
||||||
*/
|
*/
|
||||||
|
//![my_polygon]
|
||||||
void MyPolygon( Mat img )
|
void MyPolygon( Mat img )
|
||||||
{
|
{
|
||||||
int lineType = LINE_8;
|
int lineType = LINE_8;
|
||||||
@ -163,17 +163,18 @@ void MyPolygon( Mat img )
|
|||||||
Scalar( 255, 255, 255 ),
|
Scalar( 255, 255, 255 ),
|
||||||
lineType );
|
lineType );
|
||||||
}
|
}
|
||||||
//![mypolygon]
|
//![my_polygon]
|
||||||
|
|
||||||
//![myline]
|
|
||||||
/**
|
/**
|
||||||
* @function MyLine
|
* @function MyLine
|
||||||
* @brief Draw a simple line
|
* @brief Draw a simple line
|
||||||
*/
|
*/
|
||||||
|
//![my_line]
|
||||||
void MyLine( Mat img, Point start, Point end )
|
void MyLine( Mat img, Point start, Point end )
|
||||||
{
|
{
|
||||||
int thickness = 2;
|
int thickness = 2;
|
||||||
int lineType = LINE_8;
|
int lineType = LINE_8;
|
||||||
|
|
||||||
line( img,
|
line( img,
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@ -181,4 +182,4 @@ void MyLine( Mat img, Point start, Point end )
|
|||||||
thickness,
|
thickness,
|
||||||
lineType );
|
lineType );
|
||||||
}
|
}
|
||||||
//![myline]
|
//![my_line]
|
||||||
|
@ -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<MatOfPoint> ppt = new ArrayList<MatOfPoint>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
Loading…
Reference in New Issue
Block a user