RCAR会议:我的RTFA算法里面的generate_detections.py文件

地址: 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()

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Zebrafish)