[OpenCV] OpenCV-Python으로 배우는 영상 처리 및 응용 - 4장 연습문제 풀이

2025. 6. 30. 09:06·Programming/Python

1. 콜백 함수란 무엇인가?

콜백 함수는 일반적으로 이벤트를 처리하기 위한 함수로, 개발자가 시스템 함수를 직접 호출하는 방식이 아니라, 어떤 이벤트가 발생하거나 특정 시점에 도달했을 때 시스템이 개발자가 등록한 함수를 호출하는 방식이다. 

(교재 96p)

 

2. 윈도우를 지정하는 cv2.namedWindow() 함수의 두 번째 인수(flags)에 대한 옵션은 여러가지가 있다. 그 중에서 cv2.WINDOW_NORMAL와 cv2.WINDOW_AUTOSIZE간의 차이를 설명하시오.

두 번째 인수 flags는 인도우의 크기 조정과 관련된 파라미터이다.

cv2.WINDOW_NORMAL은 0의 값을 가지며, 윈도우 크기 조정이 가능하다.

cv2.WINDOW_AUTOSIZE는 1의 값을 가지며, 표시된 행렬의 크기에 맞춰 자동 조정된다.

(교재 92p)

 

3. 타원을 그리는 cv2.ellipses() 함수의 인수를 자세히 설명하시오.

[함수 설명]

cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) → img

center를 중심으로 axes 크기의 타원을 그린다.

[인수 설명]

인수 설명 옵션 여부
img 그릴 대상 행렬(영상) 필
center 원의 중심 좌표 필
axes 타원의 절반 크기(x축 반지름, y축 반지름) 필
angle 타원의 각도(3시 방향이 0도, 시계방향 회전) 필
startAngle 호의 시작 각도 필
endAngle 호의 종료 각도 필
color 선의 색상 필
thickness 선의 두께 옵
lineType 선의 형태 옵
shift 좌표에 대한 비트 시프트 옵

(교재 116p)

 

4. OpenCV이 제공하는, 마우스 이벤트와 트랙바 이벤트를 제어할 콜백 함수를 시스템에 등록하는 함수는 각각 무엇이며, 인수가 어떻게 구성되었는지 자세히 설명하시오.

1) 마우스 이벤트 제어

cv2.setMouseCallback(windowName, onMouse, param=None) → None

사용자가 정의한 마우스 콜백 함수를 시스템에 등록

인수 설명 옵션 여부
windowName 이벤트 발생을 확인할 윈도우 이름, 문자열 필
onMouse 마우스 이벤트를 처리하는 콜백 함수 이름(콜백 함수) 필
param 이벤트 처리 함수로 전달할 추가적인 사용자 정의 인수 옵(기본 None)

(교재 100p)

 

2) 트랙바 이벤트 제어

cv2.createTrackbar(trackbarname, winname, value count, onChange) → None

트랙바를 생성한 후, 지정한 윈도우에 추가하는 함수.

인수 설명 옵션 여부
trackbarname 윈도우에 생성되는 트랙바 이름 필
winname 트랙바의 부모 윈도우 이름(트랙바 이벤트 발생을 체크하는 윈도우) 필
value 트랙바 슬라이더의 위치를 반영하는 값(정수) 필
count 트랙바 슬라이더의 최댓값, 최솟값은 항상 0 필
onChange 트랙바 슬라이더의 값이 변경될 때 호출되는 콜백 함수 필

(교재 103p)

 

5. 다음 예시 코드의 실행 결과를 설명하시오.

1) 첫번째 코드

300행, 400열의 행렬을 생성하고, 행렬의 모든 값을 100으로 초기화한다. 윈도우 이름을 ‘Window’로 지정하여, 크기 조정이 가능한 윈도우를 생성한다. 윈도우 위치를 좌측 상단에서 오른쪽으로 100px, 아래쪽으로 200px 떨어진 곳으로 바꾼다.

처음 생성한 행렬을 윈도우에 표시하고 키 입력을 기다린다.

키 입력이 발생하면 윈도우를 없앤다.

 

2) 두번째 코드

400행, 600열, 3채널 행렬을 만들고, 모든 채널을 흰색(255, 255, 255)로 초기화 한다. 이렇게 초기화된 흰색 바탕에 (50, 100)에서 (200, 300)으로 이어지는 5px 두께의 초록색 선을 그린다. 또 (200, 300)과 (300, 400)에 꼭짓점을 둔 빨간색으로 채워진 직사각형을 그린다. 이를 “Line & Rectangle”이라는 이름의 윈도우에 표시하고 키 입력을 기다린다. 키 입력이 생기면 윈도우를 없앤다.

 

6. 300행, 400열의 행렬을 회색 바탕색(100)으로 생성해서 500행, 600열의 윈도우에 표시하시오.

 

# 4장 6번
import numpy as np, cv2

image = np.zeros((300,400), np.uint8)
image[:] = 100

title = '4-6'
cv2.namedWindow(title, cv2.WINDOW_NORMAL)
cv2.moveWindow(title, 500, 600)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

