使用OpenCV或者matplotlib給照片裏的物體添加方框和文字說明

目錄

 

1. OpenCV

2. matplotlib


1. OpenCV

這裏我們用YOLOv3COCO的模型來給照片做檢測。我們用tensornets導入預訓練的YOLO模型,用OpenCV給照片添加方框和文字,用matplotlib顯示圖片。

tensornets提供對各種預訓練模型的高層接口,包括YOLOv2、YOLOv3、Faster RCNN。

OpenCV中的cv2.rectanglecv2.putText兩個函數分別給圖片添加方框和文字。請點擊超鏈接查看兩個函數的文檔。

我們輸入這樣的圖片

用下面這些代碼處理上圖。

import tensorflow as tf
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import cv2 as cv
import tensornets as nets
from tensornets.datasets.coco import classnames

# 輸入佔位符
input_img = tf.placeholder(shape=(None, 416, 416, 3), dtype=tf.float32)
# 實例化YOLO模型
yolov3 = nets.YOLOv3COCO(input_img)

img_path = './road.bmp'
# 讀入圖片
image = Image.open(img_path)
# 放縮圖片到指定大小
image_resize = image.resize((416, 416))
image_resize = np.expand_dims(np.asarray(image_resize), 0)

# TensorFlow的配置
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
# 運行YOLO模型獲得各個物體類別的方框及其可信度
with tf.Session(config=config) as sess:
    sess.run(yolov3.pretrained())
    res = sess.run(yolov3.preds, {input_img: yolov3.preprocess(image_resize)})
    boxes = yolov3.get_boxes(res, image_resize.shape[1:3])
# MSCOCO中有80種物體類別
print(len(boxes))

# 圖片的第一維是數組裏的y座標,第二維是數組裏的x座標
width, height = image.size
# 複製圖片
image2 = np.copy(np.asarray(image))
for idx, box in enumerate(boxes):
    if box.shape[0] > 0:
        for line in box:
            x1, y1, x2, y2, score = line
            # 只顯示可信度超過0.4的方框
            if score > 0.4:
                x1 *= width / 416
                y1 *= height / 416
                x2 *= width / 416
                y2 *= height / 416
                x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
                # 畫框
                image2 = cv.rectangle(image2, (x1, y1), (x2, y2), (255, 0, 0), thickness=3)
                # 上文字
                image2 = cv.putText(image2, classnames[idx], (x1, y1-10), cv. FONT_HERSHEY_TRIPLEX, (x2-x1)/120, (0, 255, 0), 2)
# 顯示圖片
plt.figure(figsize=(20,20))
plt.imshow(image2)

最終獲得的圖片類似於這樣:

可以看到YOLO找到了兩輛car、一個stop sign和一輛truck,其中一輛car和truck重疊。


2. matplotlib

matplotlib也可以給圖片加上方框。這裏我們要使用matplotlib.pyplot.text函數和matplotlib.patches.Rectangle類。

class matplotlib.patches.Rectangle(xy, width, height, angle=0.0, **kwargs)[source]

Bases: matplotlib.patches.Patch

A rectangle with lower left at xy = (x, y) with specified width, height and rotation angle.

Parameters:

xy : (float, float)

The bottom and left rectangle coordinates

width : float

Rectangle width

height : float

Rectangle height

angle : float, optional

rotation in degrees anti-clockwise about xy (default is 0.0)

fill : bool, optional

Whether to fill the rectangle (default is True)

 

Rectangle是繼承了Patch的類。它初始化的第一個參數是矩形左下角的座標,這裏的xy是一般數學意義上的xy,也就是橫座標在前,縱座標在後,這與計算機領域數組的表示恰好相反。它第二個參數是寬度,第三個參數是高度。另外你還可以給它傳遞關鍵詞參數,比如指定線寬的linewidth,邊緣顏色的edgecolor和表面顏色facecolor。

matplotlib.pyplot.text(x, y, s, fontdict=None, withdash=<deprecated parameter>, **kwargs)[source]

Add text to the axes.

Add the text s to the axes at location x, y in data coordinates.

Parameters:

x, y : scalars

The position to place the text. By default, this is in data coordinates. The coordinate system can be changed using the transform parameter.

s : str

The text.

fontdict : dictionary, optional, default: None

A dictionary to override the default text properties. If fontdict is None, the defaults are determined by your rc parameters.

withdash : boolean, optional, default: False

Creates a TextWithDash instance instead of a Text instance.

Returns:

text : Text

The created Text instance.

Other Parameters:

**kwargs : Text properties.

Other misc

text是個函數,用於在當前axes上添加文字。matplotlib用figure表示單獨一張圖,axes分別表示圖中若干個子圖。作圖操作直接作用於axes上。text的第一個參數是橫座標,第二個參數是縱座標,第三個參數是要添加的字符串,第四個參數是指定字體。除此以外你還可以指定關鍵詞參數,比如文字顏色color,垂直對齊verticalalignment,文字框參數bbox。

下面是一個例子

for cls, score, box in zip(d['detection_classes'], d['detection_scores'], d['detection_boxes']):
    bbox = patches.Rectangle((box[1]*w, box[0]*h), 
                             (box[3]-box[1])*w, (box[2]-box[0])*h, 
                             linewidth=1, 
                             edgecolor=idx2color[cls], 
                             facecolor='none')
    plt.gca().add_patch(bbox)
    plt.text(box[1]*w, 
             box[0]*h, s='%s %.2f'%(idx2cls[cls], score), 
             color='white', 
             verticalalignment='bottom', 
             bbox={'color':idx2color[cls], 'pad': 0})

在一次檢測後我們給圖像這樣添加方框可以得到這樣的效果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章