Python Ghost Body Transform / invisibility_cloak.py
Back to Folderpython_hideman/invisibility_cloak.py
Download ZIP
"""
Invisibility Cloak
Powered by doniahub
Link: doniahub.cc
"""
import cv2
import mediapipe as mp
import numpy as np
import time
def calculate_distance(point1, point2):
return np.hypot(point1.x - point2.x, point1.y - point2.y)
def generate_empty_background(frame, raw_seg_mask):
h, w, _ = frame.shape
if raw_seg_mask is None:
return frame.copy()
person_mask = (raw_seg_mask > 0.10).astype(np.uint8) * 255
if np.sum(person_mask > 0) < 1000:
return frame.copy()
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (35, 35))
dilated_person = cv2.dilate(person_mask, kernel, iterations=2)
scale = 0.5
small_frame = cv2.resize(frame, (int(w * scale), int(h * scale)))
small_mask = cv2.resize(dilated_person, (int(w * scale), int(h * scale)))
small_inpaint = cv2.inpaint(small_frame, small_mask, inpaintRadius=5, flags=cv2.INPAINT_TELEA)
inpainted_bg = cv2.resize(small_inpaint, (w, h))
clean_bg = frame.copy()
clean_bg[dilated_person == 255] = inpainted_bg[dilated_person == 255]
print("[INFO] doniahub.cc - Generated AI-erased background plate")
return clean_bg
def draw_hud(frame, invisible_mode, background_frame, gesture_detected, fps):
h, w, _ = frame.shape
overlay = frame.copy()
cv2.rectangle(overlay, (10, 10), (410, 160), (20, 20, 20), -1)
cv2.addWeighted(overlay, 0.75, frame, 0.25, 0, frame)
status_text = "CLOAK: ACTIVE [INVISIBLE]" if invisible_mode else "CLOAK: INACTIVE [NORMAL]"
status_color = (0, 255, 0) if invisible_mode else (0, 0, 255)
cv2.putText(frame, status_text, (25, 42), cv2.FONT_HERSHEY_SIMPLEX, 0.7, status_color, 2)
bg_captured = background_frame is not None
bg_text = "Background: READY" if bg_captured else "Background: INITIALIZING..."
bg_color = (0, 220, 0) if bg_captured else (0, 140, 255)
cv2.putText(frame, bg_text, (25, 75), cv2.FONT_HERSHEY_SIMPLEX, 0.50, bg_color, 1)
gesture_text = "Gesture: PINCH (CLOAK TOGGLED)" if gesture_detected else "Gesture: Open Hand (Ready)"
cv2.putText(frame, gesture_text, (25, 105), cv2.FONT_HERSHEY_SIMPLEX, 0.52, (255, 255, 255), 1)
cv2.putText(frame, f"FPS: {int(fps)} | doniahub.cc", (25, 135), cv2.FONT_HERSHEY_SIMPLEX, 0.50, (200, 200, 200), 1)
if background_frame is not None:
thumb_w, thumb_h = 160, 90
thumb_x = w - thumb_w - 20
thumb_y = 15
thumb_resized = cv2.resize(background_frame, (thumb_w, thumb_h))
frame[thumb_y:thumb_y + thumb_h, thumb_x:thumb_x + thumb_w] = thumb_resized
cv2.rectangle(frame, (thumb_x, thumb_y), (thumb_x + thumb_w, thumb_y + thumb_h), (0, 255, 0), 2)
cv2.putText(frame, "doniahub.cc", (thumb_x + 10, thumb_y + thumb_h + 18),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 1)
cv2.rectangle(overlay, (0, h - 35), (w, h), (15, 15, 15), -1)
cv2.addWeighted(overlay, 0.8, frame, 0.2, 0, frame)
cv2.putText(frame, "doniahub.cc | Pinch: Toggle Invisibility | 'b': Re-Erase BG | 'c': Capture Clean Room | 'q': Quit",
(20, h - 12), cv2.FONT_HERSHEY_SIMPLEX, 0.50, (0, 255, 255), 1, cv2.LINE_AA)
def build_perfect_cloak_mask(frame, raw_seg_mask, hand_landmarks_list):
h, w, _ = frame.shape
seg_mask = (raw_seg_mask > 0.12).astype(np.uint8) * 255
hand_erase_mask = np.zeros((h, w), dtype=np.uint8)
if hand_landmarks_list:
for hand_landmarks in hand_landmarks_list:
pts = []
for lm in hand_landmarks.landmark:
cx, cy = int(lm.x * w), int(lm.y * h)
pts.append([cx, cy])
cv2.circle(hand_erase_mask, (cx, cy), 42, 255, -1)
if len(pts) > 0:
hull = cv2.convexHull(np.array(pts, dtype=np.int32))
cv2.fillConvexPoly(hand_erase_mask, hull, 255)
combined_mask = cv2.bitwise_or(seg_mask, hand_erase_mask)
close_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
closed_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_CLOSE, close_kernel)
dilate_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25, 25))
dilated_mask = cv2.dilate(closed_mask, dilate_kernel, iterations=2)
return dilated_mask
def main():
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("[ERROR] Could not open webcam.")
return
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
mp_selfie_segmentation = mp.solutions.selfie_segmentation
hands = mp_hands.Hands(
static_image_mode=False,
max_num_hands=2,
min_detection_confidence=0.6,
min_tracking_confidence=0.6
)
segmenter = mp_selfie_segmentation.SelfieSegmentation(model_selection=1)
landmark_style = mp_drawing.DrawingSpec(color=(0, 255, 128), thickness=2, circle_radius=4)
connection_style = mp_drawing.DrawingSpec(color=(255, 0, 200), thickness=3)
background_frame = None
invisible_mode = False
was_pinching = False
last_toggle_time = 0.0
debounce_delay = 0.65
prev_time = time.time()
fps = 0.0
print("[INFO] doniahub.cc Application running.")
try:
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame = cv2.flip(frame, 1)
h, w, _ = frame.shape
curr_time = time.time()
fps = 1.0 / (curr_time - prev_time) if (curr_time - prev_time) > 0 else 0
prev_time = curr_time
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
seg_results = segmenter.process(rgb_frame)
hand_results = hands.process(rgb_frame)
if background_frame is None and seg_results.segmentation_mask is not None:
background_frame = generate_empty_background(frame, seg_results.segmentation_mask)
gesture_active_this_frame = False
pinch_center_px = None
if hand_results.multi_hand_landmarks:
for hand_landmarks in hand_results.multi_hand_landmarks:
thumb_tip = hand_landmarks.landmark[mp_hands.HandLandmark.THUMB_TIP]
index_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
dist = calculate_distance(thumb_tip, index_tip)
if dist < 0.055:
gesture_active_this_frame = True
pinch_center_px = (
int((thumb_tip.x + index_tip.x) * 0.5 * w),
int((thumb_tip.y + index_tip.y) * 0.5 * h)
)
break
if gesture_active_this_frame and not was_pinching:
if (curr_time - last_toggle_time) > debounce_delay:
if background_frame is not None:
invisible_mode = not invisible_mode
last_toggle_time = curr_time
was_pinching = gesture_active_this_frame
if invisible_mode and background_frame is not None and seg_results.segmentation_mask is not None:
if background_frame.shape != frame.shape:
background_frame = cv2.resize(background_frame, (w, h))
cloak_mask = build_perfect_cloak_mask(
frame=frame,
raw_seg_mask=seg_results.segmentation_mask,
hand_landmarks_list=hand_results.multi_hand_landmarks
)
output_frame = frame.copy()
mask_bool = (cloak_mask == 255)
output_frame[mask_bool] = background_frame[mask_bool]
else:
output_frame = frame.copy()
if hand_results.multi_hand_landmarks:
for hand_landmarks in hand_results.multi_hand_landmarks:
mp_drawing.draw_landmarks(
output_frame,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
landmark_drawing_spec=landmark_style,
connection_drawing_spec=connection_style
)
if pinch_center_px is not None:
cv2.circle(output_frame, pinch_center_px, 18, (0, 255, 255), 2)
cv2.circle(output_frame, pinch_center_px, 6, (0, 0, 255), -1)
draw_hud(
output_frame,
invisible_mode=invisible_mode,
background_frame=background_frame,
gesture_detected=gesture_active_this_frame,
fps=fps
)
cv2.imshow("doniahub.cc - Invisibility Cloak", output_frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q') or key == 27:
break
elif key == ord('t'):
invisible_mode = not invisible_mode
elif key == ord('b') or key == ord('r'):
if seg_results.segmentation_mask is not None:
background_frame = generate_empty_background(frame, seg_results.segmentation_mask)
elif key == ord('c'):
background_frame = frame.copy()
finally:
cap.release()
cv2.destroyAllWindows()
hands.close()
segmenter.close()
if __name__ == "__main__":
main()