브라우저에서 실시간 감지를 시도했습니다.

이번에는 이런 것을 만들 것입니다.

과거 기사 와 같은 일을 하고 있습니다만, 이번은 검출 화면은 투과 처리해 그대로 데스크탑에 표시해 보았습니다.

리포지토리를 둡니다. 필요한 모듈을 설치 한 후 python main.py에서 즉시 실행할 수 있으므로 꼭 시도해보십시오.



아래에 구성도가 나와 있습니다.



크게 나누어 화상 인식 프로세스와 화면 표시 프로세스로 나누어져 있는 것을 알 수 있다고 생각합니다.

각각 해설합니다.



이미지 인식 프로세스



이 프로세스의 구조는 간단합니다. 스크린 샷을 찍고 검출기에 전달하면됩니다.



· 스크린 샷




sct.py

import mss
import mss.tools

def screenshot(monitor_number = 0,output="sct.png"):
    with mss.mss() as sct:
        output = sct.shot(mon=monitor_number, output=output)

    return output




스크린샷은 mss라는 모듈을 사용합니다. 처리가 빠르고 구현도 간단하므로 마음에 사용하고 있습니다.



· 검출기




recognition.py

import torch
from sct import screenshot
from multiprocessing import Queue

# Model
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

def yolo():
    while True:
        img = screenshot(monitor_number = 2,output="sct.png")
        results = model(img)
        return result_tolist(results)

def result_tolist(results):
    rpd = results.pandas().xyxy[0]
    rpd.iloc[:,:4] = rpd.iloc[:,:4].astype('int')
    return rpd.values.tolist()

def yolo_loop(q:Queue):
    while True:
        res = yolo()
        q.put(res)




검출기에 yolo를 사용했습니다. torchhub에서 떨어 뜨려 사용하기 때문에 코드는 상당히 깔끔합니다. yolo_loop 함수가 화면 표시 프로세스에 전달할 데이터를 queue로 입력합니다. 데이터는 목록 형식으로 [[x1,y1,x2,y2],confidence,class]입니다.



화면 표시 프로세스




transparent_window.py


import tkinter
import time
from multiprocessing import Queue


def tk_preload():
    root = tkinter.Tk()
    root.wm_attributes("-transparentcolor", "snow")
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry("%dx%d+0+0" % (w, h))
    root.attributes('-fullscreen', True)
    root.attributes('-topmost', True)
    canvas = tkinter.Canvas(root, width=w, height=h, bg="snow")
    canvas.place(x=0, y=0)
    return root, canvas

def transparent_window(q:Queue):
    root, canvas = tk_preload()

    while True:
        result = q.get()

        for i ,res in enumerate(result):
            x1,y1,x2,y2 = res[0],res[1],res[2],res[3]
            conf = res[4]
            cls = res[6]

            n = canvas.create_rectangle(
            x1,y1,x2,y2, tags='o', outline="red", width=3)
            canvas.create_text(
            x1-20, y1-20, text=f"{cls}:{str(conf)[:4]}", font=('MS Gothic', 20, "bold"),fill="red", tags='o'
        )

        canvas.pack()
        canvas.update()
        if q.empty():
            time.sleep(0.1)
        canvas.delete('o')



GUI 모듈은 pysimplegui, tkinter, Kivy, PyQt, wxPython 등을 들으면 딱딱하지 않기 때문에 어느 것을 사용하는지 선정에 매우 시간이 걸렸습니다만, tkinter가 화면의 투과 처리를 가장 간단하게 구현할 수 있다 네.
root.wm_attributes("-transparentcolor", "snow") 행에서 지정된 색상을 투명하게 합니다. 그리고는 윈도우의 배경색을 같은 색으로 지정해 주면 투명 화면을 표시할 수 있는 구조입니다.

투명화면을 표시할 수 있으면 나머지는 검출기의 아웃풋을 queue.get() 로 받아 사각형과 텍스트를 표시해 루프 처리로 돌려 주면 완성입니다.



main



마지막으로 이미지 인식 프로세스와 화면 표시 프로세스를 multiprocess로 연계하여 병렬 처리하면 큰 지연 없이 구현할 수 있습니다.




main.py


import time
from multiprocessing import Process, Queue

from transparent_window import transparent_window
from AI.recognition import yolo_loop

def main():
    q = Queue()
    p1 = Process(target=yolo_loop, args=(q,))
    p2 = Process(target=transparent_window, args=(q,))
    p1.start()
    while q.empty():
        time.sleep(0.1)
    p2.start()
    p1.join()
    p2.join()



마지막으로



눈으로 바로 확인할 수 있는 구현은 매우 재미있네요.

최종 코드도 꽤 슬림하게 완성되었기 때문에 매우 만족하고 있습니다.

이미지 인식 부분은 yolo에 한정되지 않고 다른 라이브러리에서도 구현 가능하므로 시도해보십시오.


좋은 웹페이지 즐겨찾기