天天看點

Python計算機視覺-使用OpenCV注釋圖像

作者:熬夜學Python的程式媛

前言

學習猶如逆水行舟,不進則退。作為程式員,每天學習一個新知識就是最大的收獲。是以,感謝大家對小編的喜歡和支援,願意跟小編一起學習程式設計知識。

如果對學習沒有自制力或者沒有一起學習交流的動力,歡迎進學習交流群,我們一起交流學習,報團打卡!

Python計算機視覺-使用OpenCV注釋圖像

注釋圖像和視訊有多種用途,OpenCV使這個過程簡單明了。看看如何使用它:

  • 向示範添加資訊
  • 在物體周圍繪制邊框,以便檢測物體
  • 用不同顔色高亮像素進行圖像分割

一旦你學會了注釋圖像,注釋視訊幀看起來也很簡單。這是因為視訊中的每一幀都表示為一幅圖像。我們将在這裡示範如何用幾何形狀和文本注釋圖像。

這是我們将在所有例子中用到的圖像。

Python計算機視覺-使用OpenCV注釋圖像

1.簡單實作畫線

首先,快速檢視一下注釋圖像的代碼。我們将詳細讨論代碼中的每一行,以便您能夠完全了解它。

(1)Python

# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 在圖像上畫線
imageLine = img.copy()
# 在圖像上繪制從A點到B點
pointA = (200,80)
pointB = (450,80)
cv2.line(imageLine, pointA, pointB, (255, 255, 0), thickness=3, lineType=cv2.LINE_AA)
cv2.imshow('Image Line', imageLine)
cv2.waitKey(0)           

(2)C++

// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 在圖像上畫線
Mat imageLine = img.clone();
Point pointA(200,80);
Point pointB(450,80);
line(imageLine, pointA, pointB, Scalar(255, 255, 0), 3, 8, 0);
imshow("Lined Image", imageLine);
waitKey();
}           
Python計算機視覺-使用OpenCV注釋圖像

2.代碼解析

在第一個例子中,讓我們使用OpenCV中的line()函數為圖像添加一條彩色線。在調用line()函數之前,通過以下方法建立原始圖像的副本:

  • 在Python中copy()函數
  • 在C++中clone()函數

副本将確定您對圖像所做的任何更改不會影響原始圖像。在c++中,首先為原始圖像的副本建立一個矩陣。

下面是line()函數的文法:line(image, start_point, end_point, color, thickness)

  • 第一個參數是圖像
  • 接下來的兩個參數是線段的起點和終點。

從點A (x1, y1)到點B(x2, y2)畫一條直線,其中A和B代表圖像中的任意兩點。看圖像的左上角,你會發現這裡是xy坐标系的原點。

  • x軸表示圖像的水準方向或列。
  • y軸表示圖像的垂直方向或行。

如代碼所示:

  • 指定起始點和結束點,以便在圖像上水準繪制一條250像素長的直線。
  • 指定它的顔色為藍色和綠色的混合物,線寬指定為3。

3.畫圓

接下來,讓我們使用OpenCV中的circle()函數為圖像添加一個圓圈注釋。看看它的文法:circle(image, center_coordinates, radius, color, thickness)

  • 與OpenCV中的所有繪圖函數一樣,第一個參數是圖像。
  • 接下來的兩個參數定義圓心的坐标及其半徑。
  • 最後兩個參數指定線條的顔色和粗細。

在這個例子中,您用一個紅色的圓圈圍繞着狗的臉來注釋圖像。然後使用imshow()函數顯示帶注釋的圖像。

# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 複制圖像
imageCircle = img.copy()
# 定義圓心
circle_center = (415,190)
# 定義圓的半徑
radius =100
# 使用circle()函數繪制一個圓
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA)
# 顯示結果
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)           
// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 複制圖像
imageCircle = img.copy()
// 定義圓的中心
circle_center = (415,190)
// 定義圓的半徑
radius =100
// 使用circle()函數繪制一個圓
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA)
// 顯示結果
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)
}           
Python計算機視覺-使用OpenCV注釋圖像

4.畫填充的圓

您剛剛完成了用紅色圓圈對圖像的注釋。如果你想用純色填充這個圓呢?這很簡單。隻需将線寬參數更改為-1,如下面的代碼所示。

# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 複制圖像
imageCircle = img.copy()
# 定義圓心
circle_center = (415,190)
# 定義圓的半徑
radius =100
# 使用circle()函數繪制一個圓
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=-1, lineType=cv2.LINE_AA)
# 顯示結果
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)           
// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 複制圖像
imageCircle = img.copy()
// 定義圓的中心
circle_center = (415,190)
// 定義圓的半徑
radius =100
// 使用circle()函數繪制一個圓
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=-1, lineType=cv2.LINE_AA)
// 顯示結果
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)
}           
Python計算機視覺-使用OpenCV注釋圖像

5.畫矩形

現在,您将使用OpenCV中的rectangle()函數在圖像上繪制一個矩形。看看它的文法:rectangle(image, start_point, end_point, color, thickness)

在rectangle()函數中,為矩形的各個角提供起始點(左上)和結束點(右下)。

現在浏覽一下這個示例代碼,并在小狗的臉上用一個紅色矩形注釋這個圖像。

# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 複制圖像
imageRectangle = img.copy()
# 定義矩形的起點和終點
start_point =(300,115)
end_point =(475,225)
# 畫矩形
cv2.rectangle(imageRectangle, start_point, end_point, (0, 0, 255), thickness= 3, lineType=cv2.LINE_8)
# 輸出顯示
cv2.imshow('imageRectangle', imageRectangle)
cv2.waitKey(0)           
// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 複制圖像
Mat rect_image = image.clone();
// 定義矩形的起始點和結束點
Point start_point(300,115);
Point end_point(475,225);
// 使用 rectangle() 函數繪制一個矩形
rectangle(rect_image, start_point, end_point, Scalar(0,0,255), 3, 8, 0);
imshow("Rectangle on Image", rect_image);
waitKey();
}           
Python計算機視覺-使用OpenCV注釋圖像

6.畫橢圓

ellipse(image, centerCoordinates, axesLength, angle, startAngle, endAngle, color, thickness)

你可以使用OpenCV中的ellipse()函數在圖像上畫一個橢圓。ellipse()函數的文法與circle非常相似。除了,你需要指定的不是半徑,而是:

  • 橢圓的長和短軸長度
  • 旋轉角度
  • 橢圓的起始和結束角,這些角度讓我們隻繪制弧線的一部分

在下面的示例代碼中,您可以使用:

  • 水準藍色橢圓
  • 垂直的紅色橢圓

正如您再次看到的,OpenCV中的繪圖函數非常相似,是以很容易掌握。此外,它們還提供可選參數,以便您可以自由定義許多基本幾何形狀的位置和方向。

# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 複制圖像
imageEllipse = img.copy()
# 定義橢圓的中心點
ellipse_center = (415,190)
# 定義橢圓的長軸和短軸
axis1 = (100,50)
axis2 = (125,50)
# 繪制橢圓
#水準
cv2.ellipse(imageEllipse, ellipse_center, axis1, 0, 0, 360, (255, 0, 0), thickness=3)
#垂直
cv2.ellipse(imageEllipse, ellipse_center, axis2, 90, 0, 360, (0, 0, 255), thickness=3)
# 顯示輸出
cv2.imshow('ellipse Image',imageEllipse)
cv2.waitKey(0)           
// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 複制圖像
Mat imageEllipse = img.clone();
// 定義橢圓的中心點
Point ellipse_center(415,190);
// 定義橢圓的長軸和短軸
Point axis1(100, 50);
Point axis2(125, 50);
// 使用ellipse()函數繪制一個橢圓
// 水準
ellipse(imageEllipse, ellipse_center, axis1, 0, 0, 360, Scalar(255, 0, 0), 3, 8, 0);
// 垂直
ellipse(imageEllipse, ellipse_center, axis2, 90, 0, 360, Scalar(0, 0, 255), 3, 8, 0);
// 顯示輸出
imshow("Ellipses on Image", imageEllipse);
waitKey();
}           
Python計算機視覺-使用OpenCV注釋圖像

7.繪制半橢圓

在這個例子中,我們将前面的代碼修改為:

  • 隻畫藍色橢圓的一半
  • 将垂直的紅色橢圓改為半填充的水準紅色橢圓

要做到這一點,請進行以下更改:

  • 設定藍色橢圓的結束角為180度
  • 改變紅色橢圓的方向從90到0
  • 指定紅色橢圓的起始角和結束角,分别為0和180
  • 将紅色橢圓的厚度指定為負數
# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 複制圖像
halfEllipse = img.copy()
# 定義半橢圓的中心
ellipse_center = (415,190)
# 定義軸點
axis1 = (100,50)
# 畫一個不完整/開放的橢圓,隻是一個輪廓
cv2.ellipse(halfEllipse, ellipse_center, axis1, 0, 180, 360, (255, 0, 0), thickness=3)
# 如果您想繪制一個填充橢圓,請使用這行代碼
# cv2.ellipse(halfEllipse, ellipse_center, axis1, 0, 0, 180, (0, 0, 255), thickness=-2)
# 輸出顯示
cv2.imshow('halfEllipse',halfEllipse)
cv2.waitKey(0)           
// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 複制圖像
Mat halfEllipse = image.clone();
// 定義半橢圓的中心
Point ellipse_center(415,190);
// 定義軸點
Point axis1(100, 50);
// 畫半橢圓,隻畫輪廓
ellipse(halfEllipse, ellipse_center, axis1, 0, 180, 360, Scalar(255, 0, 0), 3, 8, 0);
// 如果您想繪制一個填充橢圓,請使用這行代碼
// ellipse(halfEllipse, ellipse_center, axis1, 0, 0, 180, Scalar(0, 0, 255), -2, 8, 0);
// 輸出顯示
imshow("Half-Ellipses on Image", halfEllipse);
waitKey();
}           
Python計算機視覺-使用OpenCV注釋圖像

8.添加文字

最後,讓我們嘗試用文本注釋圖像。要做到這一點,請使用OpenCV中的putText()函數。看看它的文法,後面跟着參數:putText(image, text, org, font, fontScale, color)

  • 和往常一樣,第一個參數是輸入圖像。
  • 下一個參數是我們想要注釋圖像的實際文本字元串。
  • 第三個參數指定文本字元串左上角的起始位置。
  • 接下來的兩個參數指定字型樣式和比例。OpenCV支援來自Hershey字型集合的幾種字型樣式,以及斜體字型。看看這個清單:

FONT_HERSHEY_SIMPLEX = 0,

FONT_HERSHEY_PLAIN = 1,

FONT_HERSHEY_DUPLEX = 2,

FONT_HERSHEY_COMPLEX = 3,

FONT_HERSHEY_TRIPLEX = 4,

FONT_HERSHEY_COMPLEX_SMALL = 5,

FONT_HERSHEY_SCRIPT_SIMPLEX = 6,

FONT_HERSHEY_SCRIPT_COMPLEX = 7,

FONT_ITALIC = 16

  • 字型比例是一個浮點值,用于向上或向下縮放字型的基本大小。根據圖像的分辨率,選擇合适的字型比例。
  • 最後一個必需參數是顔色,它被指定為BGR三元組。

看一下這段代碼,了解如何實作這些參數來在圖像上顯示文本字元串。

# 導入依賴
import cv2
# 讀取圖像
img = cv2.imread('sample.jpg')
# 顯示圖像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 列印錯誤資訊
if img is None:
print('Could not read image')
# 複制圖像
imageText = img.copy()
#讓我們寫下你想要放在圖像上的文本
text = 'I am a Happy dog!'
#你想放文本的地方
org = (50,350)
# 将文本寫在輸入圖像上
cv2.putText(imageText, text, org, fontFace = cv2.FONT_HERSHEY_COMPLEX, fontScale = 1.5, color = (250,225,100))
# 顯示帶有文本的輸出圖像
cv2.imshow("Image Text",imageText)
cv2.waitKey(0)
cv2.destroyAllWindows()           
// 導入依賴
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空間
using namespace std;
using namespace cv;
int main()
{
// 讀取圖像
Mat img = imread("sample.jpg");
// 顯示圖像
imshow("Original Image", img);
waitKey();
// 列印錯誤資訊
if (img.empty())
{
cout << "Could not read image" << endl;
}
// 複制圖像
Mat imageText = img.clone();
// 使用 putText() 函數寫入文本
putText(imageText, "I am a Happy dog!", Point(50,350), FONT_HERSHEY_COMPLEX, 1.5, Scalar(250,225,100));
imshow("Text on Image", imageText);
waitKey(0);
}           
Python計算機視覺-使用OpenCV注釋圖像

總結

用幾何形狀和文本注釋圖像是一種強大的交流方式。它有助于放大圖像上的資訊。在圖像經過各種計算機視覺算法處理後(例如,在物體檢測模型檢測到的物體周圍繪制邊界框),圖像幾乎總是被注釋以覆寫結果。

您已經看到用幾何形狀和文本注釋圖像是多麼容易。甚至繪圖函數也有類似的輸入參數。隻是指定注釋的位置和大小的方式可能略有不同。

你還學會了用想要的顔色填充形狀。繪制特定方向和長度的橢圓和弧。

最後,您看到了如何用文本注釋圖像。

參考目錄

https://learnopencv.com/annotating-images-using-opencv/

繼續閱讀