반응형
저번 시간에 배운 MediaPipe를 활용한 프로젝트 수업입니다.
1) MediaPipe를 이용한 손가락 제스처에 따른 크기 조절
- 엄지 손가락(4번)과 두번째 손가락(8번)을 좁혔다가 벌렸다 하는 제스처에 따라 두 손가락 끝의 점의 길이를 측정하여 화면에 출력해주는 소스코드입니다.
- Vscode를 실행하고 'Open Folder'(폴더열기)를 선택하여 'ArduinoHandgesture'폴더를 새로 만들고 그 안에 'HandGestureVolume.py' 파일을 새로 생성합니다.
소스코드
import cv2
import mediapipe as mp
import pyautogui
x1 = y1 = x2 = y2 = 0
webcam=cv2.VideoCapture(0)
my_hands = mp.solutions.hands.Hands()
drawing_utils = mp.solutions.drawing_utils
while True:
_, image = webcam.read()
image = cv2.flip(image, 1)
frame_height, frame_width, _ = image.shape
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
output = my_hands.process(rgb_image)
hands = output.multi_hand_landmarks
if hands:
for hand in hands:
drawing_utils.draw_landmarks(image, hand)
landmarks = hand.landmark
for id, landmark in enumerate(landmarks):
x = int(landmark.x * frame_width)
y = int(landmark.y * frame_height)
if id == 8:
cv2.circle(img=image, center=(x,y), radius=8, color=(0,255,255), thickness=3)
x1 = x
y1 = y
if id == 4:
cv2.circle(img=image, center=(x, y), radius=8, color=(0,0,255), thickness=3)
x2 = x
y2 = y
dist = ((x2-x1)**2 + (y2-y1)**2)**(0.5)//4
cv2.line(image, (x1,y1), (x2, y2), (0, 255,0), 5)
print(dist)
if dist > 50 :
pyautogui.press("volumeup")
else:
pyautogui.press("volumedown")
cv2.imshow("Img", image)
key = cv2.waitKey(10)
if key == 27: #esc key
break
webcam.release()
cv2.destroyAllWindows()
- 'esc'키를 치면 실행이 종료됩니다.
- 결과
2) 손가락 제스처에 따라 LED밝기 조절하기
- 회로도
소스코드
- 아두이노 코드
const int ledPin=3;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
while(Serial.available()>0){
int val=Serial.parseInt();
if(Serial.read()=='\n'){
val=constrain(val,0,255);
analogWrite(ledPin, val);
Serial.print(val);
}
}
}
- 아두이노 '포트번호를 확인'하고 파이썬 코드에서 수정합니다.
- 파이썬 코드
import cv2
import mediapipe as mp
import pyautogui
import serial
x1 = y1 = x2 = y2 = 0
webcam=cv2.VideoCapture(0)
my_hands = mp.solutions.hands.Hands()
drawing_utils = mp.solutions.drawing_utils
arduino = serial.Serial('COM26', 9600)
arduino.timeout = 1
while True:
_, image = webcam.read()
image = cv2.flip(image, 1)
frame_height, frame_width, _ = image.shape
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
output = my_hands.process(rgb_image)
hands = output.multi_hand_landmarks
if hands:
for hand in hands:
drawing_utils.draw_landmarks(image, hand)
landmarks = hand.landmark
for id, landmark in enumerate(landmarks):
x = int(landmark.x * frame_width)
y = int(landmark.y * frame_height)
if id == 8:
cv2.circle(img=image, center=(x,y), radius=8, color=(0,255,255), thickness=3)
x1 = x
y1 = y
if id == 4:
cv2.circle(img=image, center=(x, y), radius=8, color=(0,0,255), thickness=3)
x2 = x
y2 = y
dist = ((x2-x1)**2 + (y2-y1)**2)**(0.5)//4
cv2.line(image, (x1,y1), (x2, y2), (0, 255,0), 5)
# if dist > 50 :
# pyautogui.press("volume up")
# else:
# pyautogui.press("volume down")
d = int((dist/70)*255)
print(dist, d)
e='\n'
if 0<d<256:
cv2.putText(image, str(d), (40, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 3)
arduino.write(str(d).encode())
arduino.write(e.encode())
cv2.imshow("Img", image)
key = cv2.waitKey(10)
if key == 27: #esc key
break
webcam.release()
cv2.destroyAllWindows()
- 결과
반응형
'피지컬컴퓨팅 > 아두이노' 카테고리의 다른 글
심장박동 센서 활용하기 (0) | 2024.06.25 |
---|---|
ESP32 와 ESP8266 차이점 비교 (0) | 2024.05.23 |
#인공지능 AI 활용 - Mediapipe로 HandTracking 하여 LED 제어하기 (0) | 2024.04.17 |
4x4 키패드 활용하기 (0) | 2024.04.11 |
DS1302 RTC(Real Time Clock) (0) | 2024.04.05 |