地址: nk_DeepSortYolo/deep_sort_yolov3-master/tools/generate_detections.py
# vim: expandtab:ts=4:sw=4
import os
import errno
import argparse
import numpy as np
import cv2
import tensorflow as tf
from PIL import Image
# from PIL import Image 配合 # TODO 放缩
def _run_in_batches(f, data_dict, out, batch_size): # TODO 4
data_len = len(out)
# print(data_len)为人的个数
num_batches = int(data_len / batch_size)
s, e = 0, 0
for i in range(num_batches):
s, e = i * batch_size, (i + 1) * batch_size
batch_data_dict = {k: v[s:e] for k, v in data_dict.items()}
out[s:e] = f(batch_data_dict)
if e < len(out):
batch_data_dict = {k: v[e:] for k, v in data_dict.items()}
out[e:] = f(batch_data_dict)
# 我们引用了新的放缩方法(此处) def scaling_extract_image_patch: 来让动物的全身特征都加入特征内放缩为(64,128)
# 而不是(下面)的 def extract_image_patch: 提取图片切片是不包含放缩小的直接切成(64,128)宽高的人性切片,
# 但是放缩方法并不好用在行人reid
# TODO 5 一:放缩法 x方向
def scaling_x_extract_image_patch(image, bbox, patch_shape): # patch_shape = image_shape: [128, 64, 3]
# patch_shape = image_shape[:2]=[128, 64]
"""Extract image patch from bounding box.
Parameters
----------
image : ndarray
The full image.
bbox : array_like
The bounding box in format (x, y, width, height).这里的xy指的是左上角点的坐标
patch_shape : Optional[array_like]
This parameter can be used to enforce a desired patch shape
(height, width). First, the `bbox` is adapted to the aspect ratio
of the patch shape, then it is clipped at the image boundaries.
If None, the shape is computed from :arg:`bbox`.
Returns
-------
ndarray | NoneType
An image patch showing the :arg:`bbox`, optionally reshaped to
:arg:`patch_shape`.
Returns None if the bounding box is empty or fully outside of the image
boundaries.
如果bbox空的或者完全离开图像边界,就返回none
"""
# print('bbox:', bbox) # 列表
bbox = np.array(bbox) # 现在是数组
# print('bbox:', bbox)
# bbox1 = bbox
# bbox1[2:] += bbox1[:2]
# bbox1 = bbox1.astype(np.int)
# sx1, sy1, ex1, ey1 = bbox1
# print('bbox:', bbox) # 数组
# 只改变宽度来适应纵横比
'''省略了这里面的剪裁步骤,转而进行下面的放缩过程 # TODO 放缩
if patch_shape is not None: # patch_shape为image_shape[:2]=[128, 64] 高宽
# correct aspect ratio to patch shape
target_aspect = float(patch_shape[1]) / patch_shape[0] # 宽/高 height bbox[3]高在这里没有改变,只改变宽度
new_width = target_aspect * bbox[3] # bbox[3] height
# 新的宽度 = 宽/高 ×bbox[高]
bbox[0] -= (new_width - bbox[2]) / 2 # 中心点x,这里的新的宽度一般是小于原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[2] = new_width
# bbox 新的xywh
'''
# convert (x,y,width,height) to ( left,top,right, bottom ) ltrb
bbox[2:] += bbox[:2]
bbox = bbox.astype(np.int)
# clip at image boundaries
bbox[:2] = np.maximum(0, bbox[:2]) # top,left 取非负
bbox[2:] = np.minimum(np.asarray(image.shape[:2][::-1]) - 1, bbox[2:]) # right,bottom不要过原图像右下界限
if np.any(bbox[:2] >= bbox[2:]): # 图像top left 不能大于 right bottom
return None
sx, sy, ex, ey = bbox # x左 y上 x右 y下
# print('class:', type(image)) #
# print('shape:', image.shape) # (480, 640, 3)
image = image[sy:ey, sx:ex] # y方向,x方向
# image1 = image[sy1:ey1, sx1:ex1]
# TODO 放缩\
# print('class:', type(image)) #
# image = np.rot90(image)
# TODO 放缩0 numpy 截取出来的最初结果
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale-x1' + ".jpg", image)
# print('patch_shape', patch_shape)
image = cv2.resize(image, (patch_shape[1], patch_shape[0])) # TODO 此步骤可以取代后面 放缩1,2,3,4步骤
# patch_shape = [128, 64]
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale-x2-zoom' + ".jpg", image)
'''
# 注释:因为我没有发现cv2针对格式图片有放缩函数 cv2.resize(image, (64, 128)),
# 因而采取了下面转换为Image格式在用 Image里面的image.resize((64, 128))函数,再转换为格式的笨方法.
# 并且此方法还会导致色彩错乱,下面地址可见案例/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/色彩错乱案例
# TODO 放缩1 image 格式转换为Image
image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # 从cv格式转换为Image格式
image.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-1' + ".jpg")
# print('class', type(image)) #
# image = image.rotate(-90) # -90是顺时针旋转90度
# TODO 放缩2 image 放缩为 宽高1:2
image = image.resize((64, 128)) # 调整图片大小
# 此时image
image.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg")
# TODO 放缩3 numpy 再从image格式转换为numpy格式
image = np.reshape(image, (128, 64, 3)) # 如果是灰度图片 把3改为-1
# print('1', type(image))
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-3' + ".jpg", image)
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image1)
# TODO 放缩4 (此步骤貌似可以省略)
image = cv2.resize(image, tuple(patch_shape[::-1])) # resize需要(宽,高)格式 patch_shape 是[高,宽]
# print('2', type(image)) #
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-4' + ".jpg", image)
# resize需要(宽,高)格式 image_shape高宽为[128, 64, 3]
# image_shape[:2]= patch_shape 是[高,宽]
'''
# TODO 放缩/
return image
# 我们引用了新的放缩方法(此处) def scaling_extract_image_patch: 来让动物的全身特征都加入特征内放缩为(64,128)
# 而不是(下面)的 def extract_image_patch: 提取图片切片是不包含放缩小的直接切成(64,128)宽高的人性切片,
# 但是放缩方法并不好用在行人reid
# TODO 5 二(90):放缩法 y方向
def scaling_y_extract_image_patch(image, bbox, patch_shape):
# patch_shape = image_shape[:2]=[128, 64]
"""Extract image patch from bounding box.
Parameters
----------
image : ndarray
The full image.
bbox : array_like
The bounding box in format (x, y, width, height).这里的xy指的是左上角点的坐标
patch_shape : Optional[array_like]
This parameter can be used to enforce a desired patch shape
(height, width). First, the `bbox` is adapted to the aspect ratio
of the patch shape, then it is clipped at the image boundaries.
If None, the shape is computed from :arg:`bbox`.
Returns
-------
ndarray | NoneType
An image patch showing the :arg:`bbox`, optionally reshaped to
:arg:`patch_shape`.
Returns None if the bounding box is empty or fully outside of the image
boundaries.
如果bbox空的或者完全离开图像边界,就返回none
"""
# print('bbox:', bbox) # 列表
bbox = np.array(bbox) # 现在是数组
# print('bbox:', bbox)
# bbox1 = bbox
# bbox1[2:] += bbox1[:2]
# bbox1 = bbox1.astype(np.int)
# sx1, sy1, ex1, ey1 = bbox1
# print('bbox:', bbox) # 数组
# 只改变宽度来适应纵横比
'''省略了这里面的剪裁步骤,转而进行下面的放缩过程 # TODO 放缩
if patch_shape is not None: # patch_shape为image_shape[:2]=[128, 64] 高宽
# correct aspect ratio to patch shape
target_aspect = float(patch_shape[1]) / patch_shape[0] # 宽/高 height bbox[3]高在这里没有改变,只改变宽度
new_width = target_aspect * bbox[3] # bbox[3] height
# 新的宽度 = 宽/高 ×bbox[高]
bbox[0] -= (new_width - bbox[2]) / 2 # 中心点x,这里的新的宽度一般是小于原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[2] = new_width
# bbox 新的xywh
'''
# convert (x,y,width,height) to ( left,top,right, bottom ) ltrb
bbox[2:] += bbox[:2]
bbox = bbox.astype(np.int)
# clip at image boundaries
bbox[:2] = np.maximum(0, bbox[:2]) # top,left 取非负
bbox[2:] = np.minimum(np.asarray(image.shape[:2][::-1]) - 1, bbox[2:]) # right,bottom不要过原图像右下界限
if np.any(bbox[:2] >= bbox[2:]): # 图像top left 不能大于 right bottom
return None
sx, sy, ex, ey = bbox # x左 y上 x右 y下
# print('class:', type(image)) #
# print('shape:', image.shape) # (480, 640, 3)
image = image[sy:ey, sx:ex] # y方向,x方向
# image1 = image[sy1:ey1, sx1:ex1]
# TODO 放缩\
# print('class:', type(image)) #
# image = np.rot90(image)
# TODO 放缩0 numpy 截取出来的最初结果
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale90-y1' + ".jpg", image)
image = cv2.resize(image, (patch_shape[0], patch_shape[1])) # TODO 此步骤可以取代后面 放缩1,2,3,4步骤
# patch_shape = [128, 64]
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale90-y2-zoom' + ".jpg", image)
image = np.rot90(image)
# print('y90', image.shape)
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale90-y3-rot90' + ".jpg", image)
'''旋转 不好用, 报错参数是浮点形应该是整形
# rows, cols, channel = image.shape
# rows = int(rows)
# cols = int(cols)
# print('rows, cols, channel:', rows, ' ', cols, ' ', channel)
# change = cv2.getRotationMatrix2D((rows//2, cols//2), 90, 1)
# image = cv2.warpAffine(image, change, (rows, cols))
'''
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image)
'''
# 注释:因为我没有发现cv2针对格式图片有放缩函数 cv2.resize(image, (64, 128)),
# 因而采取了下面转换为Image格式在用 Image里面的image.resize((64, 128))函数,再转换为格式的笨方法.
# 并且此方法还会导致色彩错乱,下面地址可见案例/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/色彩错乱案例
# TODO 放缩1 image 格式转换为Image
image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # 从cv格式转换为Image格式
image.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-1' + ".jpg")
# print('class', type(image)) #
# image = image.rotate(-90) # -90是顺时针旋转90度
# TODO 放缩2 image 放缩为 宽高1:2
image = image.resize((64, 128)) # 调整图片大小
# 此时image
image.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg")
# TODO 放缩3 numpy 再从image格式转换为numpy格式
image = np.reshape(image, (128, 64, 3)) # 如果是灰度图片 把3改为-1
# print('1', type(image))
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-3' + ".jpg", image)
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image1)
# TODO 放缩4 (此步骤貌似可以省略)
image = cv2.resize(image, tuple(patch_shape[::-1])) # resize需要(宽,高)格式 patch_shape 是[高,宽]
# print('2', type(image)) #
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-4' + ".jpg", image)
# resize需要(宽,高)格式 image_shape高宽为[128, 64, 3]
# image_shape[:2]= patch_shape 是[高,宽]
'''
# TODO 放缩/
return image
# TODO 5 二(270):放缩法 y方向
def scaling_y_270_extract_image_patch(image, bbox, patch_shape):
# patch_shape = image_shape[:2]=[128, 64]
"""Extract image patch from bounding box.
Parameters
----------
image : ndarray
The full image.
bbox : array_like
The bounding box in format (x, y, width, height).这里的xy指的是左上角点的坐标
patch_shape : Optional[array_like]
This parameter can be used to enforce a desired patch shape
(height, width). First, the `bbox` is adapted to the aspect ratio
of the patch shape, then it is clipped at the image boundaries.
If None, the shape is computed from :arg:`bbox`.
Returns
-------
ndarray | NoneType
An image patch showing the :arg:`bbox`, optionally reshaped to
:arg:`patch_shape`.
Returns None if the bounding box is empty or fully outside of the image
boundaries.
如果bbox空的或者完全离开图像边界,就返回none
"""
# print('bbox:', bbox) # 列表
bbox = np.array(bbox) # 现在是数组
# print('bbox:', bbox)
# bbox1 = bbox
# bbox1[2:] += bbox1[:2]
# bbox1 = bbox1.astype(np.int)
# sx1, sy1, ex1, ey1 = bbox1
# print('bbox:', bbox) # 数组
# 只改变宽度来适应纵横比
'''省略了这里面的剪裁步骤,转而进行下面的放缩过程 # TODO 放缩
if patch_shape is not None: # patch_shape为image_shape[:2]=[128, 64] 高宽
# correct aspect ratio to patch shape
target_aspect = float(patch_shape[1]) / patch_shape[0] # 宽/高 height bbox[3]高在这里没有改变,只改变宽度
new_width = target_aspect * bbox[3] # bbox[3] height
# 新的宽度 = 宽/高 ×bbox[高]
bbox[0] -= (new_width - bbox[2]) / 2 # 中心点x,这里的新的宽度一般是小于原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[2] = new_width
# bbox 新的xywh
'''
# convert (x,y,width,height) to ( left,top,right, bottom ) ltrb
bbox[2:] += bbox[:2]
bbox = bbox.astype(np.int)
# clip at image boundaries
bbox[:2] = np.maximum(0, bbox[:2]) # top,left 取非负
bbox[2:] = np.minimum(np.asarray(image.shape[:2][::-1]) - 1, bbox[2:]) # right,bottom不要过原图像右下界限
if np.any(bbox[:2] >= bbox[2:]): # 图像top left 不能大于 right bottom
return None
sx, sy, ex, ey = bbox # x左 y上 x右 y下
# print('class:', type(image)) #
# print('shape:', image.shape) # (480, 640, 3)
image = image[sy:ey, sx:ex] # y方向,x方向
# image1 = image[sy1:ey1, sx1:ex1]
# TODO 放缩\
# print('class:', type(image)) #
# image = np.rot90(image)
# TODO 放缩0 numpy 截取出来的最初结果
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale270-y1' + ".jpg", image)
image = cv2.resize(image, (patch_shape[0], patch_shape[1])) # TODO 此步骤可以取代后面 放缩1,2,3,4步骤
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale270-y2-zoom' + ".jpg", image)
image = cv2.flip(image, 0, dst=None) # 水平镜像
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale270-y2-flip' + ".jpg", image)
image = np.rot90(image)
# print('y270', image.shape)
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-scale270-y2-rot90' + ".jpg", image)
'''旋转 不好用, 报错参数是浮点形应该是整形
# rows, cols, channel = image.shape
# rows = int(rows)
# cols = int(cols)
# print('rows, cols, channel:', rows, ' ', cols, ' ', channel)
# change = cv2.getRotationMatrix2D((rows//2, cols//2), 90, 1)
# image = cv2.warpAffine(image, change, (rows, cols))
'''
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image)
'''
# 注释:因为我没有发现cv2针对格式图片有放缩函数 cv2.resize(image, (64, 128)),
# 因而采取了下面转换为Image格式在用 Image里面的image.resize((64, 128))函数,再转换为格式的笨方法.
# 并且此方法还会导致色彩错乱,下面地址可见案例/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/色彩错乱案例
# TODO 放缩1 image 格式转换为Image
image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # 从cv格式转换为Image格式
image.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-1' + ".jpg")
# print('class', type(image)) #
# image = image.rotate(-90) # -90是顺时针旋转90度
# TODO 放缩2 image 放缩为 宽高1:2
image = image.resize((64, 128)) # 调整图片大小
# 此时image
image.save('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg")
# TODO 放缩3 numpy 再从image格式转换为numpy格式
image = np.reshape(image, (128, 64, 3)) # 如果是灰度图片 把3改为-1
# print('1', type(image))
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-3' + ".jpg", image)
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image1)
# TODO 放缩4 (此步骤貌似可以省略)
image = cv2.resize(image, tuple(patch_shape[::-1])) # resize需要(宽,高)格式 patch_shape 是[高,宽]
# print('2', type(image)) #
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-4' + ".jpg", image)
# resize需要(宽,高)格式 image_shape高宽为[128, 64, 3]
# image_shape[:2]= patch_shape 是[高,宽]
'''
# TODO 放缩/
return image
# 此处的提取图片切片是不包含放缩小的直接切成(64,128)宽高的人性切片,
# 因为我们引用了新的放缩方法(在上面) def scaling_extract_image_patch: 来让动物的全身特征都加入特征内放缩为(64,128)
# TODO 5 三:切割法 x方向
def extract_image_patch(image, bbox, patch_shape):
# patch_shape = image_shape[:2]=[128, 64]
"""Extract image patch from bounding box.
Parameters
----------
image : ndarray
The full image.
bbox : array_like
The bounding box in format (x, y, width, height).这里的xy指的是左上角点的坐标
patch_shape : Optional[array_like]
This parameter can be used to enforce a desired patch shape
(height, width). First, the `bbox` is adapted to the aspect ratio
of the patch shape, then it is clipped at the image boundaries.
If None, the shape is computed from :arg:`bbox`.
Returns
-------
ndarray | NoneType
An image patch showing the :arg:`bbox`, optionally reshaped to
:arg:`patch_shape`.
Returns None if the bounding box is empty or fully outside of the image
boundaries.
如果bbox空的或者完全离开图像边界,就返回none
"""
# print('bbox:', bbox) # 列表
bbox = np.array(bbox)
# bbox1 = bbox
# bbox1[2:] += bbox1[:2]
# bbox1 = bbox1.astype(np.int)
# sx1, sy1, ex1, ey1 = bbox1
# print('bbox:', bbox) # 数组
# 只改变宽度来适应纵横比
if patch_shape is not None: # patch_shape为image_shape[:2]=[128, 64] 高宽
# correct aspect ratio to patch shape
target_aspect = float(patch_shape[1]) / patch_shape[0] # 宽/高 height bbox[3]高在这里没有改变,只改变宽度
new_width = target_aspect * bbox[3] # bbox[3] height
# 新的宽度 = 宽/高 ×bbox[高]
bbox[0] -= (new_width - bbox[2]) / 2 # 中心点x,这里的新的宽度一般是小雨原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[2] = new_width
# bbox 新的xywh
# convert (x,y,width,height) to ( left,top,right, bottom ) ltrb
bbox[2:] += bbox[:2]
bbox = bbox.astype(np.int)
# clip at image boundaries
bbox[:2] = np.maximum(0, bbox[:2]) # top,left 取非负
bbox[2:] = np.minimum(np.asarray(image.shape[:2][::-1]) - 1, bbox[2:]) # right,bottom不要过原图像右下界限
if np.any(bbox[:2] >= bbox[2:]): # 图像top left 不能大于 right bottom
return None
sx, sy, ex, ey = bbox # x左 y上 x右 y下
image = image[sy:ey, sx:ex] # y方向,x方向
# image1 = image[sy1:ey1, sx1:ex1]
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut-x1' + ".jpg", image)
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image1)
image = cv2.resize(image, tuple(patch_shape[::-1])) #
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut-x2-zoom' + ".jpg", image)
# resize需要(宽,高)格式 image_shape高宽为[128, 64, 3]
# image_shape[:2]= patch_shape 是[高,宽]
return image
# 此处的提取图片切片是不包含放缩小的直接切成(64,128)宽高的人性切片,
# 因为我们引用了新的放缩方法(在上面) def scaling_extract_image_patch: 来让动物的全身特征都加入特征内放缩为(64,128)
# TODO 5 四(90):切割法 y方向
def y_extract_image_patch(image, bbox, patch_shape):
# patch_shape = image_shape[:2]=[128, 64]
"""Extract image patch from bounding box.
Parameters
----------
image : ndarray
The full image.
bbox : array_like
The bounding box in format (x, y, width, height).这里的xy指的是左上角点的坐标
patch_shape : Optional[array_like]
This parameter can be used to enforce a desired patch shape
(height, width). First, the `bbox` is adapted to the aspect ratio
of the patch shape, then it is clipped at the image boundaries.
If None, the shape is computed from :arg:`bbox`.
Returns
-------
ndarray | NoneType
An image patch showing the :arg:`bbox`, optionally reshaped to
:arg:`patch_shape`.
Returns None if the bounding box is empty or fully outside of the image
boundaries.
如果bbox空的或者完全离开图像边界,就返回none
"""
# print('bbox:', bbox) # 列表
bbox = np.array(bbox)
# bbox1 = bbox
# bbox1[2:] += bbox1[:2]
# bbox1 = bbox1.astype(np.int)
# sx1, sy1, ex1, ey1 = bbox1
# print('bbox:', bbox) # 数组
# 只改变宽度来适应纵横比
if patch_shape is not None: # patch_shape为image_shape[:2]=[128, 64] 高宽
# correct aspect ratio to patch shape
# patch_shape[1] = 64
'''错误示范
target_aspect = float(patch_shape[0]) / patch_shape[1] # 128/64 height bbox[3]高在这里没有改变,只改变宽度
new_width = target_aspect * bbox[3] # bbox[3] height
# 新的宽度 = 宽/高(1/2) ×bbox[高]
bbox[0] -= (new_width - bbox[2]) / 2 # 中心点x,这里的新的宽度一般是小雨原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[2] = new_width
# bbox 新的xywh
'''
###
target_aspect = float(patch_shape[1]) / patch_shape[0] # 64/128 height bbox[3]高在这里没有改变,只改变宽度
new_height = target_aspect * bbox[2] # bbox[2] width
# 新的高 = 宽/高(1/2) ×bbox[宽]
bbox[1] -= (new_height - bbox[3]) / 2 # 中心点x,这里的新的宽度一般是小雨原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[3] = new_height
# bbox 新的xywh
###
# convert (x,y,width,height) to ( left,top,right, bottom ) ltrb
bbox[2:] += bbox[:2]
bbox = bbox.astype(np.int)
# clip at image boundaries
bbox[:2] = np.maximum(0, bbox[:2]) # top,left 取非负
bbox[2:] = np.minimum(np.asarray(image.shape[:2][::-1]) - 1, bbox[2:]) # right,bottom不要过原图像右下界限
if np.any(bbox[:2] >= bbox[2:]): # 图像top left 不能大于 right bottom
return None
sx, sy, ex, ey = bbox # x左 y上 x右 y下
image = image[sy:ey, sx:ex] # y方向,x方向
# image1 = image[sy1:ey1, sx1:ex1]
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut90-y1' + ".jpg", image)
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image1)
image = cv2.resize(image, tuple(patch_shape)) #
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut90-y2-zoom' + ".jpg", image)
image = np.rot90(image, 1) # 地面朝向右边
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut90-y3-rot90' + ".jpg", image)
# resize需要(宽,高)格式 image_shape高宽为[128, 64, 3]
# image_shape[:2]= patch_shape 是[高,宽]
return image
# TODO 5 四(270):切割法 y方向
def y_270_extract_image_patch(image, bbox, patch_shape):
# patch_shape = image_shape[:2]=[128, 64]
"""Extract image patch from bounding box.
Parameters
----------
image : ndarray
The full image.
bbox : array_like
The bounding box in format (x, y, width, height).这里的xy指的是左上角点的坐标
patch_shape : Optional[array_like]
This parameter can be used to enforce a desired patch shape
(height, width). First, the `bbox` is adapted to the aspect ratio
of the patch shape, then it is clipped at the image boundaries.
If None, the shape is computed from :arg:`bbox`.
Returns
-------
ndarray | NoneType
An image patch showing the :arg:`bbox`, optionally reshaped to
:arg:`patch_shape`.
Returns None if the bounding box is empty or fully outside of the image
boundaries.
如果bbox空的或者完全离开图像边界,就返回none
"""
# print('bbox:', bbox) # 列表
bbox = np.array(bbox)
# bbox1 = bbox
# bbox1[2:] += bbox1[:2]
# bbox1 = bbox1.astype(np.int)
# sx1, sy1, ex1, ey1 = bbox1
# print('bbox:', bbox) # 数组
# 只改变宽度来适应纵横比
if patch_shape is not None: # patch_shape为image_shape[:2]=[128, 64] 高宽
# correct aspect ratio to patch shape
# patch_shape[1] = 64
target_aspect = float(patch_shape[1]) / patch_shape[0] # 64/128 height bbox[3]高在这里没有改变,只改变宽度
new_height = target_aspect * bbox[2] # bbox[2] width
# 新的高 = 宽/高(1/2) ×bbox[宽]
bbox[1] -= (new_height - bbox[3]) / 2 # 中心点x,这里的新的宽度一般是小雨原来宽度,所以--为+最后是加
# bbox(x, y, width, height)
# bbox[2]是原来的宽, x - (新宽 - 原来宽)/2
bbox[3] = new_height
# bbox 新的xywh
# convert (x,y,width,height) to ( left,top,right, bottom ) ltrb
bbox[2:] += bbox[:2]
bbox = bbox.astype(np.int)
# clip at image boundaries
bbox[:2] = np.maximum(0, bbox[:2]) # top,left 取非负
bbox[2:] = np.minimum(np.asarray(image.shape[:2][::-1]) - 1, bbox[2:]) # right,bottom不要过原图像右下界限
if np.any(bbox[:2] >= bbox[2:]): # 图像top left 不能大于 right bottom
return None
sx, sy, ex, ey = bbox # x左 y上 x右 y下
image = image[sy:ey, sx:ex] # y方向,x方向
# image1 = image[sy1:ey1, sx1:ex1]
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut270-y1' + ".jpg", image)
# cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-2' + ".jpg", image1)
image = cv2.resize(image, tuple(patch_shape)) #
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut270-y2-zoom' + ".jpg", image)
image = cv2.flip(image, 1, dst=None) # 水平镜像
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut270-y2-mirror' + ".jpg", image)
image = np.rot90(image, 1) # 地面朝向右边
cv2.imwrite('/home/hp/zjc/nk_PyCharm/PyCharm_project/nk_DeepSortYolo/train/' + '-cut270-y3_rot90' + ".jpg", image)
# resize需要(宽,高)格式 image_shape高宽为[128, 64, 3]
# image_shape[:2]= patch_shape 是[高,宽]
return image
'''
# TODO 5 一:放缩法 x方向
def scaling_x_extract_image_patch(image, bbox, patch_shape): # patch_shape = image_shape: [128, 64, 3]
# TODO 5 二(90):放缩法 y方向
def scaling_y_extract_image_patch(image, bbox, patch_shape):
# TODO 5 二(270):放缩法 y方向
def scaling_y_270_extract_image_patch(image, bbox, patch_shape):
# TODO 5 三:切割法 x方向
def extract_image_patch(image, bbox, patch_shape):
# TODO 5 四:切割法(90) y方向
def y_extract_image_patch(image, bbox, patch_shape):
# TODO 5 四:切割法(270) y方向
def y_270_extract_image_patch(image, bbox, patch_shape):
'''
# TODO 被特征1,2调用: 被下面 def create_box_encoder_xy() 与 def create_box_encoder() 调用
class ImageEncoder(object): # TODO ImageEncoder
def __init__(self, checkpoint_filename, input_name="images",
output_name="features"):
self.session = tf.Session()
with tf.gfile.GFile(checkpoint_filename, "rb") as file_handle: # TODO 2 学习tf这部分
graph_def = tf.GraphDef()
# tf.gfile.GFile(filename, mode)
# 获取文本操作句柄,类似于python提供的文本操作open()函数,filename是要打开的文件名,
# mode是以何种方式去读写,将会返回一个文本操作句柄。
graph_def.ParseFromString(file_handle.read())
tf.import_graph_def(graph_def, name="net")
# 将图从graph_def导入到当前默认图中.
# graph_def: 包含要导入到默认图中的操作的GraphDef proto。
self.input_var = tf.get_default_graph().get_tensor_by_name(
"net/%s:0" % input_name)
print('self.input_var:', self.input_var)
# input_var: Tensor("net/images:0", shape=(?, 128, 64, 3), dtype=uint8)
self.output_var = tf.get_default_graph().get_tensor_by_name(
"net/%s:0" % output_name)
print('self.output_name:', self.output_var)
# output_name: Tensor("net/features:0", shape=(?, 128), dtype=float32)
# print('self.input_var', self.input_var) Tensor("net/images:0", shape=(?, 128, 64, 3), dtype=uint8)
# print('self.output_var', self.output_var) Tensor("net/features:0", shape=(?, 128), dtype=float32)
assert len(self.output_var.get_shape()) == 2
assert len(self.input_var.get_shape()) == 4
self.feature_dim = self.output_var.get_shape().as_list()[-1]
self.image_shape = self.input_var.get_shape().as_list()[1:]
# print('self.feature_dim', self.feature_dim) 128
# print('第一个shape:', self.image_shape) 高宽为[128, 64, 3]
def __call__(self, data_x, batch_size=32):
out = np.zeros((len(data_x), self.feature_dim), np.float32)
# print(data_x) # 为(1, 128, 64, 3)的四维数组多层嵌套,两个人就1变2
# print(data_x.shape)
# print(len(data_x)) # 为1
# print('zeros:', out.shape) # 为(1,128)一个人,128特征 [[0.17.., ... ,0.066..]]数组
_run_in_batches(
lambda x: self.session.run(self.output_var, feed_dict=x),
{self.input_var: data_x}, out, batch_size)
# def _run_in_batches(f, data_dict, out, batch_size):
# f
# data_dict {self.input_var: data_x}
# out.shape为(1,128)一个人,128特征 数组形式
# batch_size为1
# TODO 3 print('ImageEncoder结果输出out为:', '\n', out, '\n', out.shape)
return out
# TODO 特征1: x方向, y90方向, y270方向, 三特征综合考虑
def create_box_encoder_xy(model_filename, input_name="images",
output_name="features", batch_size=32): # TODO 1 encoder(model_filename, batch_size=1)
image_encoder = ImageEncoder(model_filename, input_name, output_name) # TODO ImageEncoder
# image_encoder= out [[0.17.., ... ,0.066..][..., ..., ...]] (2,128) 数组含义,两个人,128特征
# print('image_encoder:', image_encoder)
# image_encoder:
image_shape = image_encoder.image_shape
# print('image_shape:', image_shape)
# image_shape: [128, 64, 3]
# print('image_shape:', image_shape) # self.image_shape高宽为[128, 64, 3]
def encoder(image, boxes):
print('-->三特征create_box_encoder_xy')
image_patches = []
image_patches_y = [] # todo y
image_patches_y_270 = [] # todo y270
for box in boxes: # 此处循环, 针对每个目标进行处理
patch = scaling_x_extract_image_patch(image, box, image_shape[:2]) # TODO 5
patch_y = scaling_y_extract_image_patch(image, box, image_shape[:2]) # todo y
patch_y_270 = scaling_y_270_extract_image_patch(image, box, image_shape[:2]) # todo y270
'''
# TODO 5 一:放缩法 x方向
def scaling_x_extract_image_patch(image, bbox, patch_shape): # patch_shape = image_shape: [128, 64, 3]
# TODO 5 二(90):放缩法 y方向
def scaling_y_extract_image_patch(image, bbox, patch_shape):
# TODO 5 二(270):放缩法 y方向
def scaling_y_270_extract_image_patch(image, bbox, patch_shape):
# TODO 5 三:切割法 x方向
def extract_image_patch(image, bbox, patch_shape):
# TODO 5 四:切割法(90) y方向
def y_extract_image_patch(image, bbox, patch_shape):
# TODO 5 四:切割法(270) y方向
'''
# patch = extract_image_patch(image, box, image_shape[:2]) # TODO 5
# patch_y = y_extract_image_patch(image, box, image_shape[:2]) # todo y
# patch_y_270 = y_270_extract_image_patch(image, box, image_shape[:2]) # todo y270
print('pathce.shape:', patch.shape) # features.shape (1, 128)
print('pathce_y.shape:', patch_y.shape) # features_y.shape (2, 128)
print('pathce_y_270.shape:', patch_y_270.shape) # features__270.shape (0, 128)s
# TODO 5 extract_image_patch & scaling_x_extract_image_patch
# print('格式:', type(patch)) #
# image_shape[:2]=[128, 64]
# type(patch)是numpy.ndarray数组
# TODO patch是正常的纵向reid,patch2,patch3是横向
if patch is None:
print("WARNING: Failed to extract image patch: %s." % str(box))
patch = np.random.uniform(
0., 255., image_shape).astype(np.uint8) # 在0到255范围内随机取,矩阵是[128,64]的随机数
if patch_y is None: # todo y
print("WARNING: Failed to extract image patch: %s." % str(box))
patch_y = np.random.uniform(
0., 255., image_shape).astype(np.uint8) # 在0到255范围内随机取,矩阵是[128,64]的随机数
if patch_y_270 is None: # todo y
print("WARNING: Failed to extract image patch: %s." % str(box))
patch_y_270 = np.random.uniform(
0., 255., image_shape).astype(np.uint8) # 在0到255范围内随机取,矩阵是[128,64]的随机数
image_patches.append(patch) # 出现了几个人,就有几个box,就有几个patch
image_patches_y.append(patch_y) # 出现了几个人,就有几个box,就有几个patch # todo y
image_patches_y_270.append(patch_y_270) # 出现了几个人,就有几个box,就有几个patch # todo y270
# type(image_patches) 是列表
image_patches = np.asarray(image_patches) # image_patches -->
image_patches_y = np.asarray(image_patches_y) # todo y
image_patches_y_270 = np.asarray(image_patches_y_270) # todo y270
# type(image_patches)是numpy.ndarray数组
# print('batch_size', batch_size) # 永远都是1
# print('image_patches', image_patches)
return image_encoder(image_patches, batch_size), \
image_encoder(image_patches_y, batch_size),\
image_encoder(image_patches_y_270, batch_size)
return encoder
# TODO 特征2: 原始的x方向单一特征
def create_box_encoder(model_filename, input_name="images",
output_name="features", batch_size=32): # TODO 1 encoder(model_filename, batch_size=1)
image_encoder = ImageEncoder(model_filename, input_name, output_name) # TODO ImageEncoder
# image_encoder= out [[0.17.., ... ,0.066..][..., ..., ...]] (2,128) 数组含义,两个人,128特征
# print('image_encoder:', image_encoder)
# image_encoder:
image_shape = image_encoder.image_shape
# print('image_shape:', image_shape)
# image_shape: [128, 64, 3]
# print('image_shape:', image_shape) # self.image_shape高宽为[128, 64, 3]
def encoder(image, boxes):
print('-->单特征create_box_encoder')
image_patches = []
# image_patches_y = [] # todo y
# image_patches_y_270 = [] # todo y270
for box in boxes: # 此处循环, 针对每个目标进行处理
patch = extract_image_patch(image, box, image_shape[:2]) # TODO 5 x 缩放法
# patch_y = scaling_y_extract_image_patch(image, box, image_shape[:2]) # todo y
# patch_y_270 = scaling_y_270_extract_image_patch(image, box, image_shape[:2]) # todo y270
# TODO 5 extract_image_patch & scaling_x_extract_image_patch
# print('格式:', type(patch)) #
# image_shape[:2]=[128, 64]
# type(patch)是numpy.ndarray数组
# TODO patch是正常的纵向reid,patch2,patch3是横向
if patch is None:
print("WARNING: Failed to extract image patch: %s." % str(box))
patch = np.random.uniform(
0., 255., image_shape).astype(np.uint8) # 在0到255范围内随机取,矩阵是[128,64]的随机数
'''
if patch_y is None: # todo y
print("WARNING: Failed to extract image patch: %s." % str(box))
patch_y = np.random.uniform(
0., 255., image_shape).astype(np.uint8) # 在0到255范围内随机取,矩阵是[128,64]的随机数
if patch_y_270 is None: # todo y
print("WARNING: Failed to extract image patch: %s." % str(box))
patch_y_270 = np.random.uniform(
0., 255., image_shape).astype(np.uint8) # 在0到255范围内随机取,矩阵是[128,64]的随机数
'''
image_patches.append(patch) # 出现了几个人,就有几个box,就有几个patch
# image_patches_y.append(patch_y) # 出现了几个人,就有几个box,就有几个patch # todo y
# image_patches_y.append(patch_y_270) # 出现了几个人,就有几个box,就有几个patch # todo y270
# type(image_patches) 是列表
image_patches = np.asarray(image_patches) # image_patches -->
# image_patches_y = np.asarray(image_patches_y) # todo y
# image_patches_y_270 = np.asarray(image_patches_y_270) # todo y270
# type(image_patches)是numpy.ndarray数组
# print('batch_size', batch_size) # 永远都是1
# print('image_patches', image_patches)
return image_encoder(image_patches, batch_size)
# image_encoder(image_patches_y, batch_size), image_encoder(image_patches_y_270, batch_size)
return encoder
def generate_detections(encoder, mot_dir, output_dir, detection_dir=None):
"""Generate detections with features.
Parameters
----------
encoder : Callable[image, ndarray] -> ndarray
The encoder function takes as input a BGR color image and a matrix of
bounding boxes in format `(x, y, w, h)` and returns a matrix of
corresponding feature vectors.
mot_dir : str
Path to the MOTChallenge directory (can be either train or test).
output_dir
Path to the output directory. Will be created if it does not exist.
detection_dir
Path to custom detections. The directory structure should be the default
MOTChallenge structure: `[sequence]/det/det.txt`. If None, uses the
standard MOTChallenge detections.
"""
if detection_dir is None:
detection_dir = mot_dir
try:
os.makedirs(output_dir)
except OSError as exception:
if exception.errno == errno.EEXIST and os.path.isdir(output_dir):
pass
else:
raise ValueError(
"Failed to created output directory '%s'" % output_dir)
for sequence in os.listdir(mot_dir):
print("Processing %s" % sequence)
sequence_dir = os.path.join(mot_dir, sequence)
image_dir = os.path.join(sequence_dir, "img1")
image_filenames = {
int(os.path.splitext(f)[0]): os.path.join(image_dir, f)
for f in os.listdir(image_dir)}
detection_file = os.path.join(
detection_dir, sequence, "det/det.txt")
detections_in = np.loadtxt(detection_file, delimiter=',')
detections_out = []
frame_indices = detections_in[:, 0].astype(np.int)
min_frame_idx = frame_indices.astype(np.int).min()
max_frame_idx = frame_indices.astype(np.int).max()
for frame_idx in range(min_frame_idx, max_frame_idx + 1):
print("Frame %05d/%05d" % (frame_idx, max_frame_idx))
mask = frame_indices == frame_idx
rows = detections_in[mask]
if frame_idx not in image_filenames:
print("WARNING could not find image for frame %d" % frame_idx)
continue
bgr_image = cv2.imread(
image_filenames[frame_idx], cv2.IMREAD_COLOR)
features = encoder(bgr_image, rows[:, 2:6].copy())
detections_out += [np.r_[(row, feature)] for row, feature
in zip(rows, features)]
output_filename = os.path.join(output_dir, "%s.npy" % sequence)
np.save(
output_filename, np.asarray(detections_out), allow_pickle=False)
def parse_args():
"""Parse command line arguments.
"""
parser = argparse.ArgumentParser(description="Re-ID feature extractor")
parser.add_argument(
"--model",
default="resources/networks/mars-small128.pb",
help="Path to freezed inference graph protobuf.")
parser.add_argument(
"--mot_dir", help="Path to MOTChallenge directory (train or test)",
required=True)
parser.add_argument(
"--detection_dir", help="Path to custom detections. Defaults to "
"standard MOT detections Directory structure should be the default "
"MOTChallenge structure: [sequence]/det/det.txt", default=None)
parser.add_argument(
"--output_dir", help="Output directory. Will be created if it does not"
" exist.", default="detections")
return parser.parse_args()
def main():
args = parse_args()
encoder = create_box_encoder(args.model, batch_size=32)
generate_detections(encoder, args.mot_dir, args.output_dir,
args.detection_dir)
if __name__ == "__main__":
main()