diff --git a/src/bodypart.py b/src/bodypart.py index c70f22c..ed4ab32 100644 --- a/src/bodypart.py +++ b/src/bodypart.py @@ -18,6 +18,7 @@ class BodyPart: image_path: str, position: np.ndarray, height: float, + wavy=None, ) -> None: """Initialize the part.""" self.env = env @@ -50,6 +51,8 @@ class BodyPart: dtype=np.float32, ) + self.wavy = wavy + def draw(self) -> None: """Draw the part on the screen.""" # compute position @@ -85,6 +88,23 @@ class BodyPart: self.env.frame.shape[1::-1], ) + if self.wavy: + # move left side of bounding box up and down sinusoidally + self.sin_box = self.wavy(bounding_box.copy(), self.env.frame_count) + + # compute affine transform + sin_mat = cv2.getAffineTransform( + bounding_box[[0, 1, 3]].astype(np.float32), + self.sin_box[[0, 1, 3]].astype(np.float32), + ) + + # apply affine transform to image + warped = cv2.warpAffine( + warped, + sin_mat, + self.env.frame.shape[1::-1], + ) + # replace non black pixels of warped image by frame self.env.avatar[warped[:, :, 3] != 0] = warped[warped[:, :, 3] != 0][:, :3] @@ -97,3 +117,11 @@ class BodyPart: (255, 255, 255), 2, ) + if self.wavy: + cv2.polylines( + self.env.frame, + [self.sin_box.squeeze().astype(int)], + True, + (0, 0, 255), + 2, + ) diff --git a/src/environment.py b/src/environment.py index 030bd48..03cf9c3 100644 --- a/src/environment.py +++ b/src/environment.py @@ -12,6 +12,30 @@ NOSE_LANDMARK = 4 UNREFINED_LANDMARKS = 468 +def earL_wavy(box, t): + box[0, 0, 0] -= np.sin(t / 7) * 11 + box[1, 0, 0] -= np.sin(t / 7) * 11 + return box + + +def earR_wavy(box, t): + box[0, 0, 0] += np.sin(t / 7 + 1) * 11 + box[1, 0, 0] += np.sin(t / 7 + 1) * 11 + return box + + +def moustacheL_wavy(box, t): + box[0, 0, 1] += np.sin(t / 7) * 11 + box[3, 0, 1] += np.sin(t / 7) * 11 + return box + + +def moustacheR_wavy(box, t): + box[1, 0, 1] += np.sin(t / 7 + 1) * 11 + box[2, 0, 1] += np.sin(t / 7 + 1) * 11 + return box + + class Environment: """The environment is the main class of the application. @@ -26,6 +50,8 @@ class Environment: # store reference to webcam self.cam = camera + self.frame_count = 0 + # mediapipe stuff self.mp_drawing = mp.solutions.drawing_utils # type: ignore self.mp_drawing_styles = mp.solutions.drawing_styles # type: ignore @@ -48,12 +74,14 @@ class Environment: "assets/earL.png", np.array([6, 11, -0.5]), 1, + wavy=earL_wavy, ), BodyPart( self, "assets/earR.png", np.array([-6, 11, -0.5]), 1, + wavy=earR_wavy, ), BodyPart( self, @@ -66,12 +94,14 @@ class Environment: "assets/moustacheL.png", np.array([13, -6, 0.1]), 1, + wavy=moustacheL_wavy, ), BodyPart( self, "assets/moustacheR.png", np.array([-13, -6, 0.1]), 1, + wavy=moustacheR_wavy, ), ActiveBodyPart( self, @@ -136,6 +166,8 @@ class Environment: logging.debug("Ignoring empty camera frame.") continue + self.frame_count += 1 + # detect keypoints on frame self.detect_keypoints()