4일차 파이썬 뉴비 결국 울었습니다...
하마터면 컴퓨터 터지는 줄 알았습니다.

일단 위에 있는 윈도우창은 '메인 윈도우'라 정했고, 밑에 프레임처럼 보이는건 '서브 윈도우'라 정했음.
코드가 너무 길어서 메인 윈도우와 서브 윈도우 파이썬은 분리했음.
메인 윈도우에서 import해서 서브윈도우를 메인 윈도우가 실행될 때 함께 켜지는 것까지는 해보았는데,
목적은 저 서브 윈도우 안에 보이는 화면을 통해서 실시간 도형 검출이 하고 싶었슴다...
막 딥러닝해서 이미지 파일 학습시키고 그걸 토대로 동그라미를 인식해서 갯수 세어주는 건 꿈도 못 꾸고 ㅠㅠ(지금도 이지경인데..)
그냥 동그라미라도 일단은 실시간 추적이 가능하게 하고 싶었습니다...
근데 인터넷에 쳐보면 웹캠을 이용해서 하는 방법이 거의 나오는 것 같더라구요...
오픈된 소스들을 이용하려고 해도, 웹캠을 불러오는 것들이 많다보니 뭘 어떻게 건드려야할 지 감이 잘 잡히지 않아서,
GPT한테 주문을 넣고 코드 부분부분 이어서 어떻게든 완성해 보려 했는데..!
결국 프로그램 실행하다가 갑자기 화면에 동그라미들이 남발하더니 갑자기 멈춰서 컴퓨터 사망하는 줄 알았습니다 흐흑흐흑
이 시도만 6시간째 붙잡고 있네요...
서브 윈도우에 실현하기 어려우면, 별도의 창을 생성해서 그 안에 도형추적이 가능하게 하려고도 해보았지만,
장렬하게 실패했고... 서브 윈도우에 보이는 캡처 기능을 빼고 캡처용으로 설정한 영역을 프레임이라 인식시켜서 저 안에 있는 도형들만 검출할 수 있게 하면 되지 않을까 생각했지만 뜻대로 되지 않습니다...
사진으로 올리기엔 조금 그런 것 같아서...
정말 죄송하지만 작성한 코드를 전문 올려보려합니다 ㅠㅠ
이런 방식의 질문이 잘못 되었다면 꼭 알려주세요 ㅠㅠㅠㅠ...
------
import os
from datetime
import datetime
from PyQt5
import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets
import QFileDialog, QCheckBox
import cv2
import numpy as np
class SubWindow(QtWidgets.QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Sub Window")
self.setFixedSize(1080, 720)
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(16, 16))
close_button.setGeometry(self.width() - 30, 5, 20, 20)
close_button.clicked.connect(self.close)
close_button.setStyleSheet("background-color: white;")
# 그리드 체크박스 생성
self.grid_checkbox = QtWidgets.QCheckBox("Grid", self)
self.grid_checkbox.setGeometry(5, 5, 80, 20)
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(self, event):
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(0, 255, 0, 100), 1, QtCore.Qt.SolidLine)
p.setPen(grid_pen)
center_x = self.width() // 2
center_y = self.height() // 2
p.drawLine(0, center_y, self.width(), center_y)
p.drawLine(center_x, 0, center_x, self.height())
# 프레임 그리기
frame_width = 5 # 프레임 두께 조절
frame_pen = QtGui.QPen(QtGui.QColor(240, 240, 240, 255), frame_width, QtCore.Qt.SolidLine)
p.setPen(frame_pen)
p.drawRect(frame_width // 2, frame_width // 2, self.width() - frame_width, self.height() - frame_width)
# 툴바 배경색 지정
toolbar_height = 27
p.setBrush(QtGui.QBrush(QtGui.QColor(240, 240, 240, 255)))
p.drawRect(0, 0, self.width(), toolbar_height)
# 툴바 하단에 선 그리기
line_y = toolbar_height + 1
p.setPen(QtGui.QPen(QtGui.QColor(192, 192, 192, 255), 1, QtCore.Qt.SolidLine))
p.drawLine(0, line_y, self.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)
width, height = img.width(), img.height()
# QImage에서 바이트 데이터 추출 후 NumPy 배열로 변환
img_bytes = img.bits().asstring(img.byteCount())
mat = np.frombuffer(img_bytes, dtype=np.uint8).reshape(img.height(), img.width(), 4)
# OpenCV HoughCircles 함수를 사용하여 원 검출
gray = cv2.cvtColor(mat, cv2.COLOR_BGR2GRAY)
gray_blur = cv2.GaussianBlur(gray, (3, 3), 0)
circles = cv2.HoughCircles(gray_blur, cv2.HOUGH_GRADIENT, 1, 50, param1=50, param2=30, minRadius=0, maxRadius=0)
# 원을 그리고, 도형 추적
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
for (x, y, r) in circles:
p.drawEllipse(QtCore.QRect(x - r, y - r, r * 2, r * 2))
# 원 중심점 표시
p.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0, 255), 2, QtCore.Qt.SolidLine))
p.drawPoint(x, y)
def keyPressEvent(self, event):
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(self, state):
if state == QtCore.Qt.Checked:
self.show_grid = True
else:
self.show_grid = False
self.update()
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
event.accept()
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton and self.dragPosition is not None:
# 윈도우 창 이동
self.move(event.globalPos() - self.dragPosition)
event.accept()
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.dragPosition = None
event.accept()
def closeEvent(self, event):
# 메인 윈도우가 닫히면 함께 닫히도록 함
self.parent().closeEvent(event)
▲ 코드 안에는 이미지 저장 기능은 빼버렸습니다... 이미지 저장 기능 있는 것도 좋긴한데, 지금 그것 때문에 실시간 도형 추적이 안 되는 건가 싶어서 빼버렸거든요 ㅠㅠ
아,, 아무튼,,,,, 메인 윈도우 보다는 이 서브 윈도우에 문제가 너무너무 많은 것 같아서...
우선 이 코드만 긁어와 보았습니다...
영상 검출이 프로그램 시작하자마자 진행되면 과부화 걸릴 것 같아서,
메인 윈도우라 지칭한 부분에 'Run'을 누르면 시작할 수 있게 할 예정이에요...
(Run 누르면 버튼 네임이 Stop으로 바뀝니당... Stop 누르면 도형 검출 중단하게 할 예정...)
슬슬 한계에 부딪칩니다 흑흑
요는 위에 올린 코드가 한참 잘못되었을 수도 있지만,
이런 느낌으로 접근해라~ 라던가,, 저런 윈도우창 느낌이면 구현이 어렵다! 같은 답을 듣고 싶습니다...
만일 안 되는 구조인데, 계속 시도해보려 한 거였다면 넘넘 슬플 지도 . . ... . .. ..
살려주십시오............