功能
????????使用python + opencv, 將文字信息標注在圖片中
? ? ? ? 同一張圖片中涉及多次標注
? ? ? ? 文字大小為標注框的0.3倍
? ? ? ? 使用多綫程運行
import cv2
import threading
import numpy as npdef draw_annotations(item, annotations):"""在圖片上繪制標注框和文本annotations: 標注列表,格式為[[x1,x2,y1,y2], text, color]"""# 讀取圖片image = cv2.imread(item['filename'])# 創建圖片副本,避免修改原始圖片img_copy = image.copy()for annotation in annotations:coords, text, color = annotationx1, x2, y1, y2 = coordsbox_height = y2 - y1# 設置字體大小為框高度的0.3倍 # 確保字體大小至少為0.1,避免太小無法顯示font_scale = max(0.3 * box_height / 40, 0.2)# 設置字體類型font = cv2.FONT_HERSHEY_SIMPLEXthickness = max(int(font_scale * 1.5), 4) # 根據字體大小調整線寬# 計算文本尺寸(text_width, text_height), baseline = cv2.getTextSize(text, font, font_scale, thickness)# 計算框內右上角位置(帶5像素內邊距)text_x = x2 - text_width - 5text_y = y1 + text_height + 5# 確保文本位置在框內if text_x < x1:text_x = x1 + 5if text_y > y2:text_y = y2 - 5# 繪制邊界框cv2.rectangle(img_copy, (x1, y1), (x2, y2), color, thickness)# 繪制文本背景(提高可讀性)cv2.rectangle(img_copy,(text_x - 2, text_y - text_height - 2),(text_x + text_width + 2, text_y + 2),color, -1) # -1表示填充矩形# 繪制文本(白色)cv2.putText(img_copy, text, (text_x, text_y),font, font_scale, (0,0,0), thickness)# 創建輸出文件名output_filename = item['filename'].replace('.jpg', '_annotated.jpg')# 保存結果cv2.imwrite(output_filename, img_copy)print(f"標注圖片已保存為: {output_filename}")# return img_copy# 主函數
def main():# 示例數據tt = [{'filename': 'D:\\LABELAOI\\Test\\S_right_CAM2.jpg','info': [[(271, 393, 264, 518), 'CELOGO 0.95', (0, 255, 0)]]},{'filename': 'D:\\LABELAOI\\Test\\25732137Q0003-T3N0CV10J812126_20250320192533_L_main_CAM_basler.jpg','info': [[(3778, 4327, 212, 700), '1TUF 0.96', (0, 255, 0)],[(2176, 2501, 2431, 2568), 'ZCELOGO 0.94', (0, 255, 0)],[(4135, 5341, 2535, 3054), '312X 0.97', (0, 255, 0)],[(861, 1369, 315, 528), '15100-30874000 1.00', (0, 255, 0)]]}]threads = []for item in tt:# annotated_image = draw_annotations(item, item['info'])# 繪制標注t = threading.Thread(target=draw_annotations, args=(item, item['info']))threads.append(t)t.start()# 主線程等待所有子線程完成for t in threads:t.join() # 阻塞主線程直到該線程結束if __name__ == "__main__":import datetimestarttime = datetime.datetime.now()main()endtime = datetime.datetime.now()print(f"the process run time:{endtime - starttime}")
? ? ? ? 效果如下圖:
????????????????標注圖片已保存為: D:\LABELAOI\Test\S_right_CAM2_annotated.jpg
標注圖片已保存為: D:\LABELAOI\Test\25732137Q0003-????????????????????????T3N0CV10J812126_20250320192533_L_main_CAM_basler_annotated.jpg
the process run time:0:00:00.792136