公式チュートリアルのBasic Drawingの要約。
筆者の環境はdebian9
やること
- 線
line()
- 楕円
ellipse()
- 矩形
rectangle()
- 円
circle()
- 塗りつぶされたポリゴン
fillPoly()
を使用して図形を描画する
よく使うデータ構造
Point
x, yで指定された2次元の点。
座標の設定は
Point pt;
pt.x = 10;
pt.y = 8;
またはコンストラクタ
Point pt = Point(10, 8);
Scalar
-
名前はScalarだが4要素のベクトルを表す。ピクセルの値を渡すのによく使う。
cv::Vec< _Tp, cn >
の派生クラス。継承関係は画像の通り
-
BGRで色を指定する(3パラメータ)。必要ないなら4番目(アルファ)は設定不要
-
Scalar( a, b, c )
とすると、BGRカラーではBlue=a, Green=b, Red=cとして定義している。
コード全体
原子モデル図と、ルーク(チェスの駒)図を描画する。
draw.cpp
# 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 ){
//2枚描画するのでウィンドウ、画像配列とも2つ作る
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;
//中心が( w/2, w/2 ),( w/4, w/16 )の矩形に囲まれる楕円
//angle度だけ回転しており、弧は0~360度(途切れていない)
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 )
{
//中心center, 半径w/32の円。色は赤(Scalar( 0, 0, 255 ))
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 );
//描画するための頂点をpptに入れる
const Point* ppt[1] = { rook_points[0] };
int npt[] = { 20 };
fillPoly( img,
ppt,
npt,
1,
Scalar( 255, 255, 255 ),
lineType );
}
//start から end まで線を引く。imgに描画される
void MyLine( Mat img, Point start, Point end )
{
int thickness = 2;
int lineType = LINE_8; //8-connected(隣接するピクセルを、
//上下左右とななめ方向も含めた8ピクセルで定義する方法)
line( img,
start,
end,
Scalar( 0, 0, 0 ),
thickness,
lineType );
}
コンパイル
g++ draw.cpp -I/usr/local/include/opencv2 -I/usr/local/include/opencv -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc