일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 자바스크립트심화
- JSP
- JSP/Servlet
- SQL
- 정보처리기사필기
- 오블완
- 자바
- 중학1-1
- 자바스크립트
- 데이터베이스
- 머신러닝
- 딥러닝
- 중학수학
- c언어
- JDBC
- rnn
- 컴퓨터비전
- 자바 실습
- 데이터분석
- 순환신경망
- 상속
- 티스토리챌린지
- CSS
- 디버깅
- 정보처리기사실기
- 파이썬
- 컴퓨터구조
- html/css
- 연습문제
- 혼공머신
- Today
- Total
클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지
비전 에이전트 2 - [비전 에이전트 1] 오림 본문
대화식으로 물체를 분할하는 기법인 GrabCut은 지난 단원에서 다루었다. 이 함수를 이용하여 물체를 오려냈었다. 사용자가 마우스 왼쪽 버튼으로 물체의 일부를 파란색으로 칠하고 오른쪽 버튼으로 배경 일부를 빨간색으로 칠하면 grabCut 함수가 물체 영역을 오린다.
관심 물체 분할
이 프로그램은 사용자와 상호작용하면서 GrabCut을 반복 적용하여 사용자가 만족할 때까지 물체 영역을 오려내는 일을 지원하는 비전 에이전트다.
먼저 프로그램 실행 결과를 살펴보자. GUI 윈도우에 버튼이 7개 있는데, 왼쪽부터 영상 읽기, 페인팅 시작하기, 오리기, 붓 크기 조정하기, 저장하기, 나가기를 담당한다. <파일> 버튼을 이용해 원하는 영상을 선택한다. <페인팅> 버튼을 클릭하면 붓칠이 가능한 상태가 된다.
실행 결과에서 사용자가 물체와 배경에 붓칠을 한 영상을 확인할 수 있다. <오림> 버튼을 클릭하면 오리는 작업이 실행되고 결과를 확인할 수 있다. 붓칠이 된 영상에 추가로 붓칠을 반복하면 정교하게 물체를 오려낼 수 있고 붓의 크기도 자유자재로 바꿀 수 있다.
GrabCut을 이용해 관심 물체 오리기
프로그램 구조를 살펴보자. 코드가 좀 길므로 차근차근 나누어서 설명해보겠다.
이 코드는 이미지에서 사용자가 원하는 부분을 페인팅하여 오려내는(오림) 기능을 제공하는 GUI 애플리케이션이다. 사용자가 특정 영역을 "물체" 또는 "배경"으로 표시한 후, GrabCut 알고리즘을 적용하여 선택된 영역을 오려내도록 한다. 이 코드는 PyQt5와 OpenCV 라이브러리를 사용하여 GUI를 구성하고 이미지 처리를 수행한다.
다음은 코드의 주요 부분과 함수에 대한 설명이다.
1. Orim 클래스 생성
Orim 클래스는 GUI 창을 생성하고, 버튼과 이벤트 핸들러를 통해 기능을 제어한다. QMainWindow를 상속하여 윈도우 UI를 구성하고 필요한 기능을 정의한다.
class Orim(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('오림')
self.setGeometry(200, 200, 700, 200)
- __init__ 함수에서는 윈도우의 제목과 크기를 설정한다.
2. 버튼 생성 및 배치
GUI 상단에 배치할 7개의 버튼을 생성한다.
fileButton = QPushButton('파일', self)
paintButton = QPushButton('페인팅', self)
cutButton = QPushButton('오림', self)
incButton = QPushButton('+', self)
decButton = QPushButton('-', self)
saveButton = QPushButton('저장', self)
quitButton = QPushButton('나가기', self)
3. 버튼 이벤트 핸들러 연결
각 버튼을 클릭했을 때 호출될 함수를 연결한다.
fileButton.clicked.connect(self.fileOpenFunction)
paintButton.clicked.connect(self.paintFunction)
...
4. 페인팅 설정 및 초기값 설정
페인팅 기능에서 사용될 붓 크기와 색상을 설정한다.
self.BrushSiz = 5
self.LColor, self.RColor = (255, 0, 0), (0, 0, 255) # 왼쪽 클릭: 파란색, 오른쪽 클릭: 빨간색
5. fileOpenFunction: 이미지 파일 열기
def fileOpenFunction(self):
fname = QFileDialog.getOpenFileName(self, 'Open file', './')
self.img = cv.imread(fname[0])
if self.img is None:
sys.exit('파일을 찾을 수 없습니다.')
self.img_show = np.copy(self.img)
cv.imshow('Painting', self.img_show)
self.mask = np.zeros((self.img.shape[0], self.img.shape[1]), np.uint8)
self.mask[:, :] = cv.GC_PR_BGD
- 파일 대화상자를 통해 이미지를 열고, img에 로드한 후 img_show에 복사한다.
- self.mask는 GrabCut 알고리즘에서 사용할 마스크로, 모든 픽셀을 배경으로 초기화한다.
6. paintFunction: 페인팅 모드 전환
페인팅 모드로 전환하여 painting 함수를 마우스 이벤트 콜백 함수로 설정한다.
def paintFunction(self):
cv.setMouseCallback('Painting', self.painting)
7. painting: 페인팅 작업 수행
마우스 이벤트에 따라 선택한 영역을 파란색(물체) 또는 빨간색(배경)으로 표시하고, 이를 마스크에 반영한다.
def painting(self, event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDOWN:
cv.circle(self.img_show, (x, y), self.BrushSiz, self.LColor, -1)
cv.circle(self.mask, (x, y), self.BrushSiz, cv.GC_FGD, -1)
elif event == cv.EVENT_RBUTTONDOWN:
cv.circle(self.img_show, (x, y), self.BrushSiz, self.RColor, -1)
cv.circle(self.mask, (x, y), self.BrushSiz, cv.GC_BGD, -1)
...
- 왼쪽 클릭 시 파란색으로 표시하고 mask에서 해당 부분을 물체로 지정한다.
- 오른쪽 클릭 시 빨간색으로 표시하고 mask에서 해당 부분을 배경으로 지정한다.
8. cutFunction: GrabCut 알고리즘을 사용한 오림
사용자가 페인팅한 정보를 바탕으로 GrabCut 알고리즘을 적용하여 오림 작업을 수행한다.
def cutFunction(self):
background = np.zeros((1, 65), np.float64)
foreground = np.zeros((1, 65), np.float64)
cv.grabCut(self.img, self.mask, None, background, foreground, 5, cv.GC_INIT_WITH_MASK)
mask2 = np.where((self.mask == 2) | (self.mask == 0), 0, 1).astype('uint8')
self.grabImg = self.img * mask2[:, :, np.newaxis]
cv.imshow('Scissoring', self.grabImg)
- cv.grabCut 함수를 사용하여 오림 작업을 수행하고 결과를 grabImg에 저장하여 화면에 표시한다.
9. incFunction 및 decFunction: 붓 크기 조절
def incFunction(self):
self.BrushSiz = min(20, self.BrushSiz + 1)
def decFunction(self):
self.BrushSiz = max(1, self.BrushSiz - 1)
- incFunction은 붓 크기를 증가시키고, decFunction은 붓 크기를 감소시킨다.
10. saveFunction: 오림 결과 저장
def saveFunction(self):
fname = QFileDialog.getSaveFileName(self, '파일 저장', './')
if fname[0]:
cv.imwrite(fname[0], self.grabImg)
- 사용자가 선택한 파일 경로에 오림된 결과(grabImg)를 저장한다.
11. quitFunction: 프로그램 종료
def quitFunction(self):
cv.destroyAllWindows()
self.close()
- 모든 창을 닫고 프로그램을 종료한다.
메인 함수
app = QApplication(sys.argv)
win = Orim()
win.show()
app.exec_()
- QApplication 객체를 생성하고 Orim 창을 표시하여 애플리케이션을 실행한다.
프로그램 실행 결과
이미지 파일을 하나 다운 받아서 열어주었다. 그리고 그림을 그리기 시작한다.
파란색과 빨간색으로 물체와 배경에 페인팅을 한다. 붓의 크기도 이처럼 조절할 수 있다.
오리면 이렇게 배경과 물체가 오려진다.
이 작업을 반복하며 업데이트할 수 있다.
한 번 더 오림 작업을 진행했다. 작업이 끝났으면 저장도 할 수 있다.
여기에 저장한 파일이 있다.
학습을 마치고
확실히 실습을 하니 정말 흥미롭다. 코드가 많이 길어서 복잡하지만 하나하나 분석하며 어떻게 진행되는지 알게 되었다. 계속해서 실습을 진행해 보겠다.
'인공지능 > 컴퓨터 비전' 카테고리의 다른 글
비전 에이전트 4 - [비전 에이전트 3] 파노라마 영상 제작 (0) | 2024.11.12 |
---|---|
비전 에이전트 3 - [비전 에이전트 2] 교통약자 보호구역 알림 (0) | 2024.11.12 |
비전 에이전트 1 - 지능 에이전트로서 비전 에이전트와 PyQt를 이용한 사용자 인터페이스 (0) | 2024.11.11 |
지역 특징 8 - 연습문제 풀기 4 : 문제 7~8번 (0) | 2024.11.11 |
지역 특징 7 - 연습문제 풀기 3 : 문제 6번 (1) | 2024.11.11 |