와챠의 우당탕탕 개발 기록장

[OpenCV-Python] 4장 연습문제 8 ~ 18번 본문

이런 저런 공부

[OpenCV-Python] 4장 연습문제 8 ~ 18번

minWachya 2021. 3. 28. 22:14
반응형

8번

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

import numpy as np, cv2
img1 = np.full((200, 300), 100, np.uint8)
img2 = np.full((200, 300), 100, np.uint8)
title1, title2 = 'win_mode1', 'win_mode2'
w, h = img1.shape
cv2.imshow(title1, img1)
cv2.imshow(title2, img2)
cv2.moveWindow(title1, 0, 0)
cv2.moveWindow(title2, h, w)
cv2.waitKey(0)
cv2.destroyAllWindows()
view raw test.py hosted with ❤ by GitHub

9번

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

import numpy as np, cv2
# 600행, 400열의 윈도우를 만들고(3채널 흰 영상)
img = np.full((600, 400, 3), (255, 255, 255), np.uint8)
title = 'test'
# 영상의 (100, 100) 좌표에 200x300 크기의 빨간색 사각형을 그리시오
pt1, pt2 = (100, 100), (300, 400)
red = (0, 0, 255)
cv2.rectangle(img, pt1, pt2, red, -1)
cv2.imshow(title, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
view raw test.py hosted with ❤ by GitHub

10번

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

  • 마우스 오른쪽 버튼 클릭 시 원(클릭 좌표에서 반지름 20화소)을 그린다.
  • 마우스 왼쪽 버튼 클릭 시 사각형(크기 30*30)을 그린다.
import numpy as np, cv2
def onMouse(event, x, y, flags, param):
global title
# 마우스 오른쪽 버튼 클릭 시
if event == cv2.EVENT_RBUTTONDOWN:
# 클릭 좌표에서 반지름이 20인 원 그리기
cv2.circle(img, (x, y), 20, (0, 0, 255), 2) # 두께가 2인 빨간 원
# 마우스 왼쪽 버튼 클릭 시
elif event == cv2.EVENT_LBUTTONDOWN:
# 크기 30x30인 사각형 그리기
cv2.rectangle(img, (x, y), (x+30, y+30), (255, 0, 0), 2) # 두께가 2인 파란 사각형
cv2.imshow(title, img)
img = np.full((400, 300, 3), (255, 255, 255), np.uint8)
title = 'test'
cv2.imshow(title, img)
cv2.setMouseCallback(title, onMouse)
cv2.waitKey(0)
cv2.destroyAllWindows()
view raw test.py hosted with ❤ by GitHub

11번

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

  • 트랙바를 추가해서 선의 굵기를 1~10 픽셀로 조절한다.
  • 트랙바를 추가해서 원의 반지름을 1~50 픽셀로 조절한다.
import numpy as np, cv2
def onMouse(event, x, y, flags, param):
global title, line, radius
# 마우스 오른쪽 버튼 클릭 시
if event == cv2.EVENT_RBUTTONDOWN:
# 클릭 좌표에서 반지름이 radius인 원 그리기
cv2.circle(img, (x, y), radius, (0, 0, 255), line) # 두께가 line인 빨간 원
# 마우스 왼쪽 버튼 클릭 시
elif event == cv2.EVENT_LBUTTONDOWN:
# 크기 30x30인 사각형 그리기
cv2.rectangle(img, (x, y), (x+30, y+30), (255, 0, 0), line) # 두께가 line인 파란 사각형
cv2.imshow(title, img)
def line_bar(value):
global line
line = value
def radius_bar(value):
global radius
radius = value
title = 'test'
img = np.full((400, 300, 3), (255, 255, 255), np.uint8)
cv2.imshow(title, img)
line = 2 # 기본 선 굵기는 2
radius = 20 # 기본 반지름은 20
# 선 굵기 설정 트랙바 생성
cv2.createTrackbar('line', title, 2, 10, line_bar)
cv2.setTrackbarMin('line', title, 1) # 최솟값 설정
# 반지름 설정 트랙바 생성
cv2.createTrackbar('radius', title, 20, 50, radius_bar)
cv2.setTrackbarMin('radius', title, 1)
cv2.setMouseCallback(title, onMouse)
cv2.waitKey(0)
view raw test.py hosted with ❤ by GitHub

12번

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

import numpy as np
import cv2
def onChange(value): # 트랙바 콜백 함수
global image, title # 전역 변수 참조
#add_value = value - int(image[0][0]) # 트랙바 값과 영상 화소값 차분
#print("추가 화소값:", add_value)
#image = image + add_value # 행렬과 스칼라 덧셈 수행
image[:] = cv2.getTrackbarPos('Brightness', title) # 바뀐 값으로 바로 화면 색 변경되도록 수정...
cv2.imshow(title, image)
image = np.zeros((300, 500), np.uint8) # 영상 생성
title = 'Trackbar Event'
cv2.imshow(title, image)
cv2.createTrackbar('Brightness', title, image[0][0], 255, onChange) # 트랙바 콜백 함수 등록
while True:
key = cv2.waitKeyEx(100) # 100ms동안 키 이벤트 대기
if key == 27: break # esc 키 누르면 종료
# 왼쪽< 화살표 키 입력
if key == 2424832:
value = cv2.getTrackbarPos('Brightness', title)
cv2.setTrackbarPos('Brightness', title, value - 1)
# 오른쪽> 화살표키 입력
elif key == 2555904:
value = cv2.getTrackbarPos('Brightness', title)
cv2.setTrackbarPos('Brightness', title, value + 1)
image[:] = cv2.getTrackbarPos('Brightness', title) # 바뀐 값으로 바로 화면 색 변경되도록 수정...
cv2.imshow(title, image)
cv2.destroyAllWindows()
view raw test.py hosted with ❤ by GitHub

13번

컬러 영상 파일을 적재한 후의 행렬을 윈도우에 명암도 영상으로 표시하고, "test.jpg"와 "test.png" 파일로 각각 저장하시오(나는 이름 다르게 설정함). 이때 영상 파일을 가장 좋은 화질로 압축하시오.

import cv2
# 컬러 영상 파일을 적재한 후
image = cv2.imread("images/colorJ.jpg", cv2.IMREAD_GRAYSCALE)
if image is None :
raise Exception("영상 파일 읽기 에러")
# 행렬을 윈도우에 명암도 영상으로 표시하고
cv2.imshow('test', image)
# "testJ.jpg"와 "testJ.png" 피일로 각각 저장하시오.
# 이때, 영상 파일을 가장 좋은 화질로 압축하시오.
cv2.imwrite("images/testJ.jpg", image, (cv2.IMWRITE_JPEG_QUALITY, 100))
cv2.imwrite("images/testJ.png", image, (cv2.IMWRITE_PNG_COMPRESSION, 9))
cv2.waitKey(0)
view raw test.py hosted with ❤ by GitHub

14번

심화예제 4.3.5인 11.event_draw.py를 수정해서 마우스 중간 버튼을 클릭하여 타원을 그리시오.

import numpy as np
import cv2
def onMouse(event, x, y, flags, param):
global title, pt # 전역 변수 참조
# 마우스 왼쪽 버튼 누르면 파란 사각형 그리기
if event == cv2.EVENT_LBUTTONDOWN:
if pt[0] < 0: # 한 번 클릭
pt = (x, y) # 시작 좌표 지정
cv2.circle(image, pt, 1, 0, 2) # 클릭한 점1 표시
else: # 두 번 클릭
cv2.rectangle(image, pt, (x, y), (255, 0, 0), 2)
pt = (-1, -1) # 시작 좌표 초기화
# 마우스 오른쪽 버튼 누르면 빨간 사각형 그리기
elif event == cv2.EVENT_RBUTTONDOWN:
if pt[0] < 0: # 한 번 클릭
pt = (x, y)
cv2.circle(image, pt, 1, 0, 2) # 클릭한 점1 표시
else: # 두 번 클릭
dx, dy = pt[0] - x, pt[1] - y # 두 좌표 간의 거리
radius = int(np.sqrt(dx * dx + dy * dy))
cv2.circle(image, pt, radius, (0, 0, 255), 2)
pt = (-1, -1) # 시작 좌표 초기화
# 마우스 중간 버튼 누르면 초록 타원 그리기
elif flags == cv2.EVENT_FLAG_MBUTTON:
if pt[0] < 0: # 한 번 클릭
pt = (x, y)
cv2.circle(image, pt, 1, 0, 2) # 클릭한 점1 표시
else: # 두 번 클릭
dx, dy = pt[0] - x, pt[1] - y # 두 좌표 간의 거리
radius = int(np.sqrt(dx * dx + dy * dy))
cv2.ellipse(image, pt, (100, radius), 0, 0, 360, (0, 255, 0), 2)
pt = (-1, -1) # 시작 좌표 초기화
cv2.imshow(title, image)
image = np.full((300, 500, 3), (255, 255, 255), np.uint8) # 흰색 배경 영상
pt = (-1, -1) # 시작 좌표 초기화
title = "Draw Event"
cv2.imshow(title, image) # 윈도우에 영상 띄우기
cv2.setMouseCallback(title, onMouse) # 마우스 콜백 함수 등록
cv2.waitKey(0)
view raw test.py hosted with ❤ by GitHub

15번

심화예제 4.5.2인 18.set_camera_attr.py를 수정해서 트랙바로 카메라 영상의 밝기와 대비 변경할 수 있도록 수정하시오.

import cv2
from Common.utils import put_string
def bright_bar(value): # 밝기 조절
global capture
capture.set(cv2.CAP_PROP_BRIGHTNESS, value) # 줌 설정
def cont_bar(value): # 대비 조절
global capture
capture.set(cv2.CAP_PROP_CONTRAST, value)
capture = cv2.VideoCapture(0) # 0번 카메라 연결
if capture.isOpened() is None: raise Exception("카메라 연결 안됨")
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 400) # 카메라 프레임 너비
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 300) # 카메라 프레임 높이
capture.set(cv2.CAP_PROP_AUTOFOCUS, 0) # 오토포커싱 중지
capture.set(cv2.CAP_PROP_BRIGHTNESS, 0) # 프레임 밝기 초기화
title = "test"
cv2.namedWindow(title) # 윈도우 생성 - 반드시 생성 해야함
cv2.createTrackbar("brightness", title, 0, 100, bright_bar)
cv2.createTrackbar("contrast", title, 0, 100, cont_bar)
while True:
ret, frame = capture.read() # 카메라 영상 받기
if not ret: break
if cv2.waitKey(100) == 27: break # esc 누르면 종료
bright = int(capture.get(cv2.CAP_PROP_BRIGHTNESS)) # 밝기
cont = int(capture.get(cv2.CAP_PROP_CONTRAST)) # 대비
put_string(frame, "brightness : ", (10, 240), bright) # 영상 밝기 표시
put_string(frame, "contrast : ", (10, 270), cont) # 영상 대비 표시
cv2.imshow(title, frame)
capture.release()
view raw test.py hosted with ❤ by GitHub

16번

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

  • (200, 100) 좌표에서 100x200크기의 관심 영역 지정
  • 관심 영역에서 녹색 성분을 50만큼 증가
  • 관심 영역의 테두리를 두깨 3의 빨간색으로 표시
import cv2
capture = cv2.VideoCapture(0) # 0번 카메라 연결
if capture.isOpened() is None: raise Exception("카메라 연결 안 됨")
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 400) # 카메라 프레임 너비
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 300) # 카메라 프레임 높이
capture.set(cv2.CAP_PROP_AUTOFOCUS, 0) # 오토포커싱 중지
capture.set(cv2.CAP_PROP_BRIGHTNESS, 0) # 프레임 밝기 초기화
title = "test"
cv2.namedWindow(title)
while True:
ret, frame = capture.read() # 카메라 영상 받기
if not ret: break
if cv2.waitKey(100) == 27: break # esc 누르면 종료
blue, green, red = cv2.split(frame) # 컬러 영상 채널 분리
# 1) (200, 100)죄표에서 100x200 크기의 관심 영역 지정
# 2) 관심 영역에서 녹색 성분읠 50만큼 증가
cv2.add(green[100:300, 200:300], 50, green[100:300, 200:300])
frame = cv2.merge([blue, green, red]) # 단일 채널 영상 합성
# 3) 관심 영역 테두리를 두께 3의 빨간 색으로 표시
cv2.rectangle(frame, (200, 100), (300, 300), (0, 0, 255), 2)
cv2.imshow(title, frame)
capture.release()
view raw test.py hosted with ❤ by GitHub

17번

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

  • 동영상 파일의 크기 (640x480)
  • 초당 프레임 수 15fps
  • 동영상 코덱 DIVX
import cv2
capture = cv2.VideoCapture(0) # 0번 카메라 연결
if capture.isOpened() is None: raise Exception("카메라 연결 안 됨")
title = "test"
cv2.namedWindow(title)
# 동영상 파일 개발 및 코덱, 해상도 설정
size = (640, 480) # 동영상 파일 크기 640x480
fps = 15.0 # 초당 프레임 수 15 fps
fourcc = cv2.VideoWriter_fourcc(*'DIVX') # 동영상 코덱 DIVX
writer = cv2.VideoWriter("images/flip_test.avi", fourcc, fps, size)
if writer.isOpened() == False: raise Exception("동영상 파일 개방 안 됨")
capture.set(cv2.CAP_PROP_FRAME_WIDTH, size[0]) # 카메라 프레임 너비
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, size[1]) # 카메라 프레임 높이
capture.set(cv2.CAP_PROP_AUTOFOCUS, 0) # 오토포커싱 중지
capture.set(cv2.CAP_PROP_BRIGHTNESS, 100) # 프레임 밝기 초기화
while True:
ret, frame = capture.read() # 카메라 영상 받기
if not ret: break
if cv2.waitKey(100) == 27: break # esc 누르면 종료
frame = cv2.flip(frame, 1) # 프레임 반전. 1: 좌우 반전, 0: 상하 반전
writer.write(frame) # 프레임을 동영상으로 저장
cv2.imshow(title, frame)
writer.release()
capture.release()
view raw test.py hosted with ❤ by GitHub

 

