Python合并同类别且相交的矩形框
前言 前提条件 相关介绍 实验环境 Python合并同类别且相交的矩形框
前言
由于本人水平有限,难免出现错漏,敬请批评改正。 更多精彩内容,可点击进入Python日常小操作专栏、YOLO系列专栏、自然语言处理专栏或我的个人主页查看 基于DETR的人脸伪装检测 YOLOv7训练自己的数据集(口罩检测) YOLOv8训练自己的数据集(足球检测) YOLOv5:TensorRT加速YOLOv5模型推理 YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测 YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制 YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层 Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集 YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割) 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
前提条件
相关介绍
Python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。
实验环境
Python合并同类别且相交的矩形框
代码实现
import os
import cv2
import json
from collections import deque
import numpy as np
def xyxy2xywh ( rect) :
'''
(x1,y1,x2,y2) -> (x,y,w,h)
'''
return [ rect[ 0 ] , rect[ 1 ] , rect[ 2 ] - rect[ 0 ] , rect[ 3 ] - rect[ 1 ] ]
def xywh2xyxy ( rect) :
'''
(x,y,w,h) -> (x1,y1,x2,y2)
'''
return [ rect[ 0 ] , rect[ 1 ] , rect[ 0 ] + rect[ 2 ] , rect[ 1 ] + rect[ 3 ] ]
def is_RecA_RecB_interSect ( RecA, RecB) :
x_A_and_B_min = max ( RecA[ 0 ] , RecB[ 0 ] )
y_A_and_B_min = max ( RecA[ 1 ] , RecB[ 1 ] )
x_A_and_B_max = min ( RecA[ 2 ] , RecB[ 2 ] )
y_A_and_B_max = min ( RecA[ 3 ] , RecB[ 3 ] )
interArea = max ( 0 , x_A_and_B_max - x_A_and_B_min) * max ( 0 , y_A_and_B_max - y_A_and_B_min)
return interArea > 0
def merge_RecA_RecB ( RecA, RecB) :
xmin = min ( RecA[ 0 ] , RecB[ 0 ] )
ymin = min ( RecA[ 1 ] , RecB[ 1 ] )
xmax = max ( RecA[ 2 ] , RecB[ 2 ] )
ymax = max ( RecA[ 3 ] , RecB[ 3 ] )
return [ xmin, ymin, xmax, ymax]
'''
递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。
终止条件:矩形框数为1或者为空。
返回值: 新合并的矩形框
本级任务: 每一级需要做的就是遍历从它开始的后续矩形框,寻找可以和他合并的矩形
'''
def merge_rect ( box, labels) :
'''
合并重叠框
输入参数: box :[[xmin,ymin,xmax,ymax],...]
labels :['0', '0', '1', '1', '1', '2', '2', '2']
返回:
合并后的box:[[xmin,ymin,xmax,ymax],...]
合并后的labels:['0', '1', '2']
'''
if len ( box) == 1 or len ( box) == 0 :
return box, labels
for i in range ( len ( box) ) :
RecA_xyxy = box[ i]
labelA = labels[ i]
for j in range ( i+ 1 , len ( box) ) :
RecB_xyxy = box[ j]
labelB = labels[ i]
if is_RecA_RecB_interSect( RecA_xyxy, RecB_xyxy) and labelA== labelB:
rect_xyxy = merge_RecA_RecB( RecA_xyxy, RecB_xyxy)
box. remove( RecA_xyxy)
box. remove( RecB_xyxy)
box. append( rect_xyxy)
labels. pop( i)
labels. pop( j- 1 )
labels. append( labelA)
merge_rect( box, labels)
return box, labels
return box, labels
if __name__ == "__main__" :
color = {
'0' : ( 255 , 0 , 0 ) ,
'1' : ( 0 , 255 , 0 ) ,
'2' : ( 0 , 0 , 255 ) ,
}
box = [ [ 71 , 32 , 81 , 109 ] , [ 70 , 80 , 81 , 111 ] , [ 77 , 221 , 86 , 240 ] , [ 76 , 220 , 87 , 258 ] ,
[ 76 , 240 , 87 , 258 ] , [ 150 , 379 , 160 , 400 ] , [ 151 , 380 , 160 , 418 ] , [ 151 , 400 , 160 , 416 ] ]
labels = [ '0' , '0' , '1' , '1' , '1' , '2' , '2' , '2' ]
print ( labels, box, sep= '\n' )
img = cv2. imread( 'res.png' )
for ( xmin, ymin, xmax, ymax) , label in zip ( box, labels) :
img = cv2. rectangle( img, ( xmin, ymin) , ( xmax, ymax) , color[ label] , 1 )
cv2. imwrite( 'origin.jpg' , img)
merged_box, merged_labels = merge_rect( box, labels)
print ( merged_labels, merged_box, sep= '\n' )
merged_img = cv2. imread( 'res.png' )
for ( xmin, ymin, xmax, ymax) , label in zip ( merged_box, merged_labels) :
merged_img = cv2. rectangle( merged_img, ( xmin, ymin) , ( xmax, ymax) , color[ label] , 1 )
cv2. imwrite( 'merged.jpg' , merged_img)
由于本人水平有限,难免出现错漏,敬请批评改正。 更多精彩内容,可点击进入Python日常小操作专栏、YOLO系列专栏、自然语言处理专栏或我的个人主页查看 基于DETR的人脸伪装检测 YOLOv7训练自己的数据集(口罩检测) YOLOv8训练自己的数据集(足球检测) YOLOv5:TensorRT加速YOLOv5模型推理 YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测 YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制 YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层 Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集 YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割) 使用Kaggle GPU资源免费体验Stable Diffusion开源项目