본문 바로가기
프로젝트 기록/딥러닝 모델 개발_공학설계캡스톤디자인(스마트카ICT)

[Python] 딥러닝 감지된 걸 string으로 변환(+코드)/ PC와 시리얼 통신 중엔 시리얼 모니터사용 안됨(해결못함)

by 소요이 2023. 5. 30.
728x90

1. 보내는 string확인

 
 
머리, 손, etc 가 각각 감지되면 1, 감지되지 않으면 0.
 
 
 

import cv2
import numpy as np
import torch
import threading
import time
from gtts import gTTS
import os
import pygame
import serial
from time import sleep

# Initialize pygame mixer for playing audio
pygame.mixer.init()

# YOLOv5 모델 로드
model_path = 'C:/Users/songs/PycharmProjects/mediapipe/yolov5/data/dataset_230515/230518_/best_SY_230518.pt'
model = torch.hub.load('ultralytics/yolov5', 'custom', path=model_path)

# 클래스 이름 불러오기
names = model.module.names if hasattr(model, 'module') else model.names

# 경고문구 설정
warnings = {
    'head': '머리가 감지되었습니다.',
    'hand': "창 밖으로 손을 내밀지 마세요",
    'etc': '모르는 물체가 감지되었습니다.'
}

# Setup serial communication
ser = serial.Serial('COM6', 9600)  # Update COM port and baud rate accordingly

detected_objects = {'head': 0, 'hand': 0, 'etc': 0}

def send_data():
    while True:
        message = f"{detected_objects['head']} {detected_objects['hand']} {detected_objects['etc']}"
        print("Sending:", message)  # 메시지 출력
        ser.write(message.encode())
        sleep(0.5)


def start_send_data_thread():
    thread = threading.Thread(target=send_data, daemon=True)
    thread.start()

# 경고음 재생 함수
def play_audio(file):
    pygame.mixer.music.load(file)
    pygame.mixer.music.play()


audio_thread = None
audio_end_time = 0

# 비디오 캡처
video = cv2.VideoCapture('final_test.mp4')

# Check if the video file or camera is opened properly
if not video.isOpened():
    print('Could not open video')
    exit()

start_send_data_thread()


while video.isOpened():
    ret, frame = video.read()
    if not ret:
        break

    points = np.array([[361, 28], [565, 79], [719, 115], [870, 164], [996, 238],
                       [1069, 350], [1110, 443], [1023, 521], [904, 556], [768, 608],
                       [552, 698], [515, 539], [462, 353], [404, 173]], dtype=np.int32)

    # 관심 영역 설정 (창문 안쪽을 까맣게 처리)
    mask = np.ones_like(frame, dtype=np.uint8) * 255
    cv2.fillPoly(mask, [points], (0, 0, 0))
    roi = cv2.bitwise_and(frame, mask)

    # 객체 탐지 실행
    results = model(roi[:, :, ::-1])  # YOLOv5는 RGB 이미지를 기대하므로 BGR을 RGB로 변환
    labels = results.xyxyn[0][:, -1].cpu().numpy()
    boxes = results.xyxyn[0][:, :-1].cpu().numpy()

    # 바운딩 박스 그리기
    for (x, y, w, h, _), label in zip(boxes, labels):
        x1 = int((x - w / 2) * frame.shape[1])  # frame width
        y1 = int((y - h / 2) * frame.shape[0])  # frame height
        x2 = int((x + w / 2) * frame.shape[1])  # frame width
        y2 = int((y + h / 2) * frame.shape[0])  # frame height
        cv2.rectangle(roi, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(roi, names[int(label)], (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36,255,12), 2)

    # 객체 감지 정보 업데이트
    detected_classes = [names[int(label)] for label in labels]
    for object_name in detected_objects.keys():
        detected_objects[object_name] = 1 if object_name in detected_classes else 0

    # 새로운 객체 탐지 시 음성 재생
    if len(labels) > 0 and time.time() > audio_end_time:
        for detected_class in detected_classes:
            warning = warnings.get(detected_class, warnings['etc'])
            audio_file = f'voice_{detected_class}.mp3'
            if not os.path.isfile(audio_file):  # 파일이 존재하지 않는 경우만 TTS를 이용하여 생성
                # TTS를 이용하여 경고문장을 음성으로 변환
                tts = gTTS(warning, lang='ko')
                tts.save(audio_file)

            # 음성 재생 시작 (새로운 스레드에서)
            if audio_thread is not None:
                audio_thread.join()
            audio_thread = threading.Thread(target=play_audio, args=(audio_file,))
            audio_thread.start()

            # 경고음이 끝날 때까지 기다리는 시간 설정
            audio_end_time = time.time() + 3.5  # 가정: 각 경고음은 대략 3.5초 걸림

    cv2.imshow('ROI', roi)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video.release()
cv2.destroyAllWindows()

# 마지막으로 재생된 오디오가 끝날 때까지 기다림
if audio_thread is not None:
    audio_thread.join()

 
 
 
 
 
 
2단계. UART로 송신한 값을 아두이노가 다시 보내게 만드는 ECHO 확인
 
문제발생..
값을 확인하려면 시리얼 모니터를 사용해야 하는데, 시리얼 모니터를 오픈하면 파이참 코드 실행이 안됨.
즉, 아두이노 시리얼 통신이 거부됨

 
 
 
다른 시리얼 모니터링 프로그램도 써봤지만, 안됨
 
-> 그냥 시리얼 모니터링 안하는걸로 변경