|
|
[3장 연습문제]
# [ 3장 ]
#
# 1. 변수, 상수, 리터럴에 대해서 비교 설명하시오.
# 변수는 변수는 문자나 숫자를 특정한 메모리 공간에 이름을 붙여 저장하는 것이고,
# 상수는 이러한 변수를 변경하지 못하도록 리터럴화 시키는 것인데 파이썬에서는 이러한 키워드를 따로 지원하지 않아 변수명을 대문자로 지어 구별한다
# 또한 리터럴은 숫자나 문자열같은 이미 고정된 특정한 값 그 자체를 의미한다
#
# 2. 연산자의 종류를 10개 이상 기술하여 설명하고 각각의 우선순위를 나타내시오
# 1) 괄호 : [], {}, () 는 리스트, 사전, 튜플을 생성하며 우선 순위 1에 해당한다
# 2) 첨자 : [?], (?) 는 리스트, 튜플의 원소를 참조할 때 사용하며 우선 순위는 2이다
# 3) 거듭제곱 : ** 은 앞의 피면산자를 뒤 피연산자만큼 곱하고 우선 순위는 3이다
# 4) 마이너스 : '-' 는 단항 연산자로 뒤의 피연산자의 부호를 음수로 바꾸며 우선 순위는 4이다
# 5) 곱셈 : '*' 은 두 파연산자를 곱하며 우선 순위는 5이다
# 6) 덧셈 : '+' 은 피연산자의 자료형에 따라 수를 더하거나 문자를 붙이며 우선 순위는 6이다
# 7) 초과, 이상 : >, >= 는 앞 연산자가 뒤 연산자 이상(초과) 인지 검사하며 우선 순위는 7이다
# 8) 같음 : "==" 은 앞과 뒤의 연산자가 같은지 검사하며 우선 순위는 8이다
# 9) 논리합 : "and" 는 두 피연산자나 결과가 모두 참인지 검사하며 우선 순위는 10이다
# 10) 할당 : '=' 은 앞 피연산자에 뒤 피연산자의 결과를 저장하며 우선 순위는 12이다
#
# 3. 자주 사용하는 함수들을 모아서 모듈을 만들고자 할 때의 방법을 자세히 기술하시오
# 자주 사용하는 함수들을 별도의 파이썬 파일로 저장하면 그것이 곧 모듈이 되며, 파일명이 모듈명이 된다
# 이때 모듈 파일 안에 함수에 포함되지 않은 실행 코드가 있으면 불러오는 순간 자동으로 동작하므로 if __name__ == "__main__": 구문을 사용해 이를 방지해야 한다.
#
# 4. 함수를 선언하는 방법, 인자, 반환 방법에 대해서 자세히 설명하시오
# 함수는 def 키워드를 사용하여 이름을 붙여 선언하며 이름 뒤 소괄호 안에 외부에서 전달받는 데이터인 인자를 정의하고
# 필요에 따라 기본값을 설정하거나 여러 개를 정의하여 함수가 작동하는 데 필요한 입력값을 얻어낸 후 return 키워드를 통해 실행 결과물을 호출처로 반환한다.
#
# 5. 슬라이스 연산자를 사용하는 방법을 자세히 설명하고, 10개의 원소를 갖는 리스트를 선언하여 8번쨰 원소에서 2번쨰 원소까지 역순으로 가져오는 방법을 작성하시오
# 슬라이스 연산자는 새로운 임시객체를 생성하여 열거형 객체 뒤에 대괄호를 붙여 첫번째 숫자가 가리키는 인덱스부터 두 번째 숫자가 가리키는 인덱스까지
# 3번째 숫자가 의미하는 크기만큼 이동하며 해당 원소의 데이터를 새로운 객체에 채워넣는다
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = a[8: 2: -1]
print(b)
# 6. 넘파이 함수를 이용해서 ndarray 행렬을 선언하는 함수들을 열거하고 각각의 예시를 적고 설명하시오
# 1) .zeros() : 는 .zeros(2, 3)처럼 형태를 튜플로 전달하여 각각 행과 열수가 되고 각 요소는 0으로 초기화되어 생성된다
# 2) .ones() : 는 모든 요소를 1로 채우는 함수이다
# 3) .full() : 는 첫 번째 인자를 (x, y) 형태의 튜플로 받아 생성하고 두번째 인자 값으로 채운다
#
# 7. 다차원 행렬을 1차원으로 변경하는 방법을 3 가지 이상 제시하고 실행되는 방법을 설명하시오
# 1) flatten은 ndarray.flatten(order='C') 형태로 호출하면 원본 데이터를 메모리의 새로운 공간에 모두 복사하여 독립적인 1차원 임시객체를 생성, 반환해 해당 호출문을 대체한다.
# 이 방식은 반환된 배열을 수정해도 원본에 영향을 주지 않아 데이터 안전성이 가장 높지만 복사 과정에서 메모리와 시간이 추가로 소요된다.
# 2) 두 번째 방식인 ravel은 np.ravel(a, order='C') 또는 a.ravel() 형태로 선언하며 실행 시 새로운 메모리 할당 없이 원본의 주소를 그대로 가리키는 참조 방식이다.
# 결과물로 원본과 연결된 뷰를 반환하기 때문에 처리 속도가 매우 빠르고 효율적이지만 반환된 값을 수정하면 원본 데이터도 함께 변해 주의하여 사용해야 한다.
# 3) 세 번째 방식인 reshape은 ndarray.reshape(-1, order='C') 형태로 호출하며 논리적인 줄 바꿈이 일어나도록 하는 메타 데이터(행이나 열의 수)를 제거하여 메모리에 있는 그대로의 1차원적인 배열로 바뀌도록 한다
#
# 8. 넘파이 행렬 원소의 자료형의 종류를 기술하시오
# 1) 정수형 및 부호 없는 정수형 : 데이터의 범위와 음수 포함 여부에 따라 int와 uint 계열로 나뉜다. int8, int16, int32, int64는 음수와 양수를 모두 포함한 정수를 저장하며,
# 비트 수가 커질수록 메모리를 더 쓰는 대신 다룰 수 있는 수의 범위가 넓어지는 반면 uint8, uint16, uint32, uint64는 0 이상의 양수만 저장하는 대신 같은 비트의 정수형보다 두 배 더 큰 양수 값을 담을 수 있어, 음수값을 가질 필요가 없는 이미지 데이터 처리에 특화되어 있다.
# 2) 실수형 (정밀도와 속도의 전문화) : 소수점 데이터를 다루며 연산의 우선순위가 정밀도인지 혹은 속도인지에 따라 다르다. float64와 float128은 소수점 아래를 아주 세밀하게 표현하는 정밀도 특화 자료형으로, 미세한 오차가 결과에 큰 영향을 주는 과학 시뮬레이션이나 금융 분석에 사용된다.
# 반대로 float16과 float32는 정밀도를 일부 희생하는 대신 메모리 사용량을 줄이고 연산 속도를 비약적으로 높인 속도 특화 자료형으로, 대용량 데이터를 빠르게 처리해야 하는 딥러닝 모델 학습에서 표준으로 사용된다.
# 3) 복소수 및 기타 특수 자료형 : 수치 계산의 확장성과 논리 판단을 위한 타입들로 complex64와 complex128은 실수부와 허수부를 함께 관리하며 전기 전자 공학 연산에 쓰인다.
# 또한 bool은 참과 거짓을 저장하여 데이터 필터링의 기초가 된다. 또한 날짜 정보를 다루는 datetime64, 시간 간격을 나타내는 timedelta64, 그리고 일반적인 문자열을 담는 string_과 unicode_가 있다. 마지막으로 모든 파이썬 객체를 담을 수 있는 object는 유연하지만 넘파이 특유의 고속 연산 이점이 사라진다.
#
# 9. 실수형 원소 10개를 갖는 행렬을 선언 후 전체 원소의 합과 평균을 구하시오 합과 평균은 소수점 둘째 자리까지 나타내시오
import numpy as np
a = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0]
print(f"합계 : {np.sum(a):.2f} \n평균 : {np.mean(a):.2f}")
# 10. 0~50 사이의 임의의 원소(정수형, 중복가능)을 500개 만들어서 가장 중복이 많이 나온 원소 3개를 원소값과 중복 횟수로 출력하시오
import numpy as np
data = np.random.randint(0, 51, 500)
values, counts = np.unique(data, return_counts=True)
top_indices = np.argsort(counts)[::-1][:3]
print("가장 많이 나온 원소")
for i in top_indices: print(f"원소값: {values[i]}, 중복 횟수: {counts[i]}회")
[4장 연습문제]
# [ 4장 ]
# 1 콜백 함수란 무엇인가?
# 콜백 함수는 어떤 입력으로 인해 이벤트가 발생하거나 특정 시점에 도달했을 때 시스템에서 개발자가 등록한 함수를 호출하는 것으로 상황에 따른 동작을 자동화할 수 있다.
#
# 2. 윈도우를 지정하는 vc2.namedwindow()함수의 두 번째 인수에 대한 옵션 중 WINDOW_NORMAL 과 WINDOW_AUTOSIZE 간의 차이를 설명하시오
# 첫 번째 옵션은 창 크기를 사용자 마음대로 늘리거나 줄일 수 있고, 이때 내부의 이미지도 창 크기에 맞춰 자동으로 확대되거나 축소된다.
# 두 번째 옵션은 창 크기를 사용자가 조정할 수 없고 이미지의 원본 크기에 맞춰 창 크기가 고정된다
#
# 3. 타원을 그리는 cv2.eclipse() 함수의 인수를 자세히 설명하시오
# 첫 번째 인자 (img): 타원을 그릴 대상 이미지이다.
# 두 번째 인자 (center): 타원의 중심점 좌표로 (x, y) 형태의 튜플을 사용한다.
# 세 번째 인자 (axes): 타원의 크기를 결정하는 (가로 반지름, 세로 반지름) 튜플이다.
# 네 번째 인자 (angle): 타원 자체가 회전하는 각도이다.
# 다섯 번째 인자 (startAngle): 호를 그리기 시작할 각도이다.
# 여섯 번째 인자 (endAngle): 호를 끝낼 각도이다.
# 일곱 번째 인자 (color): 선의 색상으로 컬러 이미지라면 (B, G, R) 형식을 사용한다.
# 여덟 번째 인자 (thickness): 선의 두께이며 음수 값을 넣으면 내부가 채워진다.
#
# 4. opencv가 제공하는 마우스 이벤트와 트랙바 이벤트를 제어할 콜백 함수를 시스템에 등록하는 함수는 각각 무엇이며 어떤 인수로 구성되었는지 설명하시오
# 1) 마우스 이벤트 등록 함수: cv2.setMouseCallback()
# 사용자가 윈도우 창에서 클릭하거나 마우스를 움직일 때 반응하도록 시스템에 등록하는 함수이다.
# 첫 번째 인자 (windowName): 마우스 이벤트를 감지할 윈도우 창의 이름이다.
# 두 번째 인자 (onMouse): 이벤트 발생 시 호출될 콜백 함수 이름이다.
# 세 번째 인자 (param): 콜백 함수에 전달하고 싶은 사용자 정의 데이터이다. (생략 가능)
# 2) 트랙바 이벤트 등록 함수: cv2.createTrackbar()
# 윈도우 창에 슬라이더 바를 생성하고, 값이 변할 때마다 반응하도록 등록하는 함수이다.
# 첫 번째 인자 (trackbarName): 생성할 트랙바의 이름입이다.
# 두 번째 인자 (windowName): 트랙바를 부착할 윈도우 창의 이름이다.
# 세 번째 인자 (value): 트랙바 시작 시의 초기 위치 값이다.
# 네 번째 인자 (count): 트랙바가 이동할 수 있는 최대값이다.
# 다섯 번째 인자 (xxonChange): 슬라이더가 움직일 때마다 호출될 콜백 함수 이름이다.
#
# 5. 다음 코드의 실행 결과를 설명하시오
import numpy as np
import cv2
image = np.zeros((200, 300), np.uint8)
image.fill(255)
title1, title2 = "auto", "normal"
cv2.namedWindow(title1, cv2.WINDOW_AUTOSIZE)
cv2.namedWindow(title2, cv2.WINDOW_NORMAL)
cv2.imshow(title1, image)
cv2.imshow(title2, image)
cv2.resizeWindow(title1, 400, 300)
cv2.resizeWindow(title2, 400, 300)
cv2.waitKey(0)
cv2.destroyAllWindows()
# title1 윈도우는 좌상단 점에 맞춰 이미지가 출력된다
# title2 윈도우는 이미지가 윈도우 창에 맞춰 확장되어 출력되고 사용자가 윈도우의 화면 크기를 변형할 수 있다.
#
# 6. 300행, 400열의 행렬을 100으로 채운 후 생성해서 500행 600열의 윈도우에 표시하시오
import numpy as np, cv2
image = np.full((300, 400), 100, np.uint8)
title = "500x600 Window"
cv2.namedWindow(title, cv2.WINDOW_AUTOSIZE)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# 7 해당 코드를 디버깅하시오
import numpy as np, cv2
image = np.zeros((400, 400, 3), np.uint8)
image[:] = (255, 255, 255)
pt1, pt2, pt3 = (50, 130), (200, 300), (300, 200)
cv2.line(image, pt1, (100, 200), (255, 0, 0)) # (255, 0, 0) 색 인자 추가
cv2.line(image, (200, 250), (300, 250), (100, 100, 100)) # (200, 200) 끝점 추가
cv2.rectangle(image, pt1, pt2, (255, 0, 255))
cv2.rectangle(image, pt2, pt3, (0, 0, 255)) # 끝점을 새로 정의하여 중복 회피 pt3 = (300, 200)
title = "line & Rectangle"
cv2.namedWindow(title)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 8. 200행, 300열의 행렬 2개를 만들어서 한 점을 중심으로 윈도우 창이 좌상단, 우하단에 팝업되도록 작성하시오
import numpy as np, cv2
w, h = 300, 200
image = np.full((h, w), 255, np.uint8)
title1, title2 = "a", "b"
cv2.namedWindow(title1)
cv2.moveWindow(title1, 600, 500)
cv2.imshow(title1, image)
cv2.namedWindow(title2)
cv2.moveWindow(title2, 600-w, 500-h)
cv2.imshow(title2, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# 9. 600, 400 윈도우 안에 100, 100 좌표상에 200, 300 크기의 빨간 색 사각형을 그리시오
import numpy as np, cv2
image = np.full((600, 400, 3), (255, 255, 255), np.uint8)
cv2.rectangle(image, (100, 100), (300, 400), (0, 0, 255), 1)
title = "radsqueare"
cv2.namedWindow(title)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# 10. 마우스 오른쪽 버튼 클릭 시 원(r = 20화소)를 그리고, 왼쪽버튼 클릭 시 정사각형(30화소)를 그리는 코드를 작성하시오
import numpy as np, cv2
def action(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image, (x, y), 20, (0))
cv2.imshow(title, image)
if event == cv2.EVENT_RBUTTONDOWN:
cv2.rectangle(image, (x, y), (x+30, y+30), (0))
cv2.imshow(title, image)
image = np.full((500, 1000), (255), np.uint8)
title ="spown_window"
cv2.namedWindow(title)
cv2.setMouseCallback(title, action)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# 11. 트랙바를 이용해 선의 굵기와 원의 반지름을 1~10, 1~50으로 조절하는 기능을 추가하시오
import numpy as np, cv2
def action(event, x, y, flags, param):
thic = cv2.getTrackbarPos("thicth", title)
r = cv2.getTrackbarPos("circle_r", title)
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image, (x, y), r, (0), thic)
cv2.imshow(title, image)
if event == cv2.EVENT_RBUTTONDOWN:
cv2.rectangle(image, (x, y), (x+30, y+30), (0), thic)
cv2.imshow(title, image)
image = np.full((1000, 1000), (255), np.uint8)
title ="spown_window"
cv2.namedWindow(title)
cv2.createTrackbar("thicth", title, 1, 5, lambda x: None)
cv2.createTrackbar("circle_r", title, 20, 50, lambda x: None)
cv2.setMouseCallback(title, action)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# 12. 화살표 키로 트랙바를 이동하는 코드를 추가하시오
import numpy as np, cv2
def press(key):
thic = cv2.getTrackbarPos("thicth", title)
r = cv2.getTrackbarPos("circle_r", title)
if key == 0x260000: # 위 (두께 증가)
cv2.setTrackbarPos("thicth", title, thic + 1)
elif key == 0x280000: # 아래 (두께 감소)
cv2.setTrackbarPos("thicth", title, thic - 1)
elif key == 0x270000: # 오른쪽 (반지름 증가)
cv2.setTrackbarPos("circle_r", title, r + 1)
elif key == 0x250000: # 왼쪽 (반지름 감소)
cv2.setTrackbarPos("circle_r", title, r - 1)
def action(event, x, y, flags, param):
thic = cv2.getTrackbarPos("thicth", title)
r = cv2.getTrackbarPos("circle_r", title)
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image, (x, y), r, (0), thic)
elif event == cv2.EVENT_RBUTTONDOWN:
cv2.rectangle(image, (x, y), (x + 30, y + 30), (0), thic)
cv2.imshow(title, image)
image = np.full((1000, 1000), 255, np.uint8)
title = "spown_window"
cv2.namedWindow(title)
cv2.createTrackbar("thicth", title, 1, 10, lambda x: None)
cv2.createTrackbar("circle_r", title, 20, 100, lambda x: None)
cv2.setMouseCallback(title, action)
while True:
if cv2.getWindowProperty(title, cv2.WND_PROP_VISIBLE) < 1:
break
cv2.imshow(title, image)
key = cv2.waitKeyEx(1)
if key != -1:
press(key)
cv2.destroyAllWindows()
#
# 13. 컬러 영상파일을 적재하여 jpg와 png 파일로 각각 가장 좋은 화질로 압축하여 저장하시오
import cv2
video_path = 'smart_record.mp4'
cap = cv2.VideoCapture(video_path)
ret, frame = cap.read()
if ret:
cv2.imwrite('best_frame.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 100])
cv2.imwrite('best_frame.png', frame, [cv2.IMWRITE_PNG_COMPRESSION, 0])
else:
print("영상 파일을 읽을 수 없습니다.")
cap.release()
#
# 14. 마우스 중간버튼을 클릭하여 타원을 그리는 기능을 추가하시오
import numpy as np, cv2
def action(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image, (x, y), 20, (0))
cv2.imshow(title, image)
if event == cv2.EVENT_RBUTTONDOWN:
cv2.rectangle(image, (x, y), (x+30, y+30), (0))
cv2.imshow(title, image)
if event == cv2.EVENT_MBUTTONDOWN:
cv2.ellipse(image, (x, y), (30, 60), 30, 0, 360, 0, 1)
cv2.imshow(title, image)
image = np.full((1000, 1000), (255), np.uint8)
title ="spown_window"
cv2.namedWindow(title)
cv2.setMouseCallback(title, action)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
#
# 15. 트랙바로 카메라 영상의 밝기와 대비 변경하는 기능을 가진 영상 출력 코드를 작성하시오
import numpy as np, cv2
cap = cv2.VideoCapture(0)
title = "Brightness & Contrast"
cv2.namedWindow(title)
cv2.createTrackbar("Brightness", title, 100, 200, lambda x: None)
cv2.createTrackbar("Contrast", title, 10, 30, lambda x: None)
while cap.isOpened():
ret, frame = cap.read()
if not ret: break
br = cv2.getTrackbarPos("Brightness", title) - 100
ct = cv2.getTrackbarPos("Contrast", title) / 10.0
dst = frame.astype(np.float32) * ct + br
dst = np.clip(dst, 0, 255)
dst = dst.astype(np.uint8)
cv2.imshow(title, dst)
if cv2.waitKey(1) == 27: break # ESC 종료
cap.release()
cv2.destroyAllWindows()
#
# 16. PC카메라를 통해서 받아온 프레임에 (200, 100) 에서 100*200 크기의 관심 영역 지정, 녹색 성분을 50만큼 증가, 관심 영역의 테두리를 두께 3의 빨간색으로 표시하여 출력하는 코드를 작성하시오
import cv2
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
roi = frame[100:300, 200:300]
roi[:] = cv2.add(roi, (0, 50, 0))
cv2.rectangle(frame, (200, 100), (300, 300), (0, 0, 255), 3)
cv2.imshow("Camera ROI", frame)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
#
# 16. 카메라를 통해서 받아온 프레임을 좌우로 뒤집어서 동영상 파일로 저장하는 프로그램을 작성하시오
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter('manual_flip.avi', fourcc, 20.0, (width, height))
while cap.isOpened():
ret, frame = cap.read()
if not ret: break
flipped_frame = frame[:, ::-1, :]
out.write(flipped_frame)
cv2.imshow('Manual Flip', flipped_frame)
if cv2.waitKey(1) == 27: break
cap.release()
out.release()
cv2.destroyAllWindows()
#
# 17. 태극 문양을 그리는 프로그램을 작성하시오(화면비 3대 2, 태극의 반지름 = 높이의 4/1 )
import numpy as np, cv2
image = np.full((400, 600, 3), (255, 255, 255), np.uint8)
title ="flag"
cv2.namedWindow(title)
red, blue = (0, 0, 255), (255, 0, 0)
cv2.ellipse(image, (300, 200), (100, 100), 0, 0, -180, red, -1)
cv2.ellipse(image, (300, 200), (100, 100), 0, 0, +180, blue, -1)
cv2.ellipse(image, (250, 200), (50, 50), 0, 0, +180, red, -1)
cv2.ellipse(image, (350, 200), (50, 50), 0, 0, -180, blue, -1)
cv2.imshow(title, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# ex 1
'''
import cv2
import threading
import time
class WebCam:
def __init__(self):
self.cap = cv2.VideoCapture(0) # 기기 지정
self.ret, self.frame = False, None # 이미지의 유무와 이미지 데이터
self.capture_time = 0 # 이미지의 타임스탬프
self.running = True # 쓰레드 종료 플래그
threading.Thread(target=self.update, daemon=True).start() # 쓰레드 분할, 함수 호출 및 소멸조건 지정, 실행
def update(self): # 쓰레드 동작 함수
while self.running: # 플래그 연동 무한루프
self.ret, self.frame = self.cap.read() # 이미지 저장
self.capture_time = time.time() # 찍은 시각 기록
def get_data(self): # 메인 동작에 필요한 데이터 전달 함수
return self.ret, self.frame, self.capture_time
cam = WebCam() # 객체 할당
prev_update = 0 # 최신화 주기 설정을 위한 비교 변수
msg = "" # 지연시간 출력용 문자열 저장 변수
while True: # 메인 쓰레드
ret, frame, birth_time = cam.get_data() # 서브 쓰레드로부터 데이터 전달받음
if not ret or frame is None: continue # 서브 쓰레드에 데이터가 없을 경우 다음 루프로 스킵
total_latency = (time.time() - birth_time) * 1000 # 현재시간 - 이미지의 타임 스탬프
if time.time() - prev_update > 0.1: # 0.1초마다 실행
msg = f"Total Latency: {total_latency:.1f}ms" # 지연 시간 최신화
prev_update = time.time() # 비교 변수 값 초기화
cv2.putText(frame, msg, (50, 50), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0), 1) # 지연 시간(문자열) 이미지에 덮어씌우기
cv2.imshow('Real Latency', frame) # 이미지 출력
if cv2.waitKey(1) & 0xFF == ord('q'): break # 'q' 입력시 메인 쓰레드 종료
cam.running = False # 서브 쓰레드 종료
cv2.destroyAllWindows() # 창 삭제
'''
|
|

첫댓글 영상이 저장된 객체의 자료형은 무엇인가?
영상의 각 픽셀(R,G,B)이 어떤 순서로 저장되어 있는가?
영상을 저장할 때 cv2.VideoWriter() 를 사용할 경우 프레임 단위로 numpy.ndarray 타입의 데이터를 저장하여 cv2.VideoCapture타입의 객체에 연속적인 영상으로 저장합니다 이때 프레임에는 변화량 위주의 데이터가 저장되어 있습니다.
영상의 각 픽셀의 색은(B, G, R) 순으로 저장되고 최상단 좌측을 시작점으로 하여 우측 방향으로 순차 기록되며 한 줄이 완료되면 바로 아래 행으로 이동해 저장합니다.