7. 다음 예시 코드는 컴파일 혹은 런타임 에러가 발생한다. 에러가 발생하는 부분을 수정하고 실행 결과를 적으시오.

1) 첫번째 코드

 

# 4장 7번
import numpy as np, cv2

image = np.zeros((300, 400, 3), np.uint8)
image[:] = (255, 255, 255)

pt1, pt2 = (50, 120), (200, 300)

cv2.line(image, pt1, (100, 200), (255, 0, 0))
cv2.line(image, pt2, (110, 210), (100, 100, 100))
cv2.rectangle(image, pt1, pt2, (255, 0, 255))
cv2.rectangle(image, pt1, pt2, (0, 0, 255))

title = "Line & Rectangle"
cv2.namedWindow(title)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.line() 함수에 시작점, 끝점, 색상을 필수로 제공해야 하는데 그렇지 않아 오류가 발생한다. 오류가 나지 않도록 끝점과 색상 정보를 입력하면 사진과 같은 결과가 나온다.

 

2) 두번째 코드

 

# 4장 7번
import numpy as np, cv2

def onMouse(event, x, y, flags, param):
    global title
    if event == cv2.EVENT_LBUTTONDOWN:
        pt = (x, y)
        cv2.circle(image, pt, 5, 100, 1)
        cv2.imshow(title, image)
    elif event == cv2.EVENT_RBUTTONDOWN:
        pt1 = (x, y)
        pt2 = (x+30, y+30)
        cv2.rectangle(image, pt1, pt2, 100, 2)
        cv2.imshow(title, image)

image = np.ones((300,300), np.uint8) * 255

title = "Draw Event"
cv2.namedWindow(title)
cv2.imshow(title, image)
cv2.setMouseCallback(title, onMouse)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.circle() 함수와 cv2.rectangle() 함수에서 사용되는 pt 변수가 정의되지 않아 오류가 발생한다. 이를 고쳐주면 좌클릭 시 윈도우에 원이 그려지고, 우클릭 시 윈도우에 사각형이 그려진다.

 

8. 200행, 300열의 행렬을 2개 만들어서 다음과 같이 배치하시오

# 4장 8번
import numpy as np, cv2

mat1 = np.full((200, 300), 100, np.uint8)
mat2 = np.full((200, 300), 100, np.uint8)

title1, title2 = 'title1', 'title2'
cv2.namedWindow(title1, cv2.WINDOW_AUTOSIZE)
cv2.namedWindow(title2, cv2.WINDOW_AUTOSIZE)
cv2.moveWindow(title1, 0,0)
cv2.moveWindow(title2, 300,200)

cv2.imshow(title1, mat1)
cv2.imshow(title2, mat2)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

9. 600행, 400열의 윈도우를 만들고, 영상 안의 (100, 100) 좌표에 200*300 크기의 빨간 색 사각형을 그리시오.

 

# 4장 9번
# 600행, 400열의 윈도우를 만들고, 영상 안의 (100, 100) 좌표에 200*300 크기의 빨간 색 사각형을 그리시오
import numpy as np, cv2

image = np.full((600, 400, 3), 255, np.uint8)

