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()]

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()


★結果圖:

★延伸說明/重點回顧:

    在影像處理中,這些函數已經很夠用了,畢竟大多是為了明確標示出處理後的運算結果

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *