从头开始opencv(八)——core:Basic drawing
Goals
- 画一条线
- 画一个椭圆
- 画一个矩形
- 画一个圆
- 画一个填充多边形
OpenCV Theory
我们将会频繁使用的是:cv::Point()
和cv::Scalar()
Point
代表了一个二维的点的坐标。
//method 1
Point pt;
pt.x = 10;
pt.y = 8;
//method 2
Point pt = Point(10, 8);
Scalar
是一个四维的向量。
在opencv中,我们一般用scalar来代表BGR三分量,第四个值一般不显式出现。换种说法,scalar可以用来代表任意的四维向量,但是每一个向量都不是一定要的,最多是四维的。我们在opencv中多使用前三个通道来表示BGR三分量。
Scalar( a, b, c )
Code
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#define w 400
using namespace cv;
void MyEllipse(Mat img, double angle);
void MyFilledCircle(Mat img, Point center);
void MyPolygon(Mat img);
void MyLine(Mat img, Point start, Point end);
int main(void) {
char atom_window[] = "Drawing 1: Atom";
char rook_window[] = "Drawing 2: Rook";
Mat atom_image = Mat::zeros(w, w, CV_8UC3);
Mat rook_image = Mat::zeros(w, w, CV_8UC3);
MyEllipse(atom_image, 90);
MyEllipse(atom_image, 0);
MyEllipse(atom_image, 45);
MyEllipse(atom_image, -45);
MyFilledCircle(atom_image, Point(w / 2, w / 2));
MyPolygon(rook_image);
rectangle(rook_image,
Point(0, 7 * w / 8),
Point(w, w),
Scalar(0, 255, 255),
FILLED,
LINE_8);
MyLine(rook_image, Point(0, 15 * w / 16), Point(w, 15 * w / 16));
MyLine(rook_image, Point(w / 4, 7 * w / 8), Point(w / 4, w));
MyLine(rook_image, Point(w / 2, 7 * w / 8), Point(w / 2, w));
MyLine(rook_image, Point(3 * w / 4, 7 * w / 8), Point(3 * w / 4, w));
imshow(atom_window, atom_image);
moveWindow(atom_window, 0, 200);
imshow(rook_window, rook_image);
moveWindow(rook_window, w, 200);
waitKey(0);
return(0);
}
void MyEllipse(Mat img, double angle)
{
int thickness = 2;
int lineType = 8;
ellipse(img,
Point(w / 2, w / 2),
Size(w / 4, w / 16),
angle,
0,
360,
Scalar(255, 0, 0),
thickness,
lineType);
}
void MyFilledCircle(Mat img, Point center)
{
circle(img,
center,
w / 32,
Scalar(0, 0, 255),
FILLED,
LINE_8);
}
void MyPolygon(Mat img)
{
int lineType = LINE_8;
Point rook_points[1][20];
rook_points[0][0] = Point(w / 4, 7 * w / 8);
rook_points[0][1] = Point(3 * w / 4, 7 * w / 8);
rook_points[0][2] = Point(3 * w / 4, 13 * w / 16);
rook_points[0][3] = Point(11 * w / 16, 13 * w / 16);
rook_points[0][4] = Point(19 * w / 32, 3 * w / 8);
rook_points[0][5] = Point(3 * w / 4, 3 * w / 8);
rook_points[0][6] = Point(3 * w / 4, w / 8);
rook_points[0][7] = Point(26 * w / 40, w / 8);
rook_points[0][8] = Point(26 * w / 40, w / 4);
rook_points[0][9] = Point(22 * w / 40, w / 4);
rook_points[0][10] = Point(22 * w / 40, w / 8);
rook_points[0][11] = Point(18 * w / 40, w / 8);
rook_points[0][12] = Point(18 * w / 40, w / 4);
rook_points[0][13] = Point(14 * w / 40, w / 4);
rook_points[0][14] = Point(14 * w / 40, w / 8);
rook_points[0][15] = Point(w / 4, w / 8);
rook_points[0][16] = Point(w / 4, 3 * w / 8);
rook_points[0][17] = Point(13 * w / 32, 3 * w / 8);
rook_points[0][18] = Point(5 * w / 16, 13 * w / 16);
rook_points[0][19] = Point(w / 4, 13 * w / 16);
const Point* ppt[1] = { rook_points[0] };
int npt[] = { 20 };
fillPoly(img,
ppt,
npt,
1,
Scalar(255, 255, 255),
lineType);
}
void MyLine(Mat img, Point start, Point end)
{
int thickness = 2;
int lineType = LINE_8;
line(img,
start,
end,
Scalar(0, 0, 0),
thickness,
lineType);
}
结果:
代码看起来非常的简单。下面我们来看各种形状实现的代码函数原型。
ellipse()
ellipse()
有两种实现模式。
//method 1
void cv::ellipse (
InputOutputArray img, //image
Point center, //center of the ellipse
Size axes, //Half of the size of the ellipse main axes
double angle, //Ellipse rotation angle in degrees
double startAngle,//Starting angle of the elliptic arc n degrees
double endAngle,//Ending angle of the elliptic arc in degress
const Scalar & color,//Ellipse color
int thickness = 1,//Thickness of the ellipse arc outline
int lineType = LINE_8,//type of the ellipse boundary
int shift = 0 //number of fractional bits in the coordinates of the center and values of axes
)
//method 2
void cv::ellipse (
InputOutputArray img,//image
const RotatedRect & box,//the function draws an ellipse inscribed in the rotated rectangle
const Scalar & color,//ellipse color
int thickness = 1,//thickness of the ellipse arc outline
int lineType = LINE_8//type of the ellipse boundary
)
angle
所代表的旋转是顺时针旋转的。
LineTypes:
FILLED LINE_4 4-connected line LINE_8 8-connected line LINE_AA antialiased line(抗锯齿线) 【说明】:linetype参数并不是指的线型是实线、虚线还是点画线,这个参数实际用途是改变线的产生算法。
因为分辨率的关系,直线是使用光栅的形式表示的。
8联通:
4联通:
4联通法消除了8联通法中线断裂的瑕疵,可以说是一种更好的方式,但是8联通法在算法的是线上更为简单,所以一般来讲我们会选择8联通算法。
Circle()
void cv::circle (
InputOutputArray img,//image where the circle is drawn
Point center,//center of the circle
int radius,//radius of the circle
const Scalar & color,//circle color
int thickness = 1,//thickness of the circle outline
int lineType = LINE_8,//type of the circle boundary
int shift = 0 //Number of fractional bits in the coordinates of the center and in the radius value
)
fillPoly()
fillPoly()
有两种实现模式。
//method 1
void cv::fillPoly (
Mat & img,
const Point ** pts,
const int * npts,
int ncontours,
const Scalar & color,
int lineType = LINE_8,
int shift = 0,
Point offset = Point()
)
//method 2
void cv::fillPoly (
InputOutputArray img,//image
InputArrayOfArrays pts,//array of polygons where each polygon is represented as an array of points
const Scalar & color,//polygon color
int lineType = LINE_8,//type of the polygon boundaries
int shift = 0,//number of fractional bits in the vertex coordinates
Point offset = Point() //optional offset of all points of the contours
)
rectangle()
rectangle()
也有两种实现模式。
//method 1
void cv::rectangle (
InputOutputArray img,//image
Point pt1,//vertex of the rectangle
Point pt2,//vertex of the rectangle opposite to pt1
const Scalar & color,//rectangle color or brightness
int thickness = 1,//thickness of lines that make up the rectangle
int lineType = LINE_8,//type of the line
int shift = 0 //number of the fractional bits in the point coordinates
)
//method 2
void cv::rectangle (
Mat & img,
Rect rec,//绘制矩形的替代规范
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
)
Rect
对象的定义:
typedef Rect_<int> Rect;
Rect_
的定义:
/*!
The 2D up-right rectangle class
The class represents a 2D rectangle with coordinates of the specified data type.
Normally, cv::Rect ~ cv::Rect_<int> is used.
*/
template<typename _Tp> class Rect_
{
public:
typedef _Tp value_type;
//! various constructors
Rect_();
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
Rect_(const Rect_& r);
Rect_(const CvRect& r);
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
Rect_& operator = ( const Rect_& r );
//! the top-left corner
Point_<_Tp> tl() const;
//! the bottom-right corner
Point_<_Tp> br() const;
//! size (width, height) of the rectangle
Size_<_Tp> size() const;
//! area (width*height) of the rectangle
_Tp area() const;
//! conversion to another data type
template<typename _Tp2> operator Rect_<_Tp2>() const;
//! conversion to the old-style CvRect
operator CvRect() const;
//! checks whether the rectangle contains the point
bool contains(const Point_<_Tp>& pt) const;
_Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
};
Line()
void cv::line (
InputOutputArray img,//image
Point pt1,//first point of the line segment
Point pt2,//second point of the line segment
const Scalar & color,//line color
int thickness = 1,//line thickness
int lineType = LINE_8,//type of the line
int shift = 0 //number of fractional bits in the point coordinates
)