티스토리 뷰

반응형

langchain의 ollama를 이용한다.

llama 서버는 연결되어 있어야 한다.

import threading
import speech_recognition as sr
from ultralytics import YOLO
import cv2
import os
from langchain_community.llms import Ollama


# 음성 인식 설정
r = sr.Recognizer()
mic = sr.Microphone()

# 웹캠 캡처 설정
cap = cv2.VideoCapture(0)

# YOLOv8 모델 로드
model = YOLO("yolov8n.pt")

llm = Ollama(model="llama2")

# 물체 인식 스레드 실행 여부 플래그
detect_thread = None
detect_thread_running = False

def listen_and_detect():
    global detect_thread, detect_thread_running
    while True:
        try:
            with mic as source:
                print("말씀해 주세요...")
                audio = r.listen(source)
                text = r.recognize_google(audio, language='ko-KR')
                print(f"인식된 텍스트: {text}")
                if '사진' in text:
                    if not detect_thread_running:
                        detect_thread_running = True
                        detect_thread = threading.Thread(target=detect_objects)
                        detect_thread.start()
                elif '멈춰' in text:
                    detect_thread_running = False
                    if detect_thread is not None:
                        detect_thread.join()
                        detect_thread = None
                elif '끝내기' in text:
                    detect_thread_running = False
                    if detect_thread is not None:
                        detect_thread.join()
                    cap.release()
                    cv2.destroyAllWindows()
                    return
        except sr.UnknownValueError:
            print("음성을 인식하지 못했습니다.")
        except sr.RequestError as e:
            print(f"에러가 발생했습니다; {e}")

def detect_objects():
    global detect_thread_running
    while detect_thread_running:
        # 웹캘이 프레임 읽기
        ret, frame = cap.read()
        # YOLOv8 모델로 물체 인식
        results = model(frame)
        # 인식된 물체 라벨 가져오기
        labels = [model.names[int(label)] for label in results[0].boxes.cls]
        # LLaMa 2 API에 질문하고 대답 받기
        response = ask_llm(labels)
        print(f"LLaMa 2 응답: {response}")
        # 인식된 물체 위치 표시
        annotated_frame = results[0].plot()
        cv2.imshow('Object Detection', annotated_frame)
        # 'q' 키를 누르면 종료
        if cv2.waitKey(1) & 0xFF == ord('q'):
            detect_thread_running = False
            break
    cv2.destroyAllWindows()

def ask_llm(labels):
    prompt = {'role': 'user', 'content': f"다음 물체가 인식되었습니다: {', '.join(labels)}. 이 물체들에 대해 설명해주세요."}
    response = llm.invoke([prompt])
    return response.strip()

if __name__ == "__main__":
    listen_thread = threading.Thread(target=listen_and_detect)
    listen_thread.daemon = True
    listen_thread.start()
    listen_thread.join()

 

사진에서 캡처한 라벨을 설명해달라고 하는 식.

 

사진에서 뭘 보고 있는지를 묻고, 그에 대한 걸 모두 설명해달라고 하려면 어떻게 해야 할지 고민중이다.

 

일단 코드를 좀 더 고쳐서 말하는 것 자체를 prompt에 넣어야 하고, 사진에 대한 input에서 대답을 해줄 수 있는 멀티모달 모델의 설계가 필요할 듯 보인다.

 

그리고 그 자체로 양자화도 필요.

 

갈 길이 멀어보인다.

반응형