在各类目标检测测试过程中,会对检测的结果进行可视化,将检测的结果画到图片上。以下是一个通用性实现。主要具备以下特性
- 文字显示结果在各种分辨率图片上视觉显示效果一致
import xml.etree.ElementTree as ET
import os
from os import listdir, getcwd
from os.path import join
import shutil
import cv2 as cv
class BoxUtils():
def __init__(self):
#color define
self.LIGHT_BLUE = (0xED, 0x95, 0x64)
self.GREEN = (0x00, 0xFF, 0x00)
self.RED = (0xFF, 0x00, 0x00)
self.BLACK = (0x00, 0x00, 0x00)
#font size
#定义文字像素值,像素值大小是相对于高度为base_SCREEN_HIGH的图片的。会根据实际图片的大小,将最终显示的文字
#大小映射到对应base_SCREEN_HIGH上的像素值,以保证在不同分辨率的图片上文字显示大小是一致的。类似与android中的dp值的
#设置
self.base_FONT_SIZE =36
self.base_SCREEN_HIGH=1080
self.LINE_WIDTH = 1
#根据图片高度,转化实际要显示的文字大小
def get_draw_font_scale(self, pic_high):
scal = float(self.base_FONT_SIZE) / self.base_SCREEN_HIGH
realte_font_size = int((pic_high * scal + 0.5))
font_scale = float(realte_font_size)/self.base_FONT_SIZE
return realte_font_size,font_scale
def draw_detector_box1(self, image, detect_info, detected_rect, scalar):
"""
args:
image:
detected_rect:[left, top, right, bottom], every value must be int
"""
# print(detected_rect)
cv.rectangle(image, (detected_rect[0],detected_rect[1]), (detected_rect[2],detected_rect[3]), scalar, self.LINE_WIDTH)
rect_top = detected_rect[1]
rect_left = detected_rect[0]
font_size,font_scale = self.get_draw_font_scale(image.shape[0])
# print(font_size, font_scale),设置文字前后和上下间距
offset_y = 1
padding_x_scale = 0.5
padding_x = int(font_size * font_scale * padding_x_scale)
padding_y_scale = 0.1
padding_y = int(font_size * font_scale * padding_y_scale)
if(len(detect_info)):
thickness = 2
text_size, baseline = cv.getTextSize(detect_info, cv.FONT_HERSHEY_SIMPLEX, font_scale, thickness)
p1 = (detected_rect[0], detected_rect[1]- text_size[1])
cv.rectangle(image, (p1[0] - 2//2, p1[1] - 2 - baseline-padding_y*2), (p1[0] + text_size[0] + padding_x*2, p1[1] + text_size[1]), self.RED, -1)
cv.putText(image, detect_info, (p1[0]+padding_x, p1[1] + baseline+padding_y), cv.FONT_HERSHEY_SIMPLEX, font_scale, self.BLACK, 1, 8)
使用方法如下
img = cv.imread(r"./b.jpg")
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
detected_rect = [100,100,300, 300]
detect_info='class_name:0.89'
draw_image = img.copy()
draw_image = cv.GaussianBlur(draw_image,(21,21),0,0)
#使用方法如下
box_util = BoxUtils()
box_util.draw_detector_box1(draw_image, detect_info, detected_rect, box_util.RED)
# from PIL import Image
img_cv = Image.fromarray(draw_image)
img_cv
# from matplotlib import pyplot as plt
# plt.imshow(draw_image)
# cv.imwrite("ret.jpg", draw_image)
显示效果如下



