165 lines
5.9 KiB
Python
165 lines
5.9 KiB
Python
import numpy as np
|
||
import time,cv2
|
||
def ms(t1,t0):
|
||
return (t1-t0)*1000.0
|
||
def center_coordinate(boundbxs):
|
||
'''
|
||
输入:两个对角坐标xyxy
|
||
输出:矩形框重点坐标xy
|
||
'''
|
||
boundbxs_x1=boundbxs[0]
|
||
boundbxs_y1=boundbxs[1]
|
||
boundbxs_x2=boundbxs[2]
|
||
boundbxs_y2=boundbxs[3]
|
||
center_x=0.5*(boundbxs_x1+boundbxs_x2)
|
||
center_y=0.5*(boundbxs_y1+boundbxs_y2)
|
||
return center_x,center_y
|
||
|
||
def fourcorner_coordinate(boundbxs):
|
||
'''
|
||
输入:两个对角坐标xyxy
|
||
输出:矩形框四个角点坐标,以contours顺序。
|
||
'''
|
||
boundbxs_x1=boundbxs[0]
|
||
boundbxs_y1=boundbxs[1]
|
||
boundbxs_x2=boundbxs[2]
|
||
boundbxs_y2=boundbxs[3]
|
||
wid=boundbxs_x2-boundbxs_x1
|
||
hei=boundbxs_y2-boundbxs_y1
|
||
boundbxs_x3=boundbxs_x1+wid
|
||
boundbxs_y3=boundbxs_y1
|
||
boundbxs_x4=boundbxs_x1
|
||
boundbxs_y4 = boundbxs_y1+hei
|
||
contours_rec=[[boundbxs_x1,boundbxs_y1],[boundbxs_x3,boundbxs_y3],[boundbxs_x2,boundbxs_y2],[boundbxs_x4,boundbxs_y4]]
|
||
return contours_rec
|
||
|
||
def remove_simivalue(list1,list2):
|
||
'''
|
||
将list1中属于list2的元素都删除。
|
||
输入:两个嵌套列表
|
||
返回:嵌套列表
|
||
'''
|
||
list33=list1.copy()
|
||
for i in range(len(list1)):
|
||
for j in range(len(list2)):
|
||
if list2[j] == list1[i]:
|
||
# list33.pop(list1[i])
|
||
list33.remove(list1[i])
|
||
return list33
|
||
|
||
def remove_sameeleme_inalist(list3):
|
||
'''
|
||
将list3中重复嵌套列表元素删除。
|
||
输入:嵌套列表
|
||
返回:嵌套列表
|
||
'''
|
||
list3=list3
|
||
list4=[]
|
||
list4.append(list3[0])
|
||
for dict in list3:
|
||
k=0
|
||
for item in list4:
|
||
if dict!=item:
|
||
k=k+1
|
||
else:
|
||
break
|
||
if k==len(list4):
|
||
list4.append(dict)
|
||
return list4
|
||
|
||
def order_points(pts):
|
||
''' sort rectangle points by clockwise '''
|
||
sort_x = pts[np.argsort(pts[:, 0]), :]
|
||
|
||
Left = sort_x[:2, :]
|
||
Right = sort_x[2:, :]
|
||
# Left sort
|
||
Left = Left[np.argsort(Left[:, 1])[::-1], :]
|
||
# Right sort
|
||
Right = Right[np.argsort(Right[:, 1]), :]
|
||
return np.concatenate((Left, Right), axis=0)
|
||
|
||
def mixDrowing_water_postprocess(preds,_mask_cv,pars ):
|
||
'''还未考虑船上人过滤'''
|
||
'''输入:落水人员的结果(类别+坐标)、原图、mask图像
|
||
过程:获得mask的轮廓,判断人员是否在轮廓内。
|
||
在,则保留且绘制;不在,舍弃。
|
||
返回:最终绘制的结果图、最终落水人员(坐标、类别、置信度),
|
||
'''
|
||
|
||
t0=time.time()
|
||
'''1、最大分割水域作为判断依据'''
|
||
img_gray = cv2.cvtColor(_mask_cv, cv2.COLOR_BGR2GRAY) if len(_mask_cv.shape)==3 else _mask_cv
|
||
contours, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||
# 寻找轮廓(多边界)
|
||
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, 2)
|
||
contour_info = []
|
||
for c in contours:
|
||
contour_info.append((
|
||
c,
|
||
cv2.isContourConvex(c),
|
||
cv2.contourArea(c),
|
||
))
|
||
contour_info = sorted(contour_info, key=lambda c: c[2], reverse=True)
|
||
max_contour = contour_info[0]
|
||
#print(max_contour)
|
||
t1=time.time()
|
||
'''2、preds中head+person取出,boat取出。'''
|
||
init_head_person=[]
|
||
init_boat = []
|
||
for i in range(len(preds)):
|
||
#if preds[i][4]=='head' or preds[i][4]=='person':
|
||
if preds[i][0]==0 or preds[i][0]==1:
|
||
init_head_person.append(preds[i])
|
||
else:
|
||
init_boat.append(preds[i])
|
||
t2=time.time()
|
||
'''3、preds中head+person,通过1中水域过滤'''
|
||
init_head_person_filterwater=init_head_person
|
||
final_head_person_filterwater=[]
|
||
for i in range(len(init_head_person_filterwater)):
|
||
center_x, center_y=center_coordinate(init_head_person_filterwater[i])
|
||
flag = cv2.pointPolygonTest(max_contour[0], (center_x, center_y), False) #若为False,会找点是否在内,外,或轮廓上(相应返回+1, -1, 0)。
|
||
if flag==1:
|
||
final_head_person_filterwater.append(init_head_person_filterwater[i])
|
||
else:
|
||
pass
|
||
t3=time.time()
|
||
'''4、水域过滤后的head+person,再通过船舶范围过滤'''
|
||
init_head_person_filterboat=final_head_person_filterwater
|
||
# final_head_person_filterboat=[]
|
||
#获取船舶范围
|
||
boat_contour=[]
|
||
for i in range(len(init_boat)):
|
||
boundbxs1=[init_boat[i][0],init_boat[i][1],init_boat[i][2],init_boat[i][3]]
|
||
contour_temp=fourcorner_coordinate(boundbxs1) #得到boat预测框的顺序contour
|
||
contour_temp_=np.array(contour_temp)
|
||
contour_temp_=np.float32(contour_temp_)
|
||
boat_contour.append(np.array(contour_temp_))
|
||
# 遍历船舶范围,取出在船舶范围内的head和person(可能有重复元素)
|
||
list_headperson_inboat=[]
|
||
for i in range(len(init_head_person_filterboat)):
|
||
for j in range(len(boat_contour)):
|
||
center_x, center_y=center_coordinate(init_head_person_filterboat[i])
|
||
# yyyyyyyy=boat_contour[j]
|
||
flag = cv2.pointPolygonTest(boat_contour[j], (center_x, center_y), False) #若为False,会找点是否在内,外,或轮廓上(相应返回+1, -1, 0)。
|
||
if flag==1:
|
||
list_headperson_inboat.append(init_head_person_filterboat[i])
|
||
else:
|
||
pass
|
||
|
||
if len(list_headperson_inboat)==0:
|
||
pass
|
||
else:
|
||
list_headperson_inboat=remove_sameeleme_inalist(list_headperson_inboat) #将重复嵌套列表元素删除
|
||
# 过滤船舶范围内的head和person
|
||
final_head_person_filterboat=remove_simivalue(init_head_person_filterboat,list_headperson_inboat)
|
||
|
||
t4=time.time()
|
||
timeInfos = '%.1f (step1:%.1f step2:%.2f step3:%.3f step4:%.1f) ' %( ms(t4,t0), ms(t1,t0),ms(t2,t1),ms(t3,t2),ms(t4,t3) )
|
||
|
||
|
||
|
||
return final_head_person_filterboat,timeInfos #返回最终绘制的结果图、最终落水人员(坐标、类别、置信度)
|
||
|