目標(biāo)
在本教程中莉恼,將學(xué)習(xí)如何:
- 使用OpenCV函數(shù)行()繪制一行
- 使用OpenCV函數(shù)橢圓()繪制橢圓
- 使用OpenCV函數(shù)矩形()繪制一個(gè)矩形
- 使用OpenCV函數(shù)圈()繪制一個(gè)圓
- 使用OpenCV函數(shù)fillPoly()繪制一個(gè)填充的多邊形
OpenCV理論
對(duì)于本教程,大量使用兩個(gè)結(jié)構(gòu):cv :: Point和cv :: Scalar:
point
2D point, 由圖像 x, y坐標(biāo)確定吨拍,可以定義成:
Point pt;
pt.x = 10;
pt.y = 8;
或
Point pt = Point(10, 8);
Scalar
代表一個(gè)4元素向量。Scalar類型廣泛用于OpenCV中痪伦,用于傳遞像素值耍鬓。
在本教程中阔籽,我們將廣泛使用它來表示BGR顏色值(3個(gè)參數(shù))流妻。如果不使用最后一個(gè)參數(shù)牲蜀,則無需定義最后一個(gè)參數(shù)。
讓我們看一個(gè)例子绅这,如果我們被要求一個(gè)顏色參數(shù)涣达,我們給:
Scalar(a, b, c)
將定義一個(gè)BGR顏色,例如:Blue = a证薇,Green = b和Red = c.
代碼實(shí)現(xiàn)
#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);
}
解釋
繪制兩個(gè)例子(一個(gè)原子和一個(gè)車)度苔,我們必須創(chuàng)建兩個(gè)圖像和兩個(gè)窗口來顯示它們。
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);
我們創(chuàng)建了繪制不同幾何形狀的功能浑度。例如寇窑,為了繪制原子,我們使用MyEllipse和MyFilledCircle:
MyEllipse(atom_image, 90);
MyEllipse(atom_image, 0);
MyEllipse(atom_image, 45);
MyEllipse(atom_image, -45);
MyFilledCircle(atom_image, Point(w / 2, w / 2));
并提請(qǐng)我們所使用的車MYLINE箩张,矩形和MyPolygon:
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));
MyLine
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);
}
我們可以看到甩骏,MyLine只是調(diào)用函數(shù)line(),它執(zhí)行以下操作:
- 從開始點(diǎn)到結(jié)束點(diǎn)繪制一條線
- 該行顯示在圖像img中
- 線顏色由(0,0,0)定義, 它是與黑色相對(duì)應(yīng)的RGB值
- 線厚度設(shè)定為thickness(在這種情況下為2)
- 線是8連接線(lineType = 8)
MyEllipse
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);
}
從上面的代碼先慷,我們可以看到函數(shù)ellipse()繪制一個(gè)橢圓饮笛,使得:
- 橢圓顯示在圖像img中
- 橢圓中心位于(w / 2,w / 2)點(diǎn), 大小(w / 4论熙,w / 16)
- 定義橢圓旋轉(zhuǎn)角度
- 橢圓延伸0到360度之間的圓弧
- 圖中的顏色將為(255,0,0)福青,表示BGR值為藍(lán)色。
- 橢圓的厚度為2
MyFilledCircle
void MyFilledCircle(Mat img, Point center)
{
circle(img,
center,
w / 32,
Scalar(0, 0, 255),
FILLED,
LINE_8);
}
類似于橢圓函數(shù)脓诡,我們可以觀察到圓接受作為參數(shù):
- 將圓圈顯示到圖像(img)
- 圓的中心表示為點(diǎn)中心
- 圓的半徑:w / 32
- 圓的顏色:(0,0,255)无午,表示BGR中的紅色
- 由于厚度 = -1,圓將被繪制填充
MyPolygon
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);
}
要繪制一個(gè)填充的多邊形祝谚,我們使用函數(shù)fillPoly()宪迟。我們注意到:
- 多邊形將在img上繪制
- 多邊形的頂點(diǎn)是ppt中的一組點(diǎn)
- 多邊形的顏色由(255,255,255)定義,它是白色的BGR值