[OpenCV implementation of images: visual target detection frame]

overview

The visualization of object detection boxes is an important task in the fields of computer vision and machine learning, helping to intuitively understand and evaluate the performance of object detection algorithms. By using Python and related image processing libraries, visualization of target detection boxes can be easily achieved. The main steps include reading image data, extracting coordinate information of target detection boxes, and then using visualization tools to draw these boxes on the image. Matplotlib is a commonly used visualization library, and its pyplot module provides convenient functions for drawing images and graphics. By combining the output of an object detection algorithm with the capabilities of Matplotlib, you can create an intuitive and easy-to-understand image showing the location and bounding box of an object in the image.

The output of common target detection frames.
Insert image description here
The upper left is the commonly used output frame without labels, the upper right is the YOLO series beautified rectangular frame with labels, and the lower left is the four corners The rectangular frame after point beautification, the lower right corner is the beautified rectangular frame with labels.

frame function

In OpenCV, the cv2.rectangle function is usually used to draw a rectangular box. The general form of this function is as follows:

cv2.rectangle(image, start_point, end_point, color, thickness)

Here is the parameter explanation of the function:

image: input image
start_point: the coordinates of the upper left corner of the rectangular frame
end_point: the coordinates of the lower right corner of the rectangular frame< a i=3> color: the color of the rectangular frame, expressed in BGR order by default thickness: the thickness of the line, where -1 means filling the entire rectangle

By calling this function, a rectangular frame can be drawn on the image to highlight the target or mark the detection result.

Code

Use python to achieve the corresponding frame effect in the above example.

1) Read in the image

First we read in a color image and draw a frame:

import cv2

img_name = 'img_6.png'
img = cv2.imread(img_name)
box = [ 25, 43,200,180, "sdq"]
box_color = (255,0,255)
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), color=box_color, thickness=2)
cv2.imshow('Image with Rectangle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

box = [ 20, 25,80,200, "sdq"]

Here, box is a list containing five elements:

20:矩形框的左上角 x 坐标。
25:矩形框的左上角 y 坐标。
80:矩形框的右下角 x 坐标。
200:矩形框的右下角 y 坐标。
"sdq":一个标签表示矩形框的标识或类别。

The result is as follows:
Insert image description here

Label beautification

Next, add a label to the rectangular box, observe the above drawing function, and pay attention to the last parameter thickness. If this value is equal to -1, then the filling effect will be performed on the rectangular box.
Tag beautification code


def draw_label_type(draw_img,bbox,label_color):
    label = str(bbox[-1])
    labelSize = cv2.getTextSize(label + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]
    if bbox[1] - labelSize[1] - 3 < 0:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1] + 2),
                      (bbox[0] + labelSize[0], bbox[1] + labelSize[1] + 3),
                      color=label_color,thickness=-1)                      )
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] + labelSize + 3),
                    cv2.FONT_HERSHEY_SIMPLEX,0.5,
                    (0, 0, 0),thickness=1)
    else:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1] - labelSize[1] - 3),
                      (bbox[0] + labelSize[0], bbox[1] - 3),
                      color=label_color,thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] - 3),
                    cv2.FONT_HERSHEY_SIMPLEX,0.5,
                    (0, 0, 0),thickness=1)

Use code:

import cv2

def draw_label_type(draw_img, bbox, label_color):
    label = str(bbox[4])
    labelSize = cv2.getTextSize(label + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]
    if bbox[1] - labelSize[1] - 3 < 0:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1]),
                      (bbox[0] + labelSize[0], bbox[1] + labelSize[1]),
                      color=label_color, thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] + labelSize[1]),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                    (0, 0, 0), thickness=1)
    else:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1] - labelSize[1] - 3),
                      (bbox[0] + labelSize[0], bbox[1] - 3),
                      color=label_color, thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] - 3),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                    (0, 0, 0), thickness=1)

img_name = 'img_6.png'
img = cv2.imread(img_name)
box = [25, 43, 200, 180, "sdq"]
box_color = (255, 0, 255)
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), color=box_color, thickness=2)

draw_label_type(img, box, label_color=(255, 255, 255))  # 添加标签

