jashliao 用 VC++ 實現 fanfuhan OpenCV 教學015 ~ opencv-015-圖像/畫布上繪製幾何形狀及隨機數的生成(繪圖/幾何圖/多邊形/秀英文字/畫線/建立畫布)[line()、ellipse()、circle()、rectangle()、putText()、polylines()]
jashliao 用 VC++ 實現 fanfuhan OpenCV 教學015 ~ opencv-015-圖像/畫布上繪製幾何形狀及隨機數的生成(繪圖/幾何圖/多邊形/秀英文字/畫線/建立畫布)[line()、ellipse()、circle()、rectangle()、putText()、polylines()]
資料來源: https://fanfuhan.github.io/
https://fanfuhan.github.io/2019/03/28/opencv-015/
GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV
https://github.com/jash-git/jashliao-implements-FANFUHAN-OPENCV-with-VC
★前言:
★主題:
OPENCV提供的一系列的簡易繪圖函數,下列我就整理常用的[line()、ellipse()、circle()、rectangle()、putText()、polylines()]函數做簡單介紹:
01.OpenCV 畫線
void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
img:輸入圖,線會畫在上面。
pt1:線的起點。
pt2:線的終點。
color:線的顏色。
thickness:線的厚度。
lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。
02.OpenCV 畫矩形
void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
img:輸入圖,矩形會畫在上面。
pt1:矩形頂點。
pt2:矩形頂點,pt1的對角邊
color:矩形的顏色。
thickness:矩形的邊線寬度,輸入負值或CV_FILLED代表填滿矩形。
lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。
03.OpenCV 畫圓
void circle(Mat& img, Point center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
img:輸入圖,圓會畫在上面。
center:圓心。
radius:圓半徑。
color:圓形的顏色。
thickness:圓形的邊線寬度,輸入負值或CV_FILLED代表填滿圓形。
lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。
04.OpenCV 畫橢圓
void ellipse(Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
img:輸入圖,橢圓會畫在上面。
center:圓心。
axes:橢圓軸的尺寸。
angle:旋轉角度,單位角度。
startAngle:橢圓弧度起始角度,單位角度。
endAngle:橢圓弧度結束角度,單位角度。
color:橢圓的顏色。
thickness:橢圓的邊線寬度,輸入負值或CV_FILLED代表填滿橢圓形 。
lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。
05.OpenCV 畫多角形
void polylines(Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed, const Scalar& color, int thickness=1, intlineType=8, int shift=0)
img:輸入圖,多角形會畫在上面。
pts:包含多角形各個曲線點的陣列。
npts:包含多角形各曲線頂點數目的陣列。
ncontours:曲線數。
isClosed:是否為封閉的多角形。
color:多角形的顏色。
thickness:多角形的邊線寬度,輸入負值或CV_FILLED代表填滿多角形。
lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。
06.OpenCV 畫文字字串
void putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false)
img:輸入圖,字串會畫在上面。
text:輸出字串,OpenCV目前沒有支援中文文字顯現。
org:文字左下角位置。
fontFace:字體樣式。
fontScale:字體大小。
color:字串顏色。
thickness:構成字串的線寬度。
lineType:通道型態,有以下三種可選: 8:8通道連結。 4:4通道連結。 CV_AA:消除鋸齒(antialiased line),消除顯示器畫面橢圓邊緣的凹凸鋸齒。
★C++
// VC_FANFUHAN_OPENCV015.cpp : 定義主控台應用程式的進入點。 // /* // Debug | x32 通用屬性 | C/C++ | | 一般 | | 其他 Include 目錄 -> C:\opencv\build\include | | 連結器 | |一一般 | | 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib | | |一輸入 | | 其他相依性 -> opencv_world411d.lib;%(AdditionalDependencies) // Releas | x64 組態屬性 | C/C++ | | 一般 | | 其他 Include 目錄 -> C:\opencv\build\include | | 連結器 | |一般 | | 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib | | |一輸入 | | 其他相依性 -> opencv_world411.lib;%(AdditionalDependencies) */ #include "stdafx.h" #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; void pause() { printf("Press Enter key to continue..."); fgetc(stdin); } int main() { /* OpenCV 畫線 void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0) img:輸入圖,線會畫在上面。 pt1:線的起點。 pt2:線的終點。 color:線的顏色。 thickness:線的厚度。 lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。 OpenCV 畫矩形 void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0) img:輸入圖,矩形會畫在上面。 pt1:矩形頂點。 pt2:矩形頂點,pt1的對角邊 color:矩形的顏色。 thickness:矩形的邊線寬度,輸入負值或CV_FILLED代表填滿矩形。 lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。 OpenCV 畫圓 void circle(Mat& img, Point center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0) img:輸入圖,圓會畫在上面。 center:圓心。 radius:圓半徑。 color:圓形的顏色。 thickness:圓形的邊線寬度,輸入負值或CV_FILLED代表填滿圓形。 lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。 OpenCV 畫橢圓 void ellipse(Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0) img:輸入圖,橢圓會畫在上面。 center:圓心。 axes:橢圓軸的尺寸。 angle:旋轉角度,單位角度。 startAngle:橢圓弧度起始角度,單位角度。 endAngle:橢圓弧度結束角度,單位角度。 color:橢圓的顏色。 thickness:橢圓的邊線寬度,輸入負值或CV_FILLED代表填滿橢圓形 。 lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。 OpenCV 畫多角形 void polylines(Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed, const Scalar& color, int thickness=1, intlineType=8, int shift=0) img:輸入圖,多角形會畫在上面。 pts:包含多角形各個曲線點的陣列。 npts:包含多角形各曲線頂點數目的陣列。 ncontours:曲線數。 isClosed:是否為封閉的多角形。 color:多角形的顏色。 thickness:多角形的邊線寬度,輸入負值或CV_FILLED代表填滿多角形。 lineType:通道型態,可輸入8、4、CV_AA: 8->8通道連結。 4->4通道連結。 CV_AA->消除鋸齒(antialiased line),消除顯示器畫面線邊緣的凹凸鋸齒。 OpenCV 畫文字字串 void putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false) img:輸入圖,字串會畫在上面。 text:輸出字串,OpenCV目前沒有支援中文文字顯現。 org:文字左下角位置。 fontFace:字體樣式。 fontScale:字體大小。 color:字串顏色。 thickness:構成字串的線寬度。 lineType:通道型態,有以下三種可選: 8:8通道連結。 4:4通道連結。 CV_AA:消除鋸齒(antialiased line),消除顯示器畫面橢圓邊緣的凹凸鋸齒。 */ Mat src_bgr = imread("../../images/test.png"); if (src_bgr.empty()) { cout << "could not load image.." << endl; pause(); return -1; } else { imshow("input_bgr", src_bgr); Mat image = Mat::zeros(Size(512, 512), CV_8UC3);//建立彩色黑底畫布 Rect rect(100, 100, 200, 200);//建立一個矩形 // 绘制 rectangle(image, rect, Scalar(255, 0, 0), 2, LINE_8, 0);//繪製未填滿顏色的藍色邊框矩形 circle(image, Point(256, 256), 50, Scalar(0, 255, 0), 2, LINE_8, 0);//繪製未填滿顏色的綠色邊框圓形 ellipse(image, Point(256, 256), Size(150, 50), 360, 0, 360, Scalar(0, 0, 255), 2, LINE_8, 0);//繪製未填滿顏色的紅色色邊框橢圓形 imshow("image_draw", image); // 填充 thickness=-1 or FILLED rectangle(image, rect, Scalar(255, 0, 0), FILLED, LINE_8, 0); ellipse(image, Point(256, 256), Size(150, 50), 360, 0, 360, Scalar(0, 0, 255), FILLED, LINE_8, 0); circle(image, Point(256, 256), 50, Scalar(0, 255, 0), -1, LINE_8, 0); imshow("image_fill", image); // 随机数/亂數 RNG rng(0xFFFFFF); image.setTo(Scalar(0, 0, 0)); Mat image_copy = image.clone(); for (int i = 0; i < 100000; ++i) { int x1 = rng.uniform(0, 512); int y1 = rng.uniform(0, 512); int x2 = rng.uniform(0, 512); int y2 = rng.uniform(0, 512); int b = rng.uniform(0, 256); int g = rng.uniform(0, 256); int r = rng.uniform(0, 256); rect.x = x1; rect.y = y1; rect.width = x2 - x1; rect.height = y2 - y1; // LINE_AA 反锯齿 line(image, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 1, LINE_AA, 0);//畫彩色線段 rectangle(image_copy, rect, Scalar(b, g, r), 1, LINE_AA, 0); imshow("image_line", image); imshow("image_rect", image_copy); char c = waitKey(20); if (c == 27)// ESC { break; } } //----------------------------------------- Mat img(488, 400, CV_8UC3, Scalar(255, 255, 255));//建立彩色白底畫布 line(img, Point(20, 40), Point(120, 140), Scalar(255, 9, 9), 3); rectangle(img, Point(150, 40), Point(250, 140), Scalar(0, 0, 255), -1); circle(img, Point(330, 90), 50, Scalar(9, 255, 9), -1); ellipse(img, Point(80, 280), Size(60, 48), 45, 9, 360, Scalar(255, 255, 9), 2); Point points[1][5]; points[0][0] = Point(150, 279); points[0][1] = Point(190, 229); points[0][2] = Point(260, 255); points[0][3] = Point(224, 296); points[0][4] = Point(178, 316); const Point* ppt[1] = { points[0] }; int npt[] = { 5 }; polylines(img, ppt, npt, 1, 1, Scalar(0, 255, 255), 5); putText(img, string("OpenCv"), Point(280, 280), 0, 1, Scalar(0, 0, 0), 3); imshow("window", img); waitKey(0); } return 0; }
★Python
import cv2 as cv import numpy as np image = np.zeros((512, 512, 3), dtype=np.uint8) cv.rectangle(image, (100, 100), (300, 300), (255, 0, 0), 2, cv.LINE_8, 0) cv.circle(image, (256, 256), 50, (0, 0, 255), 2, cv.LINE_8, 0) cv.ellipse(image, (256, 256), (150, 50), 360, 0, 360, (0, 255, 0), 2, cv.LINE_8, 0) cv.imshow("image", image) cv.waitKey(0) for i in range(100000): image[:,:,:]= 0 x1 = np.random.rand() * 512 y1 = np.random.rand() * 512 x2 = np.random.rand() * 512 y2 = np.random.rand() * 512 b = np.random.randint(0, 256) g = np.random.randint(0, 256) r = np.random.randint(0, 256) # cv.line(image, (np.int(x1), np.int(y1)), (np.int(x2), np.int(y2)), (b, g, r), 4, cv.LINE_8, 0) cv.rectangle(image, (np.int(x1), np.int(y1)), (np.int(x2), np.int(y2)), (b, g, r), 1, cv.LINE_8, 0) cv.imshow("image", image) c = cv.waitKey(20) if c == 27: break # ESCä¸ cv.imshow("image", image) cv.waitKey(0) cv.destroyAllWindows()
★結果圖:
★延伸說明/重點回顧:
在影像處理中,這些函數已經很夠用了,畢竟大多是為了明確標示出處理後的運算結果