Day13 虛擬試身室
🟡 先看看程式的效果
今天的程式是一個互動式的虛擬試衣間系統,使用了電腦視覺和姿態估計技術來實現實時的虛擬試衣效果。它的主要功能是將預先準備好的服裝圖片(上衣和褲子)疊加到攝像頭捕捉的人體影像上,讓使用者可以在螢幕上看到自己穿著不同服裝的樣子。
Today’s program is an interactive virtual fitting room system that utilizes computer vision and pose estimation technology to achieve real-time virtual try-on effects. Its main function is to overlay pre-prepared clothing images (tops and pants) onto the human image captured by the camera, allowing users to see themselves wearing different outfits on the screen.
🟡 學習目標
電腦視覺應用:使用 OpenCV 來處理圖像和視頻流。
人體姿態估計:利用 MediaPipe 庫進行人體姿態估計,這可以讓我們準確地定位人體的關鍵點。
圖像疊加:使用 cvzone 庫來實現圖像疊加效果,將服裝圖片疊加到攝像頭捕捉的影像上。
實時處理:程式能夠實時處理視頻流,並根據檢測到的人體姿態動態調整服裝的位置和大小。
動態縮放:根據檢測到的肩膀寬度來動態調整服裝大小,使其更符合使用者的體型。
全屏顯示:使用 OpenCV 的視窗功能來創建全屏顯示,提供更好的使用體驗。
參數調整:程式中包含了一些可調整的參數,如服裝位置的微調(topXAdjust, topYAdjust 等),這允許更精細的控制。
事件處理:程式會持續運行直到使用者按下 Esc 鍵,這展示了如何處理鍵盤輸入。
🟡 程式碼
請先下載 “Day13 虛擬校服試身室” 資料夾內的程式以及圖檔。
請按此下載
'''
Python + AI in 21 days
https://jasonworkshop.com/python
Designed by Jason Workshop
[請勿修改以上內容]
---
預備工作:
首先,請確保已安裝 opencv-python, mediapipe 模組
如不確定可直接在 Windows 的 cmd prompt 執行以下指定
pip install opencv-python mediapipe
'''
import cv2
import cvzone
import mediapipe as mp
# 讀取服裝圖檔及修正參數
top = cv2.imread("uniform01.png", cv2.IMREAD_UNCHANGED)
topXAdjust = 0
topYAdjust = 0
bottom = cv2.imread("bottom01.png", cv2.IMREAD_UNCHANGED)
bottomXAdjust = -10
bottomYAdjust = 20
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
x = [0 for i in range(32)]
y = [0 for i in range(32)]
# 取得螢幕解析度
screen_width, screen_height = 1920, 1080
# --------------------------------------------------------------------------------
def detect_position():
# 計算服裝大小比例
tscale=round((results.pose_landmarks.landmark[11].x - results.pose_landmarks.landmark[12].x), 2) # 用左肩 X - 右肩 X 求出大小比例值
# print (tscale)
if tscale > 0:
# txc, tyc = 服裝中心 X, Y 坐標
txc=round((results.pose_landmarks.landmark[11].x - results.pose_landmarks.landmark[12].x) / 2 + results.pose_landmarks.landmark[12].x, 2)
tyc=round((results.pose_landmarks.landmark[11].y - results.pose_landmarks.landmark[12].y) / 2 + results.pose_landmarks.landmark[12].y, 2)
# print(txc, " , ", tyc)
# 改變服裝大小
top2 = cv2.resize(top, (0,0), None, tscale*4.2, tscale*4.2)
# print(top2.shape[0]) # Height
# print(top2.shape[1]) # Width
# 改變服裝位置
imgResult = cvzone.overlayPNG(image, top2, [int(txc * 1280 - top2.shape[1] / 2) + topXAdjust, int(tyc * 720 - top2.shape[0] * 0.20) + topYAdjust])
# --------------------------------------------------------------------------------
# bxc, byc = 服裝中心 X, Y 坐標
bxc=round((results.pose_landmarks.landmark[23].x - results.pose_landmarks.landmark[24].x) / 2 + results.pose_landmarks.landmark[24].x, 2)
byc=round((results.pose_landmarks.landmark[23].y - results.pose_landmarks.landmark[24].y) / 2 + results.pose_landmarks.landmark[24].y, 2)
# 改變服裝大小
bottom2 = cv2.resize(bottom, (0,0), None, tscale*7, tscale*7)
# 改變服裝位置
imgResult = cvzone.overlayPNG(image, bottom2, [int(bxc * 1280 - bottom2.shape[1] / 2) + bottomXAdjust, int(byc * 720 - bottom2.shape[0] * 0.20) + bottomYAdjust])
# --------------------------------------------------------------------------------
# 創建一個視窗
cv2.namedWindow('JCCSSYL Dressing Room', cv2.WINDOW_NORMAL)
# 設定視窗屬性為全屏
cv2.setWindowProperty('JCCSSYL Dressing Room', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
# 調整視窗大小以符合解析度
cv2.resizeWindow('JCCSSYL Dressing Room', screen_width, screen_height)
# Webcam input
pose = mp_pose.Pose(min_detection_confidence = 0.7, min_tracking_confidence =0.5)
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) # Capture width = 640
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) #Capture height = 480
while cap.isOpened():
success, image = cap.read()
if not success:
break
# Flip the image horizontally for a later selfie-view display
image = cv2.flip(image, 1)
# To improve performance, optionally mark the image as not writeable to pass by reference
image.flags.writeable = True
results = pose.process(image)
if results.pose_landmarks:
detect_position()
# 顯示骨架
# mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
cv2.imshow('JCCSSYL Dressing Room', image)
# 取得畫面大小
# print(image.shape)
# 按 Esc 關閉程式及視窗
if cv2.waitKey(5) & 0xFF == 27:
cv2.destroyAllWindows()
break
pose.close()
cap.release()
🟡 小小挑戰一下
大家可以嘗試進行一些修改或改良喔! 例如:
✌️嘗試修改成女裝的虛擬試身室吧。
😁 明天見!