def __rnet_detect(self, image, pnet_boxes): #定义函数,包含p网络的的图片框pnet_boxes if len(pnet_boxes) == 0: return [] _img_dataset = [] _pnet_boxes = utils.convert_to_square(pnet_boxes) for _box in _pnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((24, 24)) img_data = self.image_transform(img) - 0.5 _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset).to(self.device) _cls, _offset, _landmak = self.rnet(img_dataset) cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() landmak = _landmak.cpu().data.numpy() boxes = [] idxs, _ = np.where(cls > self.cls[1]) for idx in idxs: _box = _pnet_boxes[idx] #这里把新生成的正方形中的元素,按照索引取出来,定义新的坐标 _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 #宽高 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] #通过建议框,偏移量,计算出在原图上的坐标点 y1 = _y1 + oh * offset[idx][1] #这里用h来算偏移量,也可以,因为现在是正方形,边长都一样; x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] x3 = _x1 + ow * landmak[idx][0] y3 = _y1 + oh * landmak[idx][1] x4 = _x2 + ow * landmak[idx][2] y4 = _y1 + oh * landmak[idx][3] x5 = _x1 + ow * landmak[idx][4] y5 = _y1 + oh * landmak[idx][5] x6 = _x1 + ow * landmak[idx][6] y6 = _y2 + oh * landmak[idx][7] x7 = _x2 + ow * landmak[idx][8] y7 = _y2 + oh * landmak[idx][9] boxes.append([ x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, cls[idx][0] ]) # 这里把置信度加进去,for循环前要用 return utils.nms(np.array(boxes), self.nms[1])
def __rnet_detect(self, image, pnet_boxes): _img_dataset = [] _pnet_boxes = utils.convert_to_square(pnet_boxes) for _box in _pnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((24, 24)) img_data = self.__image_transform(img) _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.rnet(img_dataset) _cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() boxes = [] idxs = _cls > 0.8 # print(_cls.shape) idxs = np.squeeze(idxs) # print(idxs.shape) # exit() # print(_pnet_boxes.shape) _box = _pnet_boxes[idxs] # print(_box[0]) #[1291.752 261.65625 1864.8544 834.75867 21.14312] _x1 = np.round(_box[:, 0]) _y1 = np.round(_box[:, 1]) _x2 = np.round(_box[:, 2]) _y2 = np.round(_box[:, 3]) ow = _x2 - _x1 oh = _y2 - _y1 # print(_x1.shape) # print(ow.shape) # print(offset[idxs].shape) x1 = _x1 + ow * offset[idxs][:, 0] y1 = _y1 + oh * offset[idxs][:, 1] x2 = _x2 + ow * offset[idxs][:, 2] y2 = _y2 + oh * offset[idxs][:, 3] _cls = np.squeeze(_cls) cls = _cls[idxs] boxes.append([x1, y1, x2, y2, cls]) boxes = np.array(boxes) print(boxes.shape) boxes = np.squeeze(boxes).transpose((1, 0)) print(boxes.shape) return utils.nms(boxes, 0.3)
def __onet_detect(self, image, rnet_boxes): _img_dataset = [] _rnet_boxes = utils.convert_to_square(rnet_boxes) for _box in _rnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((48, 48)) img_data = self.__image_transform(img) - 0.5 _img_dataset.append(img_data) del _x1, _y1, _x2, _y2, img, img_data img_dataset = torch.stack(_img_dataset) if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.onet(img_dataset) cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() boxes = [] idxs, _ = np.where(cls > 0.9999) # for idx in idxs: # _box = _rnet_boxes[idx] # _x1 = int(_box[0]) # _y1 = int(_box[1]) # _x2 = int(_box[2]) # _y2 = int(_box[3]) # # ow = _x2 - _x1 # oh = _y2 - _y1 # # x1 = _x1 + ow * offset[idx][0] # y1 = _y1 + oh * offset[idx][1] # x2 = _x2 + ow * offset[idx][2] # y2 = _y2 + oh * offset[idx][3] # # # boxes.append([x1, y1, x2, y2, cls[idx][0]]) # del _box,_x1,_y1,_x2,_y2,ow,oh,x1,y1,x2,y2 _box = _rnet_boxes[idxs] _x1 = np.array(_box[:, 0], dtype=np.int) _y1 = np.array(_box[:, 1], dtype=np.int) _x2 = np.array(_box[:, 2], dtype=np.int) _y2 = np.array(_box[:, 3], dtype=np.int) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idxs][:, 0] y1 = _y1 + oh * offset[idxs][:, 1] x2 = _x2 + ow * offset[idxs][:, 2] y2 = _y2 + oh * offset[idxs][:, 3] boxes = np.stack([x1, y1, x2, y2, cls[idxs][:, 0]], axis=1) # return np.array(boxes) return utils.nms(np.array(boxes), 0.7, isMin=True)
def __rnet_detect(self, image, pnet_boxes): _img_dataset = [] # 创建空列表,存放抠图 _pnet_boxes = utils.convert_to_square(pnet_boxes) # ★给p网络输出的框,找出中心点,沿着最大边长的两边扩充成“正方形”,再抠图 for _box in _pnet_boxes: # ★遍历每个框,每个框返回框4个坐标点,抠图,放缩,数据类型转换,添加列表 _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) # 根据4个坐标点抠图 img = img.resize((24, 24)) # 放缩在固尺寸 img_data = self.__image_transform(img) # 将图片数组转成张量 _img_dataset.append(img_data) img_dataset =torch.stack(_img_dataset) # stack堆叠(默认在0轴),此处相当数据类型转换,见例子2★ if self.isCuda: img_dataset = img_dataset.cuda() # 给图片数据采用cuda加速 _cls, _offset = self.rnet(img_dataset) # ★★将24*24的图片传入网络再进行一次筛选 cls = _cls.cpu().data.numpy() # 将gpu上的数据放到cpu上去,在转成numpy数组 offset = _offset.cpu().data.numpy() # print("r_cls:",cls.shape) # (11, 1):P网络生成了11个框 # print("r_offset:", offset.shape) # (11, 4) boxes = [] #R 网络要留下来的框,存到boxes里 idxs, _ = np.where(cls > r_cls) # 原置信度0.6是偏低的,时候很多框并没有用(可打印出来观察),可以适当调高些;idxs置信度框大于0.6的索引;★返回idxs:0轴上索引[0,1],_:1轴上索引[0,0],共同决定元素位置,见例子3 _box = _pnet_boxes[np.array(idxs)] for idx in idxs: # 根据索引,遍历符合条件的框;1轴上的索引,恰为符合条件的置信度索引(0轴上索引此处用不到) _box = _pnet_boxes[idx] _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 # 基准框的宽 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] # 实际框的坐标点 y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] boxes.append([x1, y1, x2, y2, cls[idx][0]]) # 返回4个坐标点和置信度 return utils.nms(np.array(boxes), r_nms) # 原r_nms为0.5(0.5要往小调),上面的0.6要往大调;小于0.5的框被保留下来
def __rnet_detect(self, image, pnet_boxes): print("4") _img_dataset = [] _pnet_boxes = utils.convert_to_square(pnet_boxes) for _box in _pnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((24, 24)) img_data = self.__image_transform(img) _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.rnet(img_dataset) _cls = _cls.cpu().data.numpy() # print(cls) # print(cls.shape) #[N,1] offset = _offset.cpu().data.numpy() # print(offset.shape) #[N,4] boxes = [] # 选取置信度达标的索引 idxs, _ = np.where(_cls > 0.6) # print(idxs) # print(idxs.shape) #[N,] for idx in idxs: # 使用R网络的置信度来筛选P网络的截图 _box = _pnet_boxes[idx] _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] cls = _cls[idx][0] boxes.append([x1, y1, x2, y2, cls]) return utils.nms(np.array(boxes), 0.3)
def __onet_detect(self, image, rnet_boxes): _img_dataset = [] _rnet_boxes = utils.convert_to_square(rnet_boxes) for _box in _rnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((48, 48)) img_data = self.__image_transform(img) _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.onet(img_dataset) _cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() boxes = [] idxs = _cls > 0.9999 # print(_cls.shape) idxs = np.squeeze(idxs) # print(idxs.shape) _box = _rnet_boxes[idxs] _x1 = np.round(_box[:, 0]) _y1 = np.round(_box[:, 1]) _x2 = np.round(_box[:, 2]) _y2 = np.round(_box[:, 3]) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idxs][:, 0] y1 = _y1 + oh * offset[idxs][:, 1] x2 = _x2 + ow * offset[idxs][:, 2] y2 = _y2 + oh * offset[idxs][:, 3] _cls = np.squeeze(_cls) cls = _cls[idxs] boxes.append([x1, y1, x2, y2, cls]) boxes = np.array(boxes) boxes = boxes.squeeze(axis=0).swapaxes(1, 0) #transpose((1, 0)) return utils.nms(boxes, 0.3, isMin=True)
def __onet_detect(self, image, rnet_boxes): _img_dataset = [] # 创建列表,存放抠图r _rnet_boxes = utils.convert_to_square( rnet_boxes) # 给r网络输出的框,找出中心点,沿着最大边长的两边扩充成“正方形” for _box in _rnet_boxes: # 遍历R网络筛选出来的框,计算坐标,抠图,缩放,数据类型转换,添加列表,堆叠 _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) # 根据坐标点“抠图” img = img.resize((48, 48)) img_data = self.__image_transform(img) # 将抠出的图转成张量 _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) # 堆叠,此处相当数据格式转换,见例子2 if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.onet(img_dataset) cls = _cls.cpu().data.numpy() # (1, 1) offset = _offset.cpu().data.numpy() # (1, 4) boxes = [] # 存放o网络的计算结果 # 原o_cls为0.97是偏低的,最后要达到标准置信度要达到0.99999,这里可以写成0.99998, # 这样的话出来就全是人脸;留下置信度大于0.97的框;★返回idxs:0轴上索引[0],_:1轴上索引[0],共同决定元素位置,见例子3 idxs, _ = np.where(cls > o_cls) for idx in idxs: # 根据索引,遍历符合条件的框;1轴上的索引,恰为符合条件的置信度索引(0轴上索引此处用不到) _box = _rnet_boxes[idx] # 以R网络做为基准框 _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 # 框的基准宽,框是“方”的,ow=oh oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][ 0] # O网络最终生成的框的坐标;生样,偏移量△δ=x1-_x1/w*side_len y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] boxes.append([x1, y1, x2, y2, cls[idx][0]]) # 返回4个坐标点和1个置信度 return utils.nms(np.array(boxes), o_nms, isMin=True) # 用最小面积的IOU;原o_nms(IOU)为小于0.7的框被保留下来
def __rnet_detect(self, image, pnet_boxes): _img_dataset = [] _pnet_boxes = utils.convert_to_square(pnet_boxes) for _box in _pnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((24, 24)) img_data = np.array(img) / 255. - 0.5 # print(img_data.shape) _img_dataset.append(img_data) img_dataset = np.stack(_img_dataset) # print(img_dataset.shape) cls, offset = self.rnet.sess.run( [self.rnet.cls_pre, self.rnet.off_pre], feed_dict={self.rnet.input: img_dataset}) # print("debug", cls, offset) boxes = [] idxs, _ = np.where(cls > 0.7) # print(idxs, idxs.shape) for idx in idxs: _box = _pnet_boxes[idx] _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] boxes.append([x1, y1, x2, y2, cls[idx][0]]) return utils.nms(np.array(boxes), 0.5, isMin=True)
def __onet_detect(self, image, rnet_boxes): _img_dataset = [] _rnet_boxes = utils.convert_to_square(rnet_boxes) for _box in _rnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((48, 48)) img_data = self.__image_transform(img) _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.onet(img_dataset) _cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() boxes = [] idxs, _ = np.where(_cls > 0.90) for idx in idxs: _box = _rnet_boxes[idx] _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] cls = _cls[idx][0] boxes.append([x1, y1, x2, y2, cls]) return utils.nms(np.array(boxes), 0.3, isMin=True)
def __rnet_detect(self, image, pnet_boxes): _img_dataset = [] #为了存放扣下来的那堆数据 _pnet_boxes = utils.convert_to_square(pnet_boxes) #把框框从原图上变成一个正方形 for _box in _pnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((24, 24)) img_data = self.__image_transform(img) _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) #组装成矩阵 if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.rnet(img_dataset) cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() boxes = [] idxs, _ = np.where(cls > 0.6) for idx in idxs: _box = _pnet_boxes[idx] #从p网络中选择 _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] boxes.append([x1, y1, x2, y2, cls[idx][0]]) return utils.nms(np.array(boxes), 0.5)
def __rnet_detect(self, image, pnet_boxes): _img_dataset = [] _pnet_boxes = utils.convert_to_square(pnet_boxes) for _box in _pnet_boxes: _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((24, 24)) img_data = self.__image_transform(img) _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) if self.isCuda: img_dataset = img_dataset.cuda() _cls, _offset = self.rnet(img_dataset) _cls = _cls.cpu().data.numpy() offset = _offset.cpu().data.numpy() idxs, _ = np.where(_cls > 0.6) _box = _pnet_boxes[idxs] # print("_box",_box) _x1 = _box[:, 0] _y1 = _box[:, 1] _x2 = _box[:, 2] _y2 = _box[:, 3] ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idxs][:, 0] y1 = _y1 + oh * offset[idxs][:, 1] x2 = _x2 + ow * offset[idxs][:, 2] y2 = _y2 + oh * offset[idxs][:, 3] cls = _cls[idxs][:, 0] boxes = np.stack((x1, y1, x2, y2, cls), axis=1) return utils.nms(boxes, 0.3)
def __onet_detect(self, image, rnet_boxes): if len(rnet_boxes) == 0: return [] _img_dataset = [] _rnet_boxes = utils.convert_to_square(rnet_boxes) #把R网络中的图像生成新的正方形 for _box in _rnet_boxes: #取出坐标 _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) img = image.crop((_x1, _y1, _x2, _y2)) img = img.resize((48, 48)) img_data = self.image_transform(img) - 0.5 _img_dataset.append(img_data) img_dataset = torch.stack(_img_dataset) img_dataset = img_dataset.to(self.device) _cls, _offset, _landmak = self.onet(img_dataset) cls = _cls.cpu().data.numpy() #print('O网络置信度:',cls) offset = _offset.cpu().data.numpy() landmak = _landmak.cpu().data.numpy() boxes = [] idxs, _ = np.where(cls > self.cls[2]) for idx in idxs: _box = _rnet_boxes[idx] _x1 = int(_box[0]) _y1 = int(_box[1]) _x2 = int(_box[2]) _y2 = int(_box[3]) ow = _x2 - _x1 oh = _y2 - _y1 x1 = _x1 + ow * offset[idx][0] #把原图上对应框画出来 y1 = _y1 + oh * offset[idx][1] x2 = _x2 + ow * offset[idx][2] y2 = _y2 + oh * offset[idx][3] x3 = _x1 + ow * landmak[idx][0] y3 = _y1 + oh * landmak[idx][1] x4 = _x2 + ow * landmak[idx][2] y4 = _y1 + oh * landmak[idx][3] x5 = _x1 + ow * landmak[idx][4] y5 = _y1 + oh * landmak[idx][5] x6 = _x1 + ow * landmak[idx][6] y6 = _y2 + oh * landmak[idx][7] x7 = _x2 + ow * landmak[idx][8] y7 = _y2 + oh * landmak[idx][9] boxes.append([ x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, cls[idx][0] ]) return utils.nms(np.array(boxes), self.nms[2], isMin=True) #isMin=True这里去掉当大框覆盖小框的情况;