OpenCV

[OpenCV_01_EX_키 입력이랑 마우스 이벤트로 점도 찍고 글씨도 쓰고 창도 움직이고 입력한 것 지우기도 하고 현재 창 저장도 하고 하기]

선호하는 2022. 12. 17. 21:00

main.py

from EX_01 import *


window = EX01("./white.jpg")

img = window.read()

while img is not None:
    open(img, window.win_name)

    key = cv2.waitKey()
    if key == ord('m'):
        window.x, window.y = move_window(window.win_name, window.x, window.y)

    if key == ord('c'):
        circle(img, window.win_name)

    if key == ord('w'):
        write(img, window.win_name)

    if key == ord('r'):
        remove(img, window.win_name)

    if key == ord('s'):
        save(img, window.win_name)

    if key == ord('q') or key == 27:
        destroy()
        break

EX_01.py

import cv2


def open(img, win_name):
    cv2.rectangle(img, (0, 0), (300, 50), (0, 0, 255), -1)
    cv2.putText(img, "Main Page", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    cv2.imshow(win_name, img)


def move_window(now_win, x, y):
    while True:
        cv2.moveWindow(now_win, x, y)
        key = cv2.waitKey()
        if key == ord('w'):
            y -= 10
        elif key == ord('s'):
            y += 10
        elif key == ord('a'):
            x -= 10
        elif key == ord('d'):
            x += 10
        elif key == ord('q'):
            break
    return [x, y]


def circle(img, win_name):
    cv2.rectangle(img, (0, 0), (300, 50), (0, 0, 255), -1)
    cv2.putText(img, "Drow Circle", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    cv2.imshow(win_name, img)

    def onMouse(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            cv2.circle(img, (x, y), 30, (0, 0, 0), -1)
            cv2.imshow(win_name, img)

    cv2.setMouseCallback(win_name, onMouse)
    while True:
        key = cv2.waitKey()
        if key == ord('q'):
            def onMouse(event, x, y, flags, param):
                None

            cv2.setMouseCallback(win_name, onMouse)
            break


def write(img, win_name):
    cv2.rectangle(img, (0, 0), (300, 50), (0, 0, 255), -1)
    cv2.putText(img, "writing...", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    cv2.imshow(win_name, img)

    s = ''
    while True:
        key = cv2.waitKey()
        if key == 13:
            break
        s += chr(key)

    cv2.rectangle(img, (0, 0), (300, 50), (0, 0, 255), -1)
    cv2.putText(img, "Write Mode", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    cv2.imshow(win_name, img)

    def onMouse(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            cv2.putText(img, s, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
            cv2.imshow(win_name, img)

    cv2.setMouseCallback(win_name, onMouse)

    while True:
        key = cv2.waitKey()
        if key == ord('q'):
            def onMouse(event, x, y, flags, param):
                None

            cv2.setMouseCallback(win_name, onMouse)
            break


def remove(img, win_name):
    cv2.rectangle(img, (0, 0), (300, 50), (0, 0, 255), -1)
    cv2.putText(img, "Remove Mode", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    cv2.imshow(win_name, img)

    def onMouse(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            cv2.rectangle(img, (x - 25, y - 25), (x + 25, y + 25), (255, 255, 255), -1)
            cv2.imshow(win_name, img)

    cv2.setMouseCallback(win_name, onMouse)
    while True:
        key = cv2.waitKey()
        if key == ord('q'):
            def onMouse(event, x, y, flags, param):
                None

            cv2.setMouseCallback(win_name, onMouse)
            break


def save(img, win_name):
    cv2.rectangle(img, (0, 0), (300, 50), (0, 0, 255), -1)
    cv2.putText(img, "Save File", (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    cv2.imshow(win_name, img)

    path = './save.jpg'
    cv2.imwrite(path, img)
    cv2.imshow('save', cv2.imread(path))
    key = cv2.waitKey()
    if key is not None:
        cv2.destroyWindow('save')


def destroy():
    cv2.destroyAllWindows()


class EX01:
    img_path = ""
    x = 100
    y = 100
    win_name = 'start'

    def __init__(self):
        pass

    def __init__(self, path):
        self.img_path = path

    def read(self):
        img = cv2.imread(self.img_path)
        return img

m을 누르면 창 이동 모드. wasd 키로 상하좌우 창 이동.

c을 누르면 원 그리기 모드. 마우스 좌클릭으로 원 찍기.

w을 누르면 글씨 입력 모드. 키보드로 글씨 입력하고 엔터 키 누르면 입력할 글씨 저장. 마우스 클릭으로 글씨 찍음.

r을 누르면 지우기 모드. 클릭한 좌표의 상하좌우 25px만큼 사각형으로 덮음.

s를 누르면 현재 띄워져 있는 창 저장.

각 모드에서 q 누르면 시작으로 이동. 시작에서 q 누르면 창 종료. 

 

<사족>

oop개념을 공부했기에 적당히 적용해보았다.

저렇게 하는 게 맞는지는 모르겠지만 main 코드가 좀 더 읽기 편해진 느낌이 들었다.

클린코드에 대해서도 공부해 보고, 모듈화를 어떻게 해야 하는지도 공부를 해야 할 것 같다.

그저 행동 단위대로 잘라서 함수화하는게 정답이 아닐 것 같다는 생각도 들었다.