cv2.rectangle(image, (100, 100), (100+200, 100+300), (0, 0, 255), -1)
cv2.imshow('4-9', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

10. 다음의 마우스 이벤트 제어 프로그램을 작성하시오.

 

# 4장 10번
import numpy as np, cv2

def onMouse(event, x, y, flags, param):
    global title
    if event == cv2.EVENT_LBUTTONDOWN:
        pt = (x, y)
        cv2.circle(image, pt, 20, 100, 1)
        cv2.imshow(title, image)
    elif event == cv2.EVENT_RBUTTONDOWN:
        pt1 = (x, y)
        pt2 = (x+30, y+30)
        cv2.rectangle(image, pt1, pt2, 100, 2)
        cv2.imshow(title, image)

image = np.ones((300,300), np.uint8) * 255

title = "Draw Event"
cv2.namedWindow(title)
cv2.imshow(title, image)
cv2.setMouseCallback(title, onMouse)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

11. 10번 연습문제에서 다음을 추가하여 프로그램을 작성하시오.

 

# 4장 11번
import numpy as np, cv2

width = 1
radius = 20

def onMouse(event, x, y, flags, param):
    global title, width, radius
    if event == cv2.EVENT_LBUTTONDOWN:
        pt = (x, y)
        cv2.circle(image, pt, radius, 100, width)
        cv2.imshow(title, image)
    elif event == cv2.EVENT_RBUTTONDOWN:
        pt1 = (x, y)
        pt2 = (x+30, y+30)
        cv2.rectangle(image, pt1, pt2, 100, 2)
        cv2.imshow(title, image)

image = np.ones((300,300), np.uint8) * 255

def onWidthChange(value):
    global width
    width = value
def onRadiusChange(value):
    global radius
    radius = value

title = "Draw Event"
cv2.namedWindow(title)
cv2.imshow(title, image)
cv2.setMouseCallback(title, onMouse)
cv2.createTrackbar('width', title, 1, 10, onWidthChange)
cv2.createTrackbar('radius', title, 1, 50, onRadiusChange)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

12. 예제_4.2.3인 05.event_trackbar.py에서 화살표 키로 트랙바를 이동하는 코드를 추가하시오.

 

# 4장 12번

import numpy as np
import cv2

def onChange(value):												# 트랙바 콜백 함수
    global image                        	# 전역 변수 참조

    add_value = value - int(image[0][0])        	# 트랙바 값과 영상 화소값 차분
    print("추가 화소값:", add_value)
    if  add_value > 0 : image = image + add_value            		# 행렬과 스칼라 덧셈 수행
    else: image = image - abs(add_value)  # 행렬과 스칼라 덧셈 수행
    cv2.imshow(title, image)

image = np.zeros((300, 500), np.uint8)           	# 영상 생성

title = 'Trackbar Event'
bar_name = "Brightness"   
cv2.imshow(title, image)

cv2.createTrackbar(bar_name, title, image[0][0], 255, onChange)	# 트랙바 콜백 함수 등록

def onLeftArrow():
    global image, bar_name
    if (image[0][0] >= 10): image -= 10
    cv2.setTrackbarPos(bar_name, title, image[0][0])		# 트랙바 위치 변경 
    cv2.imshow(title, image)
        
def onRightArrow():
    global image, bar_name
    if (image[0][0] < 246): image += 10
    cv2.setTrackbarPos(bar_name, title, image[0][0])		# 트랙바 위치 변경 
    cv2.imshow(title, image)
    
switch_case = {2424832: onLeftArrow,   2555904: onRightArrow, }

while True:									# 무한 반복
    key = cv2.waitKeyEx(100)          		# 100ms 동안 키 이벤트 대기
    if key == 27: break                		# ESC 키 누르면 종료
    try:
        func = switch_case[key]
        func()
    except KeyError:
        result = -1

cv2.destroyWindow(title)

 

13. 컬러 영상파일을 적재하여 “text.jpg”와 “tes.png” 파일로 각각 저장하시오. 이때 영상 파일을 가장 좋은 화질로 압축하시오.

import cv2

image = cv2.imread("read_color.jpg", cv2.IMREAD_COLOR)
if image is None: raise Exception("영상 파일 읽기 에러")
    
params_jpg = (cv2.IMWRITE_JPEG_QUALITY, 100)        # JPEG 화질 설정
params_png = [cv2.IMWRITE_PNG_COMPRESSION, 0]       # PNG 압축 레벨 설정

## 행렬을 영상 파일로 저장
cv2.imwrite("test.jpg", image, params_jpg) # 지정 화질로 저장
cv2.imwrite("tes.png", image, params_png)
print("저장 완료")

 

16. PC 카메라를 통해서 받아온 프레임에 다음의 영상처리를 수행하고, 결과 영상을 윈도우에 표시하는 프로그램을 작성하시오.

 

17. PC 카메라를 통해서 받아온 프레임을 좌우로 뒤집어서 “flip_test.avi”이름의 동영상 파일로 저장하는 프로그램을 작성하시오.

 

 

'Programming > Python' 카테고리의 다른 글

[OpenCV] OpenCV-Python으로 배우는 영상 처리 및 응용 - 6장 연습문제 풀이  (1) 2025.07.01
[OpenCV] OpenCV-Python으로 배우는 영상 처리 및 응용 - 5장 연습문제 풀이  (0) 2025.06.30
[Jupyter extension] Jupyter 확장프로그램 개발 환경 구축  (1) 2024.09.02
[OpenCV] 채널 별 배열 구조 + 이미지 투명화  (1) 2023.10.17
'Programming/Python' 카테고리의 다른 글
  • [OpenCV] OpenCV-Python으로 배우는 영상 처리 및 응용 - 6장 연습문제 풀이
  • [OpenCV] OpenCV-Python으로 배우는 영상 처리 및 응용 - 5장 연습문제 풀이
  • [Jupyter extension] Jupyter 확장프로그램 개발 환경 구축
  • [OpenCV] 채널 별 배열 구조 + 이미지 투명화
FoO__511
FoO__511
  • FoO__511
    FoO의 개발 블로그
    FoO__511
  • 전체
    오늘
    어제
    • 분류 전체보기 (17)
      • Programming (13)
        • Java (1)
        • Python (5)
        • Algorithm (2)
        • FE (5)
      • 학과공부 (2)
        • 데이터통신 (1)
        • 기계학습 (1)
        • 기타 (0)
      • 회고 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Git Action
    함수 빌려쓰기
    jupyter extension
    개방 시스템 상호 연결
    Java
    git workflow
    렉시컬 스코프
    TDZ
    백준
    사용자 속성
    seaborn
    opencv-python
    dinamic programming
    nextjs
    utm parameter
    yarn berry
    javascript
    리눅스 카톡
    Priority Queue
    partial application
    결측치 제거
    function barrowing
    opencv-python으로 배우는 영상처리 및 응용
    script tag
    kde plasma
    연습문제 풀이
    결손치 제거
    GA4
    연습문제 6장
    multi boot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
FoO__511
[OpenCV] OpenCV-Python으로 배우는 영상 처리 및 응용 - 4장 연습문제 풀이
상단으로

티스토리툴바