2024-11-04 13:44:51 +00:00
|
|
|
#encoding = utf8
|
2024-11-24 17:03:29 +00:00
|
|
|
import copy
|
2024-11-04 13:44:51 +00:00
|
|
|
import logging
|
|
|
|
import os
|
2024-11-24 17:03:29 +00:00
|
|
|
import time
|
2024-11-04 13:44:51 +00:00
|
|
|
from queue import Queue
|
|
|
|
|
2024-11-24 16:13:04 +00:00
|
|
|
import cv2
|
|
|
|
import numpy as np
|
2024-11-04 13:44:51 +00:00
|
|
|
import pygame
|
|
|
|
from pygame.locals import *
|
|
|
|
|
|
|
|
from human import HumanContext
|
2024-11-05 14:22:40 +00:00
|
|
|
from utils import config_logging
|
2024-11-04 13:44:51 +00:00
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
current_file_path = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
|
|
|
2024-11-25 21:27:00 +00:00
|
|
|
def cal_box(inv_m, p):
|
|
|
|
x = inv_m[0][0] * p[0] + inv_m[0][1] * p[1] + inv_m[0][2]
|
|
|
|
y = inv_m[1][0] * p[0] + inv_m[1][1] * p[1] + inv_m[1][2]
|
|
|
|
return x, y
|
|
|
|
|
|
|
|
|
2024-11-24 17:03:29 +00:00
|
|
|
def img_warp_back_inv_m(img, img_to, inv_m):
|
2024-11-25 21:27:00 +00:00
|
|
|
h_up, w_up, c = img.shape
|
|
|
|
# mask = np.ones_like(img).astype(np.float32)
|
|
|
|
# inv_mask = cv2.warpAffine(mask, inv_m, (w_up, h_up))
|
|
|
|
# inv_img = cv2.warpAffine(img, inv_m, (w_up, h_up))
|
|
|
|
# mask_indices = inv_mask == 1
|
|
|
|
# if 4 == c:
|
|
|
|
# img_to[:, :, :3][mask_indices] = inv_img[mask_indices]
|
|
|
|
# else:
|
|
|
|
# img_to[inv_mask == 1] = inv_img[inv_mask == 1]
|
|
|
|
# return img_to
|
|
|
|
cv2.imwrite('./face.png', img)
|
|
|
|
tx = inv_m[0][2]
|
|
|
|
ty = inv_m[1][2]
|
|
|
|
|
|
|
|
inv_m[0][2] = 0
|
|
|
|
inv_m[1][2] = 0
|
|
|
|
|
|
|
|
p0 = cal_box(inv_m, (0, 0))
|
|
|
|
p1 = cal_box(inv_m, (w_up, 0))
|
|
|
|
p2 = cal_box(inv_m, (w_up, h_up))
|
|
|
|
p3 = cal_box(inv_m, (0, h_up))
|
|
|
|
lp = (min(p0[0], p3[0]), min(p0[1], p1[1]))
|
|
|
|
rp = (max(p2[0], p1[0]), min(p2[1], p3[1]))
|
|
|
|
|
|
|
|
w_up = int(rp[0] - lp[0])
|
|
|
|
h_up = int(rp[1] - lp[1])
|
|
|
|
|
|
|
|
print(f'src_x:{w_up}, src_y:{h_up}')
|
|
|
|
inv_m[0][2] = 0
|
|
|
|
inv_m[1][2] = 0
|
|
|
|
|
|
|
|
mask = np.ones_like(img, dtype=np.float32)
|
2024-11-24 17:03:29 +00:00
|
|
|
inv_mask = cv2.warpAffine(mask, inv_m, (w_up, h_up))
|
|
|
|
inv_img = cv2.warpAffine(img, inv_m, (w_up, h_up))
|
2024-11-25 21:27:00 +00:00
|
|
|
cv2.imwrite('./combine_frame.png', inv_img[inv_mask == 1])
|
|
|
|
cv2.imwrite('./combine_frame-1.png', img_to)
|
|
|
|
|
|
|
|
if c == 4:
|
|
|
|
# img_to[30:h, 30:w][:, :, :3] = img
|
|
|
|
img_to[:, :, :3][inv_mask == 1] = inv_img[inv_mask == 1]
|
2024-11-24 17:03:29 +00:00
|
|
|
else:
|
|
|
|
img_to[inv_mask == 1] = inv_img[inv_mask == 1]
|
|
|
|
return img_to
|
|
|
|
|
|
|
|
|
|
|
|
def render_image(context, frame):
|
|
|
|
res_frame, idx, type_ = frame
|
|
|
|
|
|
|
|
if type_ == 0:
|
|
|
|
combine_frame = context.frame_list_cycle[idx]
|
|
|
|
else:
|
|
|
|
bbox = context.coord_list_cycle[idx]
|
|
|
|
combine_frame = copy.deepcopy(context.frame_list_cycle[idx])
|
|
|
|
af = context.align_frames[idx]
|
|
|
|
inv_m = context.inv_m_frames[idx]
|
|
|
|
y1, y2, x1, x2 = bbox
|
|
|
|
try:
|
|
|
|
t = time.perf_counter()
|
|
|
|
res_frame = cv2.resize(res_frame.astype(np.uint8), (x2 - x1, y2 - y1))
|
|
|
|
af[y1:y2, x1:x2] = res_frame
|
|
|
|
combine_frame = img_warp_back_inv_m(af, combine_frame, inv_m)
|
|
|
|
except Exception as e:
|
|
|
|
logging.error(f'resize error:{e}')
|
|
|
|
return
|
|
|
|
|
|
|
|
image = combine_frame
|
|
|
|
return image
|
|
|
|
|
|
|
|
|
2024-11-04 13:44:51 +00:00
|
|
|
class PyGameUI:
|
|
|
|
def __init__(self):
|
|
|
|
self._human_context = None
|
|
|
|
self._queue = None
|
2024-11-25 21:27:00 +00:00
|
|
|
self.screen_ = pygame.display.set_mode((920, 860), HWSURFACE | DOUBLEBUF | RESIZABLE)
|
2024-11-04 13:44:51 +00:00
|
|
|
self.clock = pygame.time.Clock()
|
|
|
|
|
|
|
|
background = os.path.join(current_file_path, '..', 'data', 'background', 'background.jpg')
|
|
|
|
logger.info(f'background: {background}')
|
|
|
|
self._background = pygame.image.load(background).convert()
|
2024-11-25 21:27:00 +00:00
|
|
|
self.background_display_ = pygame.transform.scale(self._background, (920, 860))
|
2024-11-04 13:44:51 +00:00
|
|
|
self._human_image = None
|
|
|
|
self.running = True
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
self._queue = Queue()
|
|
|
|
self._human_context = HumanContext()
|
|
|
|
self._human_context.build()
|
|
|
|
render = self._human_context.render_handler
|
|
|
|
render.set_image_render(self)
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
self.start()
|
|
|
|
while self.running:
|
|
|
|
self.clock.tick(60)
|
|
|
|
for event in pygame.event.get():
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
self.running = False
|
|
|
|
elif event.type == VIDEORESIZE:
|
|
|
|
self.background_display_ = pygame.transform.scale(self._background, event.dict['size'])
|
|
|
|
self.screen_.blit(self.background_display_, (0, 0))
|
2024-11-05 11:40:03 +00:00
|
|
|
self._update_human()
|
2024-11-04 13:44:51 +00:00
|
|
|
if self._human_image is not None:
|
2024-11-24 17:03:29 +00:00
|
|
|
self.screen_.blit(self._human_image, (760, -300))
|
2024-11-24 16:13:04 +00:00
|
|
|
|
|
|
|
fps = self.clock.get_fps()
|
|
|
|
pygame.display.set_caption('fps:{:.2f}'.format(fps))
|
2024-11-04 13:44:51 +00:00
|
|
|
pygame.display.flip()
|
|
|
|
self.stop()
|
|
|
|
pygame.quit()
|
|
|
|
|
|
|
|
def _update_human(self):
|
|
|
|
if self._queue.empty():
|
|
|
|
return
|
2024-11-24 17:03:29 +00:00
|
|
|
|
|
|
|
if self._queue.qsize() > 5:
|
|
|
|
print('render queue is slower')
|
|
|
|
|
2024-11-04 13:44:51 +00:00
|
|
|
image = self._queue.get()
|
2024-11-24 17:03:29 +00:00
|
|
|
image = render_image(self._human_context, image)
|
2024-11-07 23:27:00 +00:00
|
|
|
color_format = "RGB"
|
|
|
|
if 4 == image.shape[2]:
|
|
|
|
color_format = "RGBA"
|
2024-11-24 16:13:04 +00:00
|
|
|
image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA)
|
|
|
|
else:
|
|
|
|
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
2024-11-07 23:27:00 +00:00
|
|
|
|
|
|
|
self._human_image = pygame.image.frombuffer(image.tobytes(), image.shape[1::-1], color_format)
|
2024-11-04 13:44:51 +00:00
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
logger.info('stop')
|
|
|
|
if self._human_context is not None:
|
2024-11-07 00:26:03 +00:00
|
|
|
# self._human_context.pause_talk()
|
2024-11-04 13:44:51 +00:00
|
|
|
self._human_context.stop()
|
|
|
|
|
|
|
|
def on_render(self, image):
|
|
|
|
self._queue.put(image)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
config_logging('../logs/info.log', logging.INFO, logging.INFO)
|
|
|
|
|
|
|
|
logger.info('------------start------------')
|
|
|
|
ui = PyGameUI()
|
|
|
|
ui.run()
|
|
|
|
logger.info('------------finish------------')
|