首页 > 其他 > 详细

GEI步态能量图生成

时间:2019-05-24 13:40:08      阅读:621      评论:0      收藏:0      [点我收藏+]

步态能量图生成主要有两步,主要为:

  1. 在原始轮廓图上对人的轮廓进行裁剪,在下面制作步态能量图图片叠加以什么为中心位置也是一个问题。。我这里采用的是中心位置为人体宽的一半。当然也可以以头为中心位置。如:下图为原始图像与裁剪后的图像

    技术分享图片

    技术分享图片

  2. 对裁剪后图像合成,一个步态周期的图像合成一个步态能量图,步态周期如何判断,网上有一些方法,这里直接是手动指定的。如下图为一个步态周期

    技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片 技术分享图片

    合成的步态能量图为:

    技术分享图片

代码如下裁剪轮廓,存放到文件夹中,在通过裁剪的图生成GEI

原数据目录的格式为:

技术分享图片

裁剪后的数据目录格式为:与原数据一样

技术分享图片

生成步态能量图的数据的目录格式为:即同一个人的步态能量图放在一起。不管角度是多少

技术分享图片

import os
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

def cut_image(path,cut_path,size):
    '''
    将人的轮廓切割出来,并以相同的命名与目录格式存放到cut_path的文件夹中
    :param path:原始图片的文件夹位置如"./silhoutettes"
    :param cut_path:要存放切割后图片的文件夹位置如"./cut"
    :param size:裁剪生成的图片大小
    :return:
    '''
    # 若当前文件为.png或者.jpg图片,也可以为其他图片格式。需多加一个判断
    if path.endswith('.png') or path.endswith('.jpg'):
        # 获得切割后的图片,若图片不符合格式则跳过
        image,flag = cut(Image.open(path))
        if flag: return
        # 存储图片
        Image.fromarray(image).convert('L').resize((size,size)).save(cut_path)
        return

    for next_path in os.listdir(path):
        # 递归,同时若要存放的目录不存在,则生成要存放的目录
        if not os.path.exists(cut_path):
            os.makedirs(cut_path)
        cut_image(os.path.join(path,next_path),os.path.join(cut_path,next_path),size)

def cut(image):
    '''
    通过找到人的最小最大高度与宽度把人的轮廓分割出来,、
    因为原始轮廓图为二值图,因此头顶为将二值图像列相加后,形成一列后第一个像素值不为0的索引。
    同理脚底为形成一列后最后一个像素值不为0的索引。
    人的宽度也同理。
    :param image: 需要裁剪的图片 N*M的矩阵
    :return: temp:裁剪后的图片 size*size的矩阵。flag:是否是符合要求的图片
    '''
    image = np.array(image)

    # 找到人的最小最大高度与宽度
    height_min = (image.sum(axis=1)!=0).argmax()
    height_max = ((image.sum(axis=1)!=0).cumsum()).argmax()
    width_min = (image.sum(axis=0)!=0).argmax()
    width_max = ((image.sum(axis=0)!=0).cumsum()).argmax()
    # 设置切割后图片的大小,为size*size,因为人的高一般都会大于宽
    size=height_max-height_min
    temp = np.zeros((size,size))
    # 若宽大于高,则此图片为不符合要求的图片
    flag = False
    if size<=width_max-width_min:
        flag = True
        return temp,flag
    # 将width_max-width_min(宽)乘height_max-height_min(高,szie)的人的轮廓图,放在size*size的图片中央
    l = (width_max-width_min)//2
    r = width_max-width_min-l
    # centroid = np.array([(width_max+width_min)/2,(height_max+height_min)/2],dtype='int')
    temp[:,(size//2-l):(size//2+r)] = image[height_min:height_max,width_min:width_max ]
    return temp,flag

def GEI(cut_path,data_path,size,num=None):
    """
    将切割后的轮廓图合成为步态能量图
    :param cut_path:切割后的图片路径string如"./cut"
    :param data_path:生成步态能量图的路径string如"./data"
    :param size:步态能量图的大小,默认为整个文件夹
    :param num:几张图片合成一张步态能量图
    :return:
    """
    # 获得人名
    for name in os.listdir(cut_path):
        cut_name_path = os.path.join(cut_path,name)
        data_name_path = os.path.join(data_path,name)
        k = 0;
        if not os.path.exists(data_name_path):
            os.makedirs(data_name_path)
        # 读取角度文件夹中的图片
        for degree in os.listdir(cut_name_path):
            degree_path = os.path.join(cut_name_path,degree)
            # 读取图片
            imgs = [Image.open(os.path.join(degree_path,img)).convert('L') for img in os.listdir(degree_path)]
            if num==None: num = len(imgs)
            # 将图片以num个分组
            imgs = [imgs[i:i+num] for i in range(0,len(imgs),num)]
            # 合成一个步态能量图,记得除以每组图片的数量
            for i in imgs:
                GEI = np.zeros([size,size])
                for j in i:
                    GEI +=j
                GEI = GEI/len(i)
                Image.fromarray(GEI).convert('L').resize((size,size)).save(os.path.join(data_name_path,str(k)+'.png'))
                k = k+1
    pass


if __name__=='__main__':
    # 裁剪轮廓
    cut_image('./silhouettes','./cut',64)
    # 生成GEI
    GEI('./cut','./data',64,num=16)

GEI步态能量图生成

原文:https://www.cnblogs.com/lolybj/p/10914957.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!