文章目錄
- 概要
- 畫框函數
- 代碼實現
- 標簽美化
- 角點美化
- 透明效果
- 小結
概要
目標檢測框的可視化在計算機視覺和機器學習領域中是一項重要的任務,有助于直觀地理解和評估目標檢測算法的性能。通過使用Python和相關的圖像處理庫,可以輕松實現目標檢測框的可視化。主要步驟包括讀取圖像數據、提取目標檢測框的坐標信息,然后利用可視化工具在圖像上繪制這些框。Matplotlib是一個常用的可視化庫,其pyplot模塊提供了方便的函數來繪制圖像和圖形。通過結合目標檢測算法的輸出和Matplotlib的功能,可以創建一個直觀且易于理解的圖像,展示圖像中目標的位置和邊界框。
常見的目標檢測框的輸出.
左上為常用的不帶標簽的輸出框,右上為YOLO系列美化帶標簽后的矩形框,左下為四個角點美化后的矩形框,右下為帶標簽的角點美化矩形框.
畫框函數
在OpenCV中,通常使用cv2.rectangle函數來繪制矩形框,該函數的一般形式如下:
cv2.rectangle(image, start_point, end_point, color, thickness)
這里是函數的參數解釋:
image: 輸入圖像
start_point: 矩形框左上角點的坐標
end_point: 矩形框右下角點的坐標
color: 矩形框的顏色,默認使用BGR順序表示
thickness: 線的粗細,其中 -1 代表填充整個矩形
通過調用這個函數,可以在圖像上繪制矩形框,用于突顯目標或標記檢測結果。
代碼實現
用python來實現上述示例中的相應的畫框效果.
1)讀入圖像
首先我們來讀入一副彩色圖像,并畫框:
import cv2img_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”]
在這里,box 是一個列表,包含了五個元素:
20:矩形框的左上角 x 坐標。
25:矩形框的左上角 y 坐標。
80:矩形框的右下角 x 坐標。
200:矩形框的右下角 y 坐標。
"sdq":一個標簽表示矩形框的標識或類別。
結果如下:
標簽美化
接下來來給矩形框添加標簽,觀察上述畫圖函數,注意最后一個參數thickness,如果此值等于-1,那么將對矩形框執行填充效果。
標簽美化代碼
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)
使用代碼:
import cv2def 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()
角點美化
上述添加完標簽后,由于標簽框和目標矩形框顏色一致,邊界處不太容易區分,這里添加對角點美化的代碼。
def draw_box_corner(draw_img,bbox,length,corner_color):# Top Leftcv2.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 Rightcv2.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 Leftcv2.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 Rightcv2.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)
相應的相應的參數含義如下:
draw_img: 輸入圖像
bbox: 目標檢測框 形式(x1,y1,x2,y2)
length: 直線長度
corner_color 直線顏色
完整融合代碼:
import cv2def 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 Leftcv2.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 Rightcv2.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 Leftcv2.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 Rightcv2.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()
透明效果
通過cv2.rectangle 函數設置 thickness參數 ,可以得到填充后的圖像,進而利用opencv中的 cv2.add_weight 函數可以實現透明效果,自行嘗試。
利用add_weight 函數對上面兩副圖像進行加權. 如下:
alpha = 0.8
gamma = 0
out_img = cv2.addWeighted(img,alpha,draw_img,1-alpha,gamma)
完整代碼:
import cv2def 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()
小結
在目標檢測中,優化矩形框的標簽和角點可以提高可視化效果和用戶理解。透明效果的應用則使得目標框融入原始圖像,不影響圖像的主體內容,提高了整體呈現的美觀性。