|
- 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的轮廓,判断人员是否在轮廓内。
- 在,则保留且绘制;不在,舍弃。
- 返回:最终绘制的结果图、最终落水人员(坐标、类别、置信度),
- '''
- '''1、最大分割水域作为判断依据'''
- #zoom_factor=4 #缩小因子设置为4,考虑到numpy中分别遍历xy进行缩放耗时大。
- original_height = _mask_cv.shape[0]
- original_width=_mask_cv.shape[1]
-
- zoom_factor = original_width/480.0
-
- zoom_height=int(original_height/zoom_factor)
- zoom_width=int(original_width/zoom_factor)
-
- _mask_cv = cv2.resize(_mask_cv, (zoom_width,zoom_height)) #缩小原图,宽在前,高在后
- t4 = time.time()
- img_gray = cv2.cvtColor(_mask_cv, cv2.COLOR_BGR2GRAY) if len(_mask_cv.shape)==3 else _mask_cv #
- t5 = time.time()
- 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)
- t6 = time.time()
-
- '''新增模块::如果水域为空,则返回原图、无落水人员等。'''
- if contour_info==[]:
- # final_img=_img_cv
- final_head_person_filterwater=[]
- timeInfos=0
- # return final_img, final_head_person_filterwater
- return final_head_person_filterwater,timeInfos
- else:
- max_contour = contour_info[0]
- max_contour=max_contour[0]*zoom_factor# contours恢复原图尺寸
- print(max_contour)
- t7 = time.time()
-
-
- '''2.1、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':
- init_head_person.append(preds[i])
- else:
- init_boat.append(preds[i])
- t8 = time.time()
-
- '''新增模块:2.2、preds中head+person取出,过滤掉head与person中指向同一人的部分,保留同一人的person标签。'''
- init_head=[]
- init_person=[]
- #head与person标签分开
- for i in range(len(init_head_person)):
- if init_head_person[i][4]=='head':
- init_head.append(init_head_person[i])
- else:
- init_person.append(init_head_person[i])
- # person的框形成contours
- person_contour=[]
- for i in range(len(init_person)):
- boundbxs_temp=[init_person[i][0],init_person[i][1],init_person[i][2],init_person[i][3]]
- contour_temp_person=fourcorner_coordinate(boundbxs_temp) #得到person预测框的顺序contour
- contour_temp_person=np.array(contour_temp_person)
- contour_temp_person=np.float32(contour_temp_person)
- person_contour.append(np.array(contour_temp_person))
- # head是否在person的contours内,在说明是同一人,过滤掉。
- list_head=[]
- for i in range(len(init_head)):
- for j in range(len(person_contour)):
- center_x, center_y=center_coordinate(init_head[i])
- flag = cv2.pointPolygonTest(person_contour[j], (center_x, center_y), False) #若为False,会找点是否在内,外,或轮廓上(相应返回+1, -1, 0)。
- if flag==1:
- pass
- else:
- list_head.append(init_head[i])
- # person和最终head合并起来
- init_head_person_temp=init_person+list_head
-
- '''3、preds中head+person,通过1中水域过滤'''
- init_head_person_filterwater=init_head_person_temp
- 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, (center_x, center_y), False) #若为False,会找点是否在内,外,或轮廓上(相应返回+1, -1, 0)。
- if flag==1:
- final_head_person_filterwater.append(init_head_person_filterwater[i])
- else:
- pass
- t9 = 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_))
- t10 = time.time()
- # 遍历船舶范围,取出在船舶范围内的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
- # print('list_headperson_inboat',list_headperson_inboat)
- 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)
- final_output_luoshui=final_head_person_filterboat
- t11 = time.time()
-
- timeInfos=('存图:%s, 过滤标签:%s ,遍历船舶范围:%s,水域过滤后的head+person:%s,水域过滤:%s,head+person、boat取出:%s,新增如果水域为空:%s,找contours:%s,图像改变:%s'
- %((t11-t10) * 1000,(t10-t9) * 1000,(t9-t8) * 1000,(t8-t7) * 1000,(t7-t6) * 1000,(t6-t5) * 1000,(t5-t4) * 1000 ) )
-
- return final_output_luoshui,timeInfos #返回最终绘制的结果图、最终落水人员(坐标、类别、置信度)
-
-
|