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 |