|
|
[5장 연습문제]
# [ 5장 ]
# 1. opencv의 채널 처리 함수에 대해서 설명하시오
# cv2.split(img): 3차원 컬러 이미지(H, W, C)를 입력받아 각 채널을 2차원 그레이스케일 이미지(H, W) 3개로 분리하여 튜플로 반환한다.
# cv2.merge((ch1, ch2, ch3)): 분리된 2차원 채널들을 튜플 형태로 입력받아 다시 하나의 3차원 컬러 이미지로 합친다
# cv2.mixChannels(src, dst, fromTo): 입력 이미지들의 특정 채널들을 원하는 출력 이미지의 위치로 복사하거나 재배치하는
함수로, 짝지어 매핑할 채널 리스트를 통해 매우 유연한 채널 조작이 가능하다.
#
# 2. opencv의 사칙연산을 수행하는 함수와 연산의 수행 방법에 대해서 기술하시오
# cv2.add(src1, src2): 두 이미지 또는 배열의 같은 위치에 있는 픽셀 값을 더한다. 결과값이 범위를 벗어나면 255이나
0으로 제한한다
# cv2.subtract(src1, src2): 첫 번째 이미지에서 두 번째 이미지를 뺀다. 결과값이 범위를 벗어나면 255이나 0으로 제한한다.
# cv2.multiply(src1, src2): 두 이미지의 픽셀 값을 곱한다. 결과값이 범위를 벗어나면 255이나 0으로 제한한다
# cv2.divide(src1, src2): 첫 번째 이미지를 두 번째 이미지로 나눈다. 0으로 나누는 경우를 처리하며, 결과값이 범위를
벗어나면 255이나 0으로 제한한다
#
# 3. 행렬을 초기화하는 방법들에 대해서 기술하고 각 방법으로 선언하시오
# 0으로 초기화 (np.zeros): 지정된 크기의 배열을 생성하고 모든 요소를 0으로 채운다.
# 1로 초기화 (np.ones): 지정된 크기의 배열을 생성하고 모든 요소를 1로 채운다.
# 지정된 값으로 초기화 (np.full): 지정된 크기의 배열을 생성하고 모든 요소를 특정 값으로 채운다.
# 단위 행렬 생성 (np.eye): 주대각선은 1이고 나머지는 0인 단위 행렬을 생성한다.
# 비어있는 배열 생성 (np.empty): 배열을 생성하지만 초기화하지 않아 메모리에 남아있는 쓰레기 값이 들어간다.
matrix = np.zeros((3, 3), dtype=np.uint8)
matrix = np.ones((3, 3), dtype=np.uint8)
matrix = np.full((3, 3), 128, dtype=np.uint8)
matrix = np.eye(3, dtype=np.uint8)
matrix = np.empty((3, 3), dtype=np.uint8)
#
# 4. 사칙 연산이나 논리 비트 연산에서 마스킹을 사용할 때 마스크 행렬에 대한 의미와 사용법에 대해서 설명하시오
# 마스크 행렬의 의미: 연산 대상 행렬과 크기가 같고 0 또는 1(또는 0과 255)로 구성된 8비트 단일 채널 행렬이다.
마스크 값이 0인 위치는 연산 결과가 0으로 고정되거나 연산이 건너뛰어지고, 0이 아닌 위치(주로 255)만 연산이 수행된다.
# 사용법: OpenCV의 대부분의 사칙연산 및 논리연산 함수의 mask 인자에 마스크 행렬을 전달하여 요소별로 선택적 연산이
이루어지도록 한다.
#
# 5. cv2.reduce() 함수에 대해서 설명하고, 특히 축소 시에 사용하는 연산 옵션에 대해서 상세히 설명하시오
# 함수 설명: 행렬을 1차원 행렬로 축소하는 함수이다. 행렬 전체를 계산하여 합계, 평균, 최댓값, 최솟값을 구할 때 사용한다.
# 사용법: cv2.reduce(src, dim, rtype, dtype) 형태로 사용하며, dim으로 행 축소(0) 또는 열 축소(1)를 지정하고, rtype으로
연산 방식을 지정한다.
# 연산 옵션 (rtype):
# cv2.REDUCE_SUM: 지정된 축의 모든 요소를 더한다.
# cv2.REDUCE_AVG: 지정된 축의 모든 요소의 평균을 구한다.
# cv2.REDUCE_MAX: 지정된 축에서 가장 큰 값을 찾는다.
# cv2.REDUCE_MIN: 지정된 축에서 가장 작은 값을 찾는다.
#
# 6. 다음 코드를 디버깅하시오
import numpy as np
m1 = [1, 2, 3, 1, 2, 3]
m2 = [3, 3, 4, 2, 2, 3]
m3 = np.add(m1, m2) # m3 = m1 + m2 이어붙이는 것이 아닌 요소별 연산으로 변경
m4 = np.subtract(m1, m2) # m4 = m1 - m2
print("[m1] = %s" % m1 )
print("[m2] = %s" % m2 )
print("[m3] = %s" % m3 )
print("[m4] = %s" % m4 )
import numpy as np, cv2
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
m1 = np.array(data).reshape(2, 2, 3) # (2, 3, 2) -> split의 채널 수에 맞게(1 or 3) 원소의 개수에 맞게 깊이 변경
r, g, b = cv2.split(m1)
print("[m1] = %s" % m1)
print("[r, g, b] = %s %s %s" % (r, g, b))
#
# 7. 컬러 이미지를 입력받아 각 색의 밝기만으로 출력하는 화면으로 총 4개를 출력하시오
import numpy as np, cv2
logo = cv2.imread("이미지 이름", cv2.IMREAD_COLOR)
if logo is None: raise("영상파일 읽기 오류")
blue, green, red = cv2.split(logo)
zero = np.zeros_like(blue) # 0으로 채워진 blue 형태의 행렬 zero 생성
blue_img = cv2.merge((blue, zero, zero)) # zero와 각 채널 값을 합성해 한 채널의 값만 가지고 있는 컬러 이미지 생성
green_img = cv2.merge((zero, green, zero))
red_img = cv2.merge((zero, zero, red))
cv2.imshow("logo", logo)
cv2.imshow("blue_img", blue_img)
cv2.imshow("green_img", green_img)
cv2.imshow("red_img", red_img)
cv2.waitKey()
#
# 로고 없음
# 8. 다음 코드에서 특정 영역의 타원만을 복사하여 새 창에 표시하는 프로그램을 완성하시오
import numpy as np, cv2
image = cv2.imread("best_frame.jpg", cv2.IMREAD_COLOR)
mask = np.zeros(image.shape[:2], np.uint8)
center = (190, 170)
cv2.ellipse(mask, center, (60, 30), 0, 0, 360, 255, -1)
dst = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("iamge", image)
cv2. imshow("dst", dst)
cv2.waitKey()
#
# 9. 3*6 행렬을 생성하고, cv2.reduce() 함수를 이용햐여 가로 방향과 세로 방향으로 감축하여 평균을 구한 결과를 출력하시오
import numpy as np, cv2
matrix = np.array([[10, 20, 30, 40, 50, 60],
[10, 20, 30, 40, 50, 60],
[10, 20, 30, 40, 50, 60]], dtype=np.float32)
v_reduce = cv2.reduce(matrix, 0, cv2.REDUCE_AVG)
print("세로 방향 감축(열 평균):")
print(v_reduce)
h_reduce = cv2.reduce(matrix, 1, cv2.REDUCE_AVG)
print("\n가로 방향 감축(행 평균):")
print(h_reduce)
#
# 10. pc카메라로 영상을 읽어서 특정 부분의 합과 평균을 구하는 프로그램을 작성하시오
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
roi = frame[100:300, 200:400]
roi_sum = np.sum(roi)
roi_mean = np.mean(roi)
text = f"Sum: {roi_sum:.0f}, Mean: {roi_mean:.2f}"
cv2.putText(frame, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 1)
cv2.rectangle(frame, (200, 100), (400, 300), (255, 0, 0), 1)
cv2.imshow("Camera", frame)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
#
# 11. 카메라의 영상을 받아들여 윈도우의 특정 영역에서 재생하시오
import numpy as np
import cv2
win_width, win_height = 400, 300
roi_width, roi_height = 320, 240
start_x, start_y = 30, 30
cap = cv2.VideoCapture(0)
cv2.namedWindow("Video", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Video", win_width, win_height)
while True:
ret, frame = cap.read()
if not ret:
break
background = np.zeros((win_height, win_width, 3), np.uint8)
frame_resized = cv2.resize(frame, (roi_width, roi_height))
background[start_y:start_y+roi_height, start_x:start_x+roi_width] = frame_resized
cv2.rectangle(background, (start_x, start_y), (start_x+roi_width, start_y+roi_height), (0, 0, 255), 1)
cv2.imshow("Video", background)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
#
# 12. 영상파일을 읽어서 메인 윈도우에 각각 밝기를 50증가시키고, 영상의 화소대비를 증가시키는 영역을 지정하여
출력하시오
import numpy as np
import cv2
image = cv2.imread("best_frame.jpg", cv2.IMREAD_COLOR)
x1, y1, w1, h1 = 50, 50, 200, 150
roi1 = image[y1:y1+h1, x1:x1+w1]
roi1 = cv2.add(roi1, 50)
image[y1:y1+h1, x1:x1+w1] = roi1
x2, y2, w2, h2 = 300, 200, 200, 150
roi2 = image[y2:y2+h2, x2:x2+w2]
roi2 = cv2.convertScaleAbs(roi2, alpha=1.5, beta=-30)
image[y2:y2+h2, x2:x2+w2] = roi2
cv2.imshow("Processed", image)
cv2.waitKey()
cv2.destroyAllWindows()
#
# 13. cv2.solted()함수를 이용하여 Rect객체의 크기에 따라 오름차순으로 정렬하여 콘솔창에 출력하는 프로그램을
작성하시오
import numpy as np
import cv2
class Rect:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
def area(self):
return self.width * self.height
rects = [
Rect(10, 10, 50, 50), # 면적: 2500
Rect(100, 100, 20, 30), # 면적: 600
Rect(50, 50, 100, 100), # 면적: 10000
Rect(0, 0, 40, 40) # 면적: 1600
]
print("정렬 전 Rect 크기 (너비x높이):")
for r in rects:
print(f"[{r.width}x{r.height}]", end=" ")
print("\n")
areas = np.array([r.area() for r in rects], dtype=np.int32)
areas = areas.reshape(1, -1)
indices = cv2.sortIdx(areas, cv2.SORT_EVERY_ROW + cv2.SORT_ASCENDING)
print("정렬 후 Rect 크기 (면적 오름차순):")
for i in indices.flat:
r = rects[i]
print(f"Area: {r.area()}, Size: [{r.width}x{r.height}]")
#
# 14. 다음의 연립방정식을 가우시안 소거법의 역함수를 계산해서 해를 구하는 프로그램을 작성하시오
# 3x(1) + 6x(2) + 3x(3) = 2
# -5x(1) + 6x(2) + x(3) = 10
# 2x(1) - 3x(2) + 5x(3) = 28
import numpy as np
A = np.array([
[3, 6, 3, 2],
[-5, 6, 1, 10],
[2, -3, 5, 28]
], dtype=float)
n = 3
for i in range(n):
for j in range(i+1, n):
ratio = A[j][i] / A[i][i]
A[j] = A[j] - ratio * A[i]
X = np.zeros(n)
for i in range(n-1, -1, -1):
X[i] = A[i][n]
for j in range(i+1, n):
X[i] -= A[i][j] * X[j]
X[i] /= A[i][i]
print("해:")
print("x1 =", X[0])
print("x2 =", X[1])
print("x3 =", X[2])
#
# 15. 출력된 사각형을 중심점을 기준으로 45도 회전시켜 출력하는 프로그램을 작성하시오
import numpy as np, cv2
pst1 = np.array([(200, 50, 1), (400, 50, 1), (400, 250, 1), (200, 250, 1)], np.float32)
theta = 45 * np.pi / 180
m = np.array([[np.cos(theta), -np.sin(theta), 0],
[np.sin(theta), np.cos(theta), 0],
[0, 0, 1]], np.float32)
delta = (pst1[2] - pst1[0]) // 2
center = pst1[0] + delta
t1 = np.eye(3, dtype=np.float32)
t2 = np.eye(3, dtype=np.float32)
t1[0, 2] = -center[0]
t1[1, 2] = -center[1]
t2[0, 2] = center[0]
t2[1, 2] = center[1]
m2 = t2 @ m @ t1
pst2 = cv2.gemm(pst1, m2, 1, None, 1, flags=cv2.GEMM_2_T)
for i, (pt1, pt2) in enumerate(zip(pst1, pst2)):
print("pst1[%d] = %s, pst2[%d]= %s" %(i, pst1, i, pst2))
image = np.full((400, 500, 3), 255, np.uint8)
cv2.polylines(image, [np.int32(pst1[:, :2])], True, (0, 255, 0), 2)
cv2.polylines(image, [np.int32(pst2[:, :2])], True, (255, 0, 0), 3)
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# ex1
'''
import numpy as np
import cv2
dragging = False
offset_x, offset_y = 0, 0
start_x, start_y = 30, 30
def mouse_callback(event, x, y, flags, param):
global start_x, start_y, dragging, offset_x, offset_y
if event == cv2.EVENT_LBUTTONDOWN:
if start_x <= x <= start_x + roi_width and start_y <= y <= start_y + roi_height:
dragging = True
offset_x = x - start_x
offset_y = y - start_y
elif event == cv2.EVENT_MOUSEMOVE:
if dragging:
start_x = x - offset_x
start_y = y - offset_y
elif event == cv2.EVENT_LBUTTONUP:
dragging = False
win_width, win_height = 800, 600
roi_width, roi_height = 160, 120
cap = cv2.VideoCapture(0)
cv2.namedWindow("Video", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Video", win_width, win_height)
cv2.setMouseCallback("Video", mouse_callback)
while True:
ret, frame = cap.read()
if not ret:
break
background = np.zeros((win_height, win_width, 3), np.uint8)
frame_resized = cv2.resize(frame, (roi_width, roi_height))
background[start_y:start_y+roi_height, start_x:start_x+roi_width] = frame_resized
cv2.rectangle(background, (start_x, start_y), (start_x+roi_width, start_y+roi_height), (0, 0, 255), 1)
cv2.imshow("Video", background)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
'''
[6장 연습문제]
# [ 6장 ]
# 1. 그레이 스케일 이미지가 의미하는 것이 무엇인지 설명하시오
# 그레이스케일 이미지는 컬러 정보를 배제하고 오직 밝기 정보만을 2차원 공간적 데이터 구조에 매핑한 것으로, 각 픽셀은
일반적으로 8비트 정밀도를 통해 0부터 255 사이의 정수 값을 가진다
#
# 2. 화소의 밝기와 화소값에 대해서 설명하시오
# 화소의 밝기란 그레이스케일 영상에서 픽셀이 표현하는 물리적인 빛의 양을 의미하고, 화소값은 그 물리량을 영상 처리
시스템에서 처리할 수 있도록 0에서 255 사이의 정수로 정량화하여 저장한 것이다.
#
# 3. 두 개의 영상을 합성하는 방법을 두 가지 이상 기술하시오
# 가중치 합은 두 영상의 픽셀 값에 각각 가중치를 곱한 후 둘의 값을 더하여 새로운 영상을 만드는 방식으로, 두 가중치 합이
1보다 크면 두 원본 영상보다 밝은 영상이 되고 1보다 작으면 어두운 영상이 된다.
# OpenCV의 cv2.addWeighted 함수는 이 계산을 기반으로 픽셀 단위 연산을 수행하여 결과값이 8비트 범위를 벗어나지
않도록 포화 연산을 자동으로 처리한다.
#
# 4. 영상에서 밝기 변경과 명암 대비 변경의 차이를 설명하시오
# 영상에서 밝기 변경은 모든 픽셀의 화소값에 일정한 상수를 더하거나 빼는 것으로 화면 전체의 어둡고 밝은 정도를 조절하는 반면 명암 대비 변경은 화소값에 상수를 곱하거나 나누는 것으로 밝은 부분과 어두운 부분의 차이를 부풀리거나 축소시킨다.
#
# 5. 영상처리에서 히스토그램이란 무엇인가?
# 영상처리에서 히스토그램은 영상 내 화소값의 빈도 분포를 나타내는 통계적 도구로, 가로축은 0부터 255까지의 밝기 단계를, 세로축은 각 단계에 해당하는 밝기 값을 가지는 화소의 수를 표시한다.
# 이를 통해 영상이 전반적으로 어두운지 밝은지 또는 명암 대비가 뚜렷한지 확인할 수 있고 전체 화소 수로 나누어
확률 분포 형태로 정규화하여 사용하기도 한다.
#
# 6. 히스토그램 스트레칭의 과정을 기술하시오
# 히스토그램 스트레칭은 영상 내 화소값의 분포가 좁게 뭉쳐 있을 때 이를 0부터 255까지 전체 범위로 강제로 늘려
명암 대비를 높이는 기법으로 먼저 영상 전체에서 가장 어두운 화소의 밝기값과 가장 밝은 화소의 밝기값을 찾아낸다
# 그 다음 가장 어두운 값은 0으로, 가장 밝은 값은 255로 대응시키고 나머지 중간 화소값들은 그 사이의 비율에 맞춰
선형적으로 재배치하여 좁은 구간에 모여 있던 히스토그램이 양 끝으로 넓게 펼쳐지며 영상의 어두운 부분과 밝은 부분의
차이가 이전보다 훨씬 뚜렷해진다
#
# 7. 히스토그램 평활화 과정을 기술하시오
# 히스토그램 평활화는 영상의 화소값 분포를 골고루 펼쳐서 명암 대비를 높이는 기법으로, 먼저 영상 전체에서 각 화소값이 나타나는 빈도를 조사하여 히스토그램을 만든다.
# 그 다음 가장 어두운 0번 화소부터 순차적으로 빈도수를 누적하여 합계를 구해 전체 화소 수로 나눠
0~1 사이의 값을 가지는 픽셀값에 최대 밝기 단계인 255를 곱해 정수화시켜 특정 밝기에 뭉쳐 있던 화소들이
전체 구간으로 균일하게 퍼지면서 숨겨진 세부 묘사가 더 뚜렷하게 드러난다.
#
# 8. opencv함수 중에서 cv2.addWeighted()함수를 사용해서 두 영상을 합성하는 프로그램을 작성하시오
import cv2
import sys
img1 = cv2.imread('best_frame.jpg')
img2 = cv2.imread('sea-beach.jpg')
if img1 is None or img2 is None:
print('Image load failed!')
sys.exit()
alpha = 0.5
beta = 0.5
gamma = 0
dst = cv2.addWeighted(img1, alpha, img2, beta, gamma)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
#
# 9. 2개의 트렉바를 추가해 각 영상의 반영 비율을 조절할 수 있는 기능을 추가하시오
import cv2
import sys
img1 = cv2.imread('best_frame.jpg')
img2 = cv2.imread('sea-beach.jpg')
if img1 is None or img2 is None:
print('Image load failed!')
sys.exit()
cv2.namedWindow('Blended Image')
cv2.createTrackbar('Alpha', 'Blended Image', 50, 100, lambda x: None)
cv2.createTrackbar('Beta', 'Blended Image', 50, 100, lambda x: None)
while True:
alpha_val = cv2.getTrackbarPos('Alpha', 'Blended Image')
beta_val = cv2.getTrackbarPos('Beta', 'Blended Image')
alpha = alpha_val / 100
beta = beta_val / 100
dst = cv2.addWeighted(img1, alpha, img2, beta, 0)
cv2.imshow('Blended Image', dst)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
#
# 10. np.float32형으로 행렬을 선언하여 회색이 점진적으로 짙어지는 영상을 만드시오
import cv2
import numpy as np
dst = np.zeros((256, 512), dtype=np.float32)
for i in range(512):
dst[:, i] = ((511 - i) / 511.0) * 0.5
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
#
# 11. cv2.calc_histo() 함수를 이용하여 cv2.calcHist() 함수와 같이 동작하도록 하는 프로그램을 작성하시오
import numpy as np, cv2
def calc_histo(image, channals, bsize, ranges):
shape = bsize if len(channals) > 1 else (bsize[0], 1)
hist = np.zeros(shape, np.float32)
gap = np.divide(ranges[1::2], bsize)
for row in image:
for val in row:
idx = np.divide(val[channals], gap).astype('uint')
hist[tuple(idx)] += 1
return hist
#
# 12. opencv 함수 중에 cv2.reduce() 함수를 이용해서 수직 및 수평 방향 투영을 수행하는 프로그램을 작성하고
영상 파일을 읽어서 투영 히스토그램을 출력하시오
import cv2
import numpy as np
img = cv2.imread('best_frame.jpg', cv2.IMREAD_GRAYSCALE)
_, bin_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
v_proj = cv2.reduce(bin_img, 0, cv2.REDUCE_SUM, dtype=cv2.CV_32S)
h_proj = cv2.reduce(bin_img, 1, cv2.REDUCE_SUM, dtype=cv2.CV_32S)
h, w = img.shape
v_hist = np.zeros((100, w), np.uint8)
h_hist = np.zeros((h, 100), np.uint8)
v_max = np.max(v_proj) if np.max(v_proj) > 0 else 1
h_max = np.max(h_proj) if np.max(h_proj) > 0 else 1
for i in range(w):
val = int(v_proj[0, i] * 100 / v_max)
cv2.line(v_hist, (i, 100), (i, 100 - val), 255, 1)
for i in range(h):
val = int(h_proj[i, 0] * 100 / h_max)
cv2.line(h_hist, (0, i), (val, i), 255, 1)
cv2.imshow('Vertical', v_hist)
cv2.imshow('Horizontal', h_hist)
cv2.waitKey(0)
#
# 13. 컬러 영상을 입력받아서 cv2.cvtColor() 함수를 사용하지 않고 YCbCr 컬러 공간으로 변환한 후 다시 환원하는 프로그램을 작성하시오
import cv2
import numpy as np
img = cv2.imread('best_frame.jpg').astype(np.float32)
b, g, r = cv2.split(img)
y = 0.299 * r + 0.587 * g + 0.114 * b
cb = (b - y) * 0.564 + 128
cr = (r - y) * 0.713 + 128
ycbcr = cv2.merge([y.astype(np.uint8), cb.astype(np.uint8), cr.astype(np.uint8)])
r_res = y + 1.402 * (cr - 128)
g_res = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128)
b_res = y + 1.772 * (cb - 128)
recovered = cv2.merge([b_res.astype(np.uint8), g_res.astype(np.uint8), r_res.astype(np.uint8)])
cv2.imshow('YCbCr', ycbcr)
cv2.imshow('Recovered', recovered)
cv2.waitKey(0)
#
# 14. 컬러 영상 파일을 읽어 들여서 HSV 컬러 공간으로 변환하고 Hue 와 Satuartion 채널로 2차원 히스토그램을 만드시오
import cv2
import numpy as np
img = cv2.imread('best_frame.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
hist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
hist_norm = cv2.normalize(hist, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
cv2.imshow('2D Histogram (H-S)', hist_norm)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
|
|

첫댓글 1. 콜백함수가 무엇인가? 누가 호출하는가?
2. cvwaitkey함수의 역할은 무엇인가? imshow만 호출하면 화면에 출력이 안되는 이유는?
콜백함수는 이벤트 루프에 인수로 전달되어 특정한 동작이나 시점이 됐을 때 호출되는 함수로 이벤트 루프는 while문을 사용하여 메인 쓰레드에서 빠르게 반복되며 반복문이 한 바퀴 돌 때마다 특정한 동작이나 시점이 될 때 콜백함수를 호출합니다.
cvwaitkey()는 인자로 입력된 시간만큼의 프로그램 실행 제어권을 가져와 특정한 입력이 들어오면 그 즉시 키의 아스키 코드 값과 제어권을 반환하고, 0이 인자로 입력될 경우 키 값이 입력될 때까지 무한 대기합니다.
imshow는 단순히 메모리에 있는 이미지를 특정 창에 그리는 동작 외에 그 창을 화면에 유지하거나 이벤트를 처리하는 능력이 없어 이미지를 그린 후에 바로 다음 코드로 넘어가 종료되거나 다음 루프로 진행돼 우리 눈에는 창이 아예 안 뜨거나 하얗게 멈춘 상태로 보이게 됩니다. 따라서 cvwaitkey()와 같은 함수를 같이 사용하여 특정한 시간이나 값이 입력될 때까지 유지시킬 수 있습니다