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 #返回最终绘制的结果图、最终落水人员(坐标、类别、置信度)