cv2.imshow('Image with Rectangle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Insert image description here

Corner point beautification

After adding the label above, since the color of the label box and the target rectangular box are the same, it is not easy to distinguish the boundaries. Here is the code to beautify the diagonal points.


def draw_box_corner(draw_img,bbox,length,corner_color):
    # Top Left
    cv2.line(draw_img, (bbox[0], bbox[1]), (bbox[0] + length, bbox[1]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[0], bbox[1]), (bbox[0], bbox[1] + length), corner_color, thickness=3)
    # Top Right
    cv2.line(draw_img, (bbox[2], bbox[1]), (bbox[2] - length, bbox[1]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[2], bbox[1]), (bbox[2], bbox[1] + length), corner_color, thickness=3)
    # Bottom Left
    cv2.line(draw_img, (bbox[0], bbox[3]), (bbox[0] + length, bbox[3]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[0], bbox[3]), (bbox[0], bbox[3] - length), corner_color, thickness=3)
    # Bottom Right
    cv2.line(draw_img, (bbox[2], bbox[3]), (bbox[2] - length, bbox[3]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[2], bbox[3]), (bbox[2], bbox[3] - length), corner_color, thickness=3)

The corresponding corresponding parameters have the following meanings:

draw_img: input image
bbox: target detection box format (x1, y1, x2, y2)
length: straight line length
corner_color straight line color
Complete fusion code:

import cv2

def draw_label_type(draw_img, bbox, label_color):
    label = str(bbox[4])
    labelSize = cv2.getTextSize(label + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]
    if bbox[1] - labelSize[1] - 3 < 0:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1]),
                      (bbox[0] + labelSize[0], bbox[1] + labelSize[1]),
                      color=label_color, thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] + labelSize[1]),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                    (0, 0, 0), thickness=1)
    else:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1] - labelSize[1] - 3),
                      (bbox[0] + labelSize[0], bbox[1] - 3),
                      color=label_color, thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] - 3),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                    (0, 0, 0), thickness=1)

def draw_box_corner(draw_img, bbox, length, corner_color):
    # Top Left
    cv2.line(draw_img, (bbox[0], bbox[1]), (bbox[0] + length, bbox[1]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[0], bbox[1]), (bbox[0], bbox[1] + length), corner_color, thickness=3)
    # Top Right
    cv2.line(draw_img, (bbox[2], bbox[1]), (bbox[2] - length, bbox[1]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[2], bbox[1]), (bbox[2], bbox[1] + length), corner_color, thickness=3)
    # Bottom Left
    cv2.line(draw_img, (bbox[0], bbox[3]), (bbox[0] + length, bbox[3]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[0], bbox[3]), (bbox[0], bbox[3] - length), corner_color, thickness=3)
    # Bottom Right
    cv2.line(draw_img, (bbox[2], bbox[3]), (bbox[2] - length, bbox[3]), corner_color, thickness=3)
    cv2.line(draw_img, (bbox[2], bbox[3]), (bbox[2], bbox[3] - length), corner_color, thickness=3)

img_name = 'img_6.png'
img = cv2.imread(img_name)
box = [25, 43, 200, 180, "sdq"]
box_color = (255, 0, 255)
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), color=box_color, thickness=2)

draw_label_type(img, box, label_color=(255, 255, 255))  # 添加标签
draw_box_corner(img, box, length=10, corner_color=(0, 255, 0))  # 添加对角点

cv2.imshow('Image with Rectangle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Insert image description here

transparency effect

Set the thickness parameter through the cv2.rectangle function to get the filled image, and then use the cv2.add_weight function in opencv to achieve a transparent effect. Try it yourself.
Use the add_weight function to weight the above two images. As follows:

alpha = 0.8
gamma = 0
out_img = cv2.addWeighted(img,alpha,draw_img,1-alpha,gamma)
完整代码:

import cv2

def draw_label_type(draw_img, bbox, label_color):
    label = str(bbox[4])
    labelSize = cv2.getTextSize(label + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]
    if bbox[1] - labelSize[1] - 3 < 0:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1]),
                      (bbox[0] + labelSize[0], bbox[1] + labelSize[1]),
                      color=label_color, thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] + labelSize[1]),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                    (0, 0, 0), thickness=1)
    else:
        cv2.rectangle(draw_img,
                      (bbox[0], bbox[1] - labelSize[1] - 3),
                      (bbox[0] + labelSize[0], bbox[1] - 3),
                      color=label_color, thickness=-1)
        cv2.putText(draw_img, label,
                    (bbox[0], bbox[1] - 3),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5,
                    (0, 0, 0), thickness=1)

img_name = 'img_6.png'
img = cv2.imread(img_name)
box = [25, 43, 200, 180, "sdq"]
box_color = (255, 0, 255)
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), color=box_color, thickness=2)

draw_img = img.copy()
draw_label_type(draw_img, box, label_color=(255, 255, 255))  # 添加标签

alpha = 0.8
gamma = 0
out_img = cv2.addWeighted(img, alpha, draw_img, 1 - alpha, gamma)

cv2.imshow('Image with Transparent Rectangle', out_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

summary

In object detection, optimizing the labels and corners of rectangular boxes can improve visualization and user understanding. The application of the transparency effect makes the target frame blend into the original image without affecting the main content of the image, improving the aesthetics of the overall presentation.

Guess you like

Origin blog.csdn.net/weixin_47869094/article/details/134585539