''' Realtime Display 3D Human Reconstrction 3D image drawing by pygtagrph based on OpenGL speed about 25 FPS ''' import math import sys from argparse import ArgumentParser import cv2 import pyqtgraph as pg import pyqtgraph.opengl as gl from pyqtgraph.Qt import QtCore, QtGui from pyqtgraph.opengl import * from joints_detectors.openpose.main import load_model as Model2Dload model2D = Model2Dload() from joints_detectors.openpose.main import generate_frame_kpt as OpenPoseInterface interface2D = OpenPoseInterface from tools.utils import videopose_model_load as Model3Dload model3D = Model3Dload() from tools.utils import interface as VideoPoseInterface interface3D = VideoPoseInterface from tools.utils import draw_2Dimg, resize_img, common common = common() item = 0 item_num = 0 pos_init = np.zeros(shape=(17, 3)) class Visualizer(object): def __init__(self, input_video): self.traces = dict() self.app = QtGui.QApplication(sys.argv) self.w = gl.GLViewWidget() self.w.opts['distance'] = 45.0 ## distance of camera from center self.w.opts['fov'] = 60 ## horizontal field of view in degrees self.w.opts['elevation'] = 10 ## camera's angle of elevation in degrees 仰俯角 self.w.opts['azimuth'] = 90 ## camera's azimuthal angle in degrees 方位角 self.w.setWindowTitle('pyqtgraph example: GLLinePlotItem') self.w.setGeometry(450, 700, 980, 700) # 原点在左上角 self.w.show() # create the background grids gx = gl.GLGridItem() gx.rotate(90, 0, 1, 0) gx.translate(-10, 0, 0) self.w.addItem(gx) gy = gl.GLGridItem() gy.rotate(90, 1, 0, 0) gy.translate(0, -10, 0) self.w.addItem(gy) gz = gl.GLGridItem() gz.translate(0, 0, -10) self.w.addItem(gz) # special setting self.cap = cv2.VideoCapture(input_video) self.video_name = input_video.split('/')[-1].split('.')[0] self.kpt2Ds = [] pos = pos_init for j, j_parent in enumerate(common.skeleton_parents): if j_parent == -1: continue x = np.array([pos[j, 0], pos[j_parent, 0]]) * 10 y = np.array([pos[j, 1], pos[j_parent, 1]]) * 10 z = np.array([pos[j, 2], pos[j_parent, 2]]) * 10 - 10 pos_total = np.vstack([x, y, z]).transpose() self.traces[j] = gl.GLLinePlotItem(pos=pos_total, color=pg.glColor((j, 10)), width=6, antialias=True) self.w.addItem(self.traces[j]) def start(self): if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): QtGui.QApplication.instance().exec_() def set_plotdata(self, name, points, color, width): self.traces[name].setData(pos=points, color=color, width=width) def update(self): global item global item_num num = item / 2 azimuth_value = abs(num % 120 + math.pow(-1, int((num / 120))) * 120) % 120 self.w.opts['azimuth'] = azimuth_value print(item, ' ') _, frame = self.cap.read() if item % 2 != 1: frame, W, H = resize_img(frame) joint2D = interface2D(frame, model2D) img2D = draw_2Dimg(frame, joint2D, 1) if item == 0: for _ in range(30): self.kpt2Ds.append(joint2D) elif item < 30: self.kpt2Ds.append(joint2D) self.kpt2Ds.pop(0) else: self.kpt2Ds.append(joint2D) self.kpt2Ds.pop(0) item += 1 joint3D = interface3D(model3D, np.array(self.kpt2Ds), W, H) pos = joint3D[-1] # (17, 3) for j, j_parent in enumerate(common.skeleton_parents): if j_parent == -1: continue x = np.array([pos[j, 0], pos[j_parent, 0]]) * 10 y = np.array([pos[j, 1], pos[j_parent, 1]]) * 10 z = np.array([pos[j, 2], pos[j_parent, 2]]) * 10 - 10 pos_total = np.vstack([x, y, z]).transpose() self.set_plotdata( name=j, points=pos_total, color=pg.glColor((j, 10)), width=6) # save if item_num < 10: name = '000' + str(item_num) elif item_num < 100: name = '00' + str(item_num) elif item_num < 1000: name = '0' + str(item_num) else: name = str(item_num) im3Dname = 'VideoSave/' + '3D_' + name + '.png' d = self.w.renderToArray((img2D.shape[1], img2D.shape[0])) # (W, H) print('Save 3D image: ', im3Dname) pg.makeQImage(d).save(im3Dname) im2Dname = 'VideoSave/' + '2D_' + name + '.png' print('Save 2D image: ', im2Dname) cv2.imwrite(im2Dname, img2D) item_num += 1 else: item += 1 def animation(self): timer = QtCore.QTimer() timer.timeout.connect(self.update) timer.start(1) self.start() def main(): parser = ArgumentParser() parser.add_argument("-i", "--video", help="input video file name", default="/home/xyliu/Videos/sports/dance.mp4") args = parser.parse_args() print(args.video) v = Visualizer(args.video) v.animation() cv2.destroyAllWindows() if __name__ == '__main__': main()