GEI步态能量图生成
生活随笔
收集整理的這篇文章主要介紹了
GEI步态能量图生成
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
步態能量圖生成主要有兩步,主要為:
在原始輪廓圖上對人的輪廓進行裁剪,在下面制作步態能量圖圖片疊加以什么為中心位置也是一個問題。一般有兩種方式,一種是中心位置為人體寬的一半。另一種是以頭頂為中心位置。如:下圖為原始圖像與裁剪后的圖像
為人體寬一般為中心位置
以頭頂為中心位置
對裁剪后圖像合成,一個步態周期的圖像合成一個步態能量圖,步態周期如何判斷,網上有一些方法,這里直接是手動指定的。如下圖為一個步態周期
以身寬一般為中心合成的步態能量圖為:
以頭頂為中心合成步態能量圖為:
可以看出以頭頂為中心效果比較好
代碼如下裁剪輪廓,存放到與原文件夾相同格式的文件目錄中,在通過裁剪的圖生成GEI
以CISIA-B數據集為例,原文件目錄格式為
生成的剪切圖
生成的一張步態能量圖
這里以一個整個步態序列作為周期
import os
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
def cut_image(path,cut_path,size):
'''
剪切圖片
:param path: 輸入圖片路徑
:param cut_path: 剪切圖片后的輸出路徑
:param size: 要剪切的圖片大小
:return:
'''
for (root,dirs,files) in os.walk(path):
temp = root.replace(path,cut_path)
if not os.path.exists(temp):
os.makedirs(temp)
for file in files:
image,flag = cut(Image.open(os.path.join(root,file)))
if not flag: Image.fromarray(image).convert('L').resize((size,size)).save(os.path.join(temp,file))
pass
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()
head_top = image[height_min,:].argmax()
# 設置切割后圖片的大小,為size*size,因為人的高一般都會大于寬
size=height_max-height_min
temp = np.zeros((size,size))
# 將width_max-width_min(寬)乘height_max-height_min(高,szie)的人的輪廓圖,放在size*size的圖片中央
# l = (width_max-width_min)//2
# r = width_max-width_min-l
# 以頭為中心,將將width_max-width_min(寬)乘height_max-height_min(高,szie)的人的輪廓圖,放在size*size的圖片中央
l1 = head_top-width_min
r1 = width_max-head_top
# 若寬大于高,或頭的左側或右側身子比要生成圖片的一般要大。則此圖片為不符合要求的圖片
flag = False
if size<=width_max-width_min or size//2<r1 or size//2<l1:
flag = True
return temp,flag
# centroid = np.array([(width_max+width_min)/2,(height_max+height_min)/2],dtype='int')
temp[:,(size//2-l1):(size//2+r1)] = image[height_min:height_max,width_min:width_max ]
return temp,flag
def GEI(cut_path,data_path,size):
'''
生成步態能量圖
:param cut_path: 剪切后的圖片路徑
:param data_path: 生成圖片的路徑
:param size: 生成能量圖大小
:return:
'''
for (root,dirs,files) in os.walk(cut_path):
temp = root.replace(cut_path,data_path)
if not os.path.exists(temp):
os.makedirs(temp)
GEI = np.zeros([size,size])
if len(files)!=0:
for file in files:
GEI += Image.open(os.path.join(root,file)).convert('L')
GEI /= len(files)
Image.fromarray(GEI).convert('L').resize((size,size)).save(os.path.join(temp,'1.png'))
pass
if __name__=='__main_':
cut_image("C:\Users\China\Desktop\GaitDatas","C:\Users\China\Desktop\CutImage",126)
GEI("C:\Users\China\Desktop\CutImage","C:\Users\China\Desktop\GEIData",126)
更新:以重心為中心合成GEI(論文常用方式)
import os
from PIL import Image
import numpy as np
def cut_image(path,cut_path,size):
'''
剪切圖片
:param path: 輸入圖片路徑
:param cut_path: 剪切圖片后的輸出路徑
:param size: 要剪切的圖片大小
:return:
'''
for (root,dirs,files) in os.walk(path):
temp = root.replace(path,cut_path)
if not os.path.exists(temp):
os.makedirs(temp)
for file in files:
image,flag = cut(Image.open(os.path.join(root,file)))
if not flag: Image.fromarray(image).convert('L').resize((size[1],size[0])).save(os.path.join(temp,file))
pass
def cut(image):
'''
以重心為中心合成GEI
通過找到人的最小最大高度與寬度把人的輪廓分割出來,、
因為原始輪廓圖為二值圖,因此頭頂為將二值圖像列相加后,形成一列后第一個像素值不為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()
head_top = image[height_min,:].argmax()
# 設置切割后圖片的大小,為size*size,因為人的高一般都會大于寬
size=height_max-height_min
temp = np.zeros((size,size))
#計算質心
N = np.sum(image!=0)
Xy = 0
for i in range(image.shape[0]):
Xy += np.sum(image[i,:]!=0)*i
Xy = Xy//N
Xc = 0
for i in range(image.shape[1]):
Xc += np.sum(image[:, i] != 0) * i
Xc = Xc // N
centroid = (Xc,Xy)
l1 = Xc-int(size*11/16/2)
r1 = Xc+int(size*11/16/2)
# 若寬大于高,或頭的左側或右側身子比要生成圖片的一般要大。則此圖片為不符合要求的圖片
flag = False
if l1>width_min or l1<0 or r1<width_max or r1>image.shape[1]:
flag = True
return temp,flag
# centroid = np.array([(width_max+width_min)/2,(height_max+height_min)/2],dtype='int')
#temp[:,(size//2-l1):(size//2+r1)] = image[height_min:height_max,width_min:width_max ]
temp = image[height_min:height_max,l1:r1]
#print((r1-l1)/size,temp.shape[1]/temp.shape[0],11/16)
#若圖片像素值過少,則圖片也不合格
print(image.sum())
if image.sum()<5000:
flag = False
return temp,flag
def GEI(cut_path,data_path,size,batch=None,strides=None):
'''
生成步態能量圖,若batch或strides為None則將整個序列合成一GEI
:param cut_path: 剪切后的圖片路徑
:param data_path: 生成圖片的路徑
:param size: 生成能量圖大小
:param batch: 多少張圖片合成一張步態能量圖
:param strides: 合成GEI的步長
:return:
'''
for (root,dirs,files) in os.walk(cut_path):
temp = root.replace(cut_path,data_path)
if not os.path.exists(temp):
os.makedirs(temp)
if batch==None or strides==None:
batch_ = len(files)
strides_ = len(files)
else:
batch_ = batch
strides_ = strides
#圖片多余10張才生成GEI
if len(files)>10:
print(len(files))
files.sort()
k = len(os.listdir(temp))
for i in range(0,len(files),strides_):
if i+batch_>len(files):
break
GEI = np.zeros(size)
for file in files[i:i+batch_]:
GEI += Image.open(os.path.join(root, file)).convert('L')
GEI /= batch_
Image.fromarray(GEI).convert('L').save(os.path.join(temp, str(k)+'.png'))
k += 1
pass
# cut_image(r'D:gaitDatasetsGaitDatas08',r'D:gaitDataCut_Caps_64_44_',(126,126))
GEI(r'D:gaitDataCut_Caps_64_44_',r'D:oke_GEI',(64,44))
總結
以上是生活随笔為你收集整理的GEI步态能量图生成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自己对DHCP的理解
- 下一篇: 华硕Zenfone 10正式发布 配备5