4일차 파이썬 뉴비 결국 울었습니다...


하마터면 컴퓨터 터지는 줄 알았습니다.



일단 위에 있는 윈도우창은 '메인 윈도우'라 정했고, 밑에 프레임처럼 보이는건 '서브 윈도우'라 정했음.

코드가 너무 길어서 메인 윈도우와 서브 윈도우 파이썬은 분리했음. 

메인 윈도우에서 import해서 서브윈도우를 메인 윈도우가 실행될 때 함께 켜지는 것까지는 해보았는데, 

목적은 저 서브 윈도우 안에 보이는 화면을 통해서 실시간 도형 검출이 하고 싶었슴다...

막 딥러닝해서 이미지 파일 학습시키고 그걸 토대로 동그라미를 인식해서 갯수 세어주는 건 꿈도 못 꾸고 ㅠㅠ(지금도 이지경인데..)


그냥 동그라미라도 일단은 실시간 추적이 가능하게 하고 싶었습니다...

근데 인터넷에 쳐보면 웹캠을 이용해서 하는 방법이 거의 나오는 것 같더라구요... 

오픈된 소스들을 이용하려고 해도, 웹캠을 불러오는 것들이 많다보니 뭘 어떻게 건드려야할 지 감이 잘 잡히지 않아서, 

GPT한테 주문을 넣고 코드 부분부분 이어서 어떻게든 완성해 보려 했는데..!


결국 프로그램 실행하다가 갑자기 화면에 동그라미들이 남발하더니 갑자기 멈춰서 컴퓨터 사망하는 줄 알았습니다 흐흑흐흑

이 시도만 6시간째 붙잡고 있네요...

서브 윈도우에 실현하기 어려우면, 별도의 창을 생성해서 그 안에 도형추적이 가능하게 하려고도 해보았지만,

장렬하게 실패했고... 서브 윈도우에 보이는 캡처 기능을 빼고 캡처용으로 설정한 영역을 프레임이라 인식시켜서 저 안에 있는 도형들만 검출할 수 있게 하면 되지 않을까 생각했지만 뜻대로 되지 않습니다...


사진으로 올리기엔 조금 그런 것 같아서...

정말 죄송하지만 작성한 코드를 전문 올려보려합니다 ㅠㅠ

이런 방식의 질문이 잘못 되었다면 꼭 알려주세요 ㅠㅠㅠㅠ...


------


import sys
import os
from datetime 
import datetime
from PyQt5 
import QtCoreQtGuiQtWidgets
from PyQt5.QtWidgets 
import QFileDialogQCheckBox
import cv2
import numpy as np

class SubWindow(QtWidgets.QDialog):
    def __init__(selfparent=None):
        super().__init__(parent)
        self.setWindowTitle("Sub Window")
        self.setFixedSize(1080720)
        self.setWindowFlags(
            QtCore.Qt.Window | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint
        )
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.is_detecting = False  # 영상검출 여부

        # 버튼 생성
        close_button = QtWidgets.QPushButton(""self)
        close_button.setIcon(QtGui.QIcon("C:/codingga/SEM_Scan/bin/close.png"))
        close_button.setIconSize(QtCore.QSize(1616))
        close_button.setGeometry(self.width() - 3052020)
        close_button.clicked.connect(self.close)
        close_button.setStyleSheet("background-color: white;")

        # 그리드 체크박스 생성
        self.grid_checkbox = QtWidgets.QCheckBox("Grid"self)
        self.grid_checkbox.setGeometry(558020)
        self.grid_checkbox.stateChanged.connect(self.toggle_grid)

        # 그리드 초기값 설정
        self.show_grid = False

        # OpenCV 초기화
        self.capture = cv2.VideoCapture(0)  # 0번 카메라를 사용하여 캡쳐
        self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640)  # 프레임 너비 설정
        self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)  # 프레임 높이 설정

    def paintEvent(selfevent):
        painter = QtGui.QPainter(self)
        painter.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver)
        painter.setPen(QtCore.Qt.NoPen)
        painter.fillRect(self.rect(), QtCore.Qt.transparent)

        # 배경색 설정
        p = QtGui.QPainter(self)
        p.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver)
        p.setPen(QtCore.Qt.NoPen)
        p.fillRect(self.rect(), QtCore.Qt.transparent)
        p.drawRect(self.rect())

        # 그리드 그리기
        if self.show_grid:
            grid_pen = QtGui.QPen(QtGui.QColor(02550100), 1QtCore.Qt.SolidLine)
            p.setPen(grid_pen)
            center_x = self.width() // 2
            center_y = self.height() // 2
            p.drawLine(0center_yself.width(), center_y)
            p.drawLine(center_x0center_xself.height())

        # 프레임 그리기
        frame_width = 5  # 프레임 두께 조절
        frame_pen = QtGui.QPen(QtGui.QColor(240240240255), frame_widthQtCore.Qt.SolidLine)
        p.setPen(frame_pen)
        p.drawRect(frame_width // 2frame_width // 2self.width() - frame_widthself.height() - frame_width)

        # 툴바 배경색 지정
        toolbar_height = 27
        p.setBrush(QtGui.QBrush(QtGui.QColor(240240240255)))
        p.drawRect(00self.width(), toolbar_height)

        # 툴바 하단에 선 그리기
        line_y = toolbar_height + 1
        p.setPen(QtGui.QPen(QtGui.QColor(192192192255), 1QtCore.Qt.SolidLine))
        p.drawLine(0line_yself.width(), line_y)

        # OpenCV를 사용하여 원 모양의 도형 추적
        img = QtWidgets.QApplication.primaryScreen().grabWindow(
            QtWidgets.QApplication.desktop().winId(), self.x(), self.y(), self.width(), self.height()
        ).toImage()

        # OpenCV 이미지로 변환
        img = img.convertToFormat(QtGui.QImage.Format_RGBA8888)
        widthheight = img.width(), img.height()

        # QImage에서 바이트 데이터 추출 후 NumPy 배열로 변환
        img_bytes = img.bits().asstring(img.byteCount())
        mat = np.frombuffer(img_bytesdtype=np.uint8).reshape(img.height(), img.width(), 4)

        # OpenCV HoughCircles 함수를 사용하여 원 검출
        gray = cv2.cvtColor(matcv2.COLOR_BGR2GRAY)
        gray_blur = cv2.GaussianBlur(gray, (33), 0)
        circles = cv2.HoughCircles(gray_blurcv2.HOUGH_GRADIENT, 150param1=50param2=30minRadius=0maxRadius=0)

        # 원을 그리고, 도형 추적
        if circles is not None:
            circles = np.round(circles[0, :]).astype("int")
            for (xyrin circles:
                p.drawEllipse(QtCore.QRect(x - ry - rr * 2r * 2))

                # 원 중심점 표시
                p.setPen(QtGui.QPen(QtGui.QColor(25500255), 2QtCore.Qt.SolidLine))
                p.drawPoint(xy)

    def keyPressEvent(selfevent):
        if event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_S:
            if not self.is_detecting:
                self.start_detection()
            else:
                self.stop_detection()

    def start_detection(self):
        # 영상검출 시작 코드 작성
        self.is_detecting = True

    def stop_detection(self):
        # 영상검출 중지 코드 작성
        self.is_detecting = False

    def toggle_grid(selfstate):
        if state == QtCore.Qt.Checked:
            self.show_grid = True
        else:
            self.show_grid = False
        self.update()

    def mousePressEvent(selfevent):
        if event.button() == QtCore.Qt.LeftButton:
            self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
            event.accept()

    def mouseMoveEvent(selfevent):
        if event.buttons() == QtCore.Qt.LeftButton and self.dragPosition is not None:
            # 윈도우 창 이동
            self.move(event.globalPos() - self.dragPosition)
            event.accept()

    def mouseReleaseEvent(selfevent):
        if event.button() == QtCore.Qt.LeftButton:
            self.dragPosition = None
            event.accept()

    def closeEvent(selfevent):
        # 메인 윈도우가 닫히면 함께 닫히도록 함
        self.parent().closeEvent(event)



▲ 코드 안에는 이미지 저장 기능은 빼버렸습니다... 이미지 저장 기능 있는 것도 좋긴한데, 지금 그것 때문에 실시간 도형 추적이 안 되는 건가 싶어서 빼버렸거든요 ㅠㅠ


아,, 아무튼,,,,, 메인 윈도우 보다는 이 서브 윈도우에 문제가 너무너무 많은 것 같아서...

우선 이 코드만 긁어와 보았습니다...

영상 검출이 프로그램 시작하자마자 진행되면 과부화 걸릴 것 같아서,

메인 윈도우라 지칭한 부분에 'Run'을 누르면 시작할 수 있게 할 예정이에요...

(Run 누르면 버튼 네임이 Stop으로 바뀝니당... Stop 누르면 도형 검출 중단하게 할 예정...)


슬슬 한계에 부딪칩니다 흑흑

요는 위에 올린 코드가 한참 잘못되었을 수도 있지만,

이런 느낌으로 접근해라~ 라던가,, 저런 윈도우창 느낌이면 구현이 어렵다! 같은 답을 듣고 싶습니다...

만일 안 되는 구조인데, 계속 시도해보려 한 거였다면 넘넘 슬플 지도 . . ... . .. ..




살려주십시오............