18번

다음과 같이 태극 문양을 그리는 프로그램을 작성하시오.

힌트

  • 태극은 반원이 4개 필요하다.
  • 반원은 타원 그리기 함수로 그릴 수 있다.
  • 영상의 너비와 높이는 3대 2 비율이며, 태극의 반지름은 높이의 1/4이다.
import numpy as np, cv2
# 흰 배경 3채널 영상 생성
image = np.full((400, 600, 3), (255, 255, 255), np.uint8)
# 색 지정
red, blue = (0, 0, 255), (255, 0, 0)
# 큰 반원의 설정
pt1 = (int(image.shape[1]/2), int(image.shape[0]/2)) # 원의 중심
size1 = (int(image.shape[1]/8), int(image.shape[1]/8)) # 반지름은 높이의 1/4 (image.shape[1]/4 * 1/2)
# 빨간 큰 반원 그리기
cv2.ellipse(image, pt1, size1, 0, 0, -180, red, -1)
# 파란 큰 반원 그리기
cv2.ellipse(image, pt1, size1, 0, 0, 180, blue, -1)
# 빨간 작은 반원의 설정
pt2 = (int(image.shape[1]/2) - int(size1[1]/2), int(image.shape[0]/2)) # 원의 중심
size2 = (int(image.shape[1]/16), int(image.shape[1]/16)) # 큰 원의 반지름의 반
# 빨간 작은 반원 그리기
cv2.ellipse(image, pt2, size2, 0, 0, 180, red, -1)
# 파란 작은 반원의 설정
pt3 = (int(image.shape[1]/2) + int(size1[1]/2), int(image.shape[0]/2)) # 원의 중심
# 파란 작은 반원 그리기
cv2.ellipse(image, pt3, size2, 0, 0, -180, blue, -1)
cv2.imshow('test', image)
cv2.waitKey(0)
view raw test.py hosted with ❤ by GitHub
반응형
Comments