import cv2
# 경로를 잘못 입력해도 오류가 나지 않는다. NoneType이라고 명시할 뿐 img = cv2.imread('YOUR IMAGE DIRECTION') # cv2를 사용하면 numpy배열로 바꾸어주는 작업이 한번에 진행됨 type(img)
💻 결과
numpy.ndarray
위의 함수를 사용하면 numpy배열로 바꾸어 주기 때문에 변환에 용이하다.
# matplotlib에서는 RGB순서로 읽는다. # 하지만 cv2에서는 BGR순서로 읽기때문에 색이 이상해짐 plt.imshow(img) fix_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(fix_img)
💻 결과
matplot을 사용하면 RGB순서대로 나오지만 cv2를 사용하면 BGR순서로 나오기 때문에 색을 바꾸어 주는 작업을 해주어야한다.
img_gray = cv2.imread('YOUR IMAGE DIRECTION', cv2.IMREAD_GRAYSCALE) img_gray.shape plt.imshow(img_gray, cmap='gray')
💻 결과
(1300, 1950)
위의 방법으로 불러오면 원래 채널이 3개라서 (1300, 1950, 3)의 형태로 나와야 하지만 1개의 채널로 나오게 된다.
또한 이미지를 출력할 때 Numpy 및 Image Basics에서 나타낸 것 처럼 cmap='gray'가 필수적으로 나와야 한다.
fix_img.shape # (1300, 1950, 3) # 1900 -> 1000, 1300 -> 400 new_img = cv2.resize(fix_img, (1000, 400)) plt.imshow(new_img)
💻 결과
(1300, 1950)의 크기인 이미지를 (400, 1000)의 크기로 바꾼다.
여기서 주의해야할 점이 함수를 사용할 때에는 행과 열의 위치가 반대이다.
w_ratio = 0.5 h_ratio = 0.5 new_img = cv2.resize(fix_img, (0, 0), fix_img, w_ratio, h_ratio) plt.imshow(new_img)
💻 결과
고정된 값으로만 크기를 바꿀수 있는 것이 아닌 비율로도 변환이 가능하다.
new_img = cv2.flip(fix_img, 0) # 상하로 반전 new_img = cv2.flip(fix_img, 1) # 좌우로 반전 new_img = cv2.flip(fix_img, -1) # 상하좌우 반전 plt.imshow(new_img)
💻 결과
또 이미지를 뒤집는 경우도 있다. flip 함수에 0을 넣으면 상하로 뒤집히고, 1을 넣으면 좌우, -1을 넣게 되면 상하좌우가 바뀌게 된다. 위의 결과는 마지막에 있는 -1이 들어가있는 함수가 실행 되기 때문에 상하좌우가 바뀐 이미지가 나왔다.
import cv2 img = cv2.imread('YOUR IMAGE DIRECTION') while True: cv2.imshow('Puppy', img) # 1ms를 기다리고 esc버튼을 눌렀다면 멈춤 if(cv2.waitKey(1) & 0xFF == 27): break cv2.destroyAllWindows()
새 창에서 이미지를 띄우는 방법으로 cv2.imshow함수는 첫 번째 인자가 제목이고 두 번째 인자는 띄울 이미지이다.
if문을 보면 cv2.waitKey(1)의 함수는 1ms만큼 기다리겠다는 의미이고 0xFF == 27의 의미는 ESC버튼을 누른다는 의미이다.
cv2.destroyAllWindows()의 함수는 현재 띄어진 화면들을 모두 없애는 함수이다.
위의 코드를 실행하게되면 ESC를 눌러야지 화면에 띄어진 이미지가 없어진다.
이렇게 새 창에서 이미지를 나타나게하면 이미지의 크기를 변경할순 없다.
- 도형을 그리는 작업을 해주는 이유는 나중에 이미지를 읽고 나서 객체의 위치를 나타낼 때 보통 직사각형안에 해당 객체를 표현하게 된다.
blank_img = np.zeros((512, 512, 3), dtype = np.int16) # 검은 이미지 생성 # pt1 : 왼쪽 위 # pt2 : 오른쪽 아래 # thickness : 몇 픽셀만큼 두께 cv2.rectangle(blank_img, pt1 = (384, 10), pt2 = (500, 150), color=(0, 255, 0), thickness=10) plt.imshow(blank_img)
💻 결과
Numpy 및 Image Basics에서 사용한 np.zeros함수를 사용해 검은 화면에 직사각형을 그린다.
cv2.rectangle의 함수는 이미지, 좌표 2개, 색, 굵기가 매개변수로 들어간다.
pt1의 좌표는 왼쪽 위, pt2의 좌표는 오른쪽 아래 이 두가지만 있으면 직사각형을 그릴 수 있다.
cv2.circle(blank_img, center=(100,100), radius=50, color=(0,0,255), thickness=8) plt.imshow(blank_img)
💻 결과
cv2.circle의 함수도 직사각형을 그릴 때와 별 차이점 없이 이미지, 좌표, 반지름, 색, 굵기가 매개변수로 들어가게 된다.
cv2.line(blank_img, pt1=(100,400), pt2=(500, 460), color=(255,255,255), thickness=5) plt.imshow(blank_img)
💻 결과
선을 그리는 함수도 이미지, 좌표 2개, 색, 굵기를 매개변수로 가진다.
cv2.circle(blank_img, center=(100,100), radius=50, color=(0,0,255), thickness=-1) plt.imshow(blank_img)
💻 결과
색이 채워진 도형을 그리기 위해선 선의 굵기를 나타내는 thickness부분에 -1을 넣으면 된다.
vertices = np.array([ [100,300], [200,200], [400,300], [200,400] ], dtype = np.int32) # 이미지는 대부분 3차원인데 현재 vertices의 차원은 2차원 이므로 늘려준다 pts = vertices.reshape((-1,1,2)) cv2.polylines(blank_img, [pts], isClosed=True, color=(0,0,255), thickness=5) plt.imshow(blank_img)
💻 결과
사용자 정의대로 도형을 나타내려면 일단 원하는 좌표를 만들어준다.
하지만 좌표가 들어있는 배열은 2차원이고 이미지는 3차원 이므로 좌표 배열의 차원을 바꾸어준다.
(-1, 1, 2)로 reshape를 해주면 배열이 (4, 2)에서 (4, 1, 2)으로 차원이 커지게 된다.
채워진 도형을 그리고 싶다면 cv2.fillPoly함수를 사용하면된다.
font = cv2.FONT_HERSHEY_SIMPLEX # org : 왼쪽 아래 좌표 # lineType : 선의 종류 cv2.putText(blank_img, text='Hello', org=(10,500), fontFace=font, fontScale=4, color=(255,255,255), thickness=3, lineType=cv2.LINE_AA) plt.imshow(blank_img)
💻 결과
이 경우는 인자로 이미지, 텍스트, 텍스트를 나타낼 좌표(왼쪽 아래), 폰트, 색, 굵기, 선 타입 등 많은 매개변수가 들어간다.
import cv2 import numpy as np ################ ### FUNCTION ### ################ def draw_circle(event, x, y, flags, param): """ 원을 그리는 함수 Args: event: 마우스의 클릭 이벤트 x: 마우스의 좌표 y: 마우스의 좌표 flags: 경고 플래그 필요한 경우 param: 추가 매개변수 있으면 사용 """ # 마우스 왼쪽 버튼 클릭 시 (누를 때) if(event==cv2.EVENT_LBUTTONDOWN): cv2.circle(img, (x,y), 50, (0,255,0), -1) elif(event==cv2.EVENT_RBUTTONDOWN): cv2.circle(img, (x,y), 30, (255,0,0), -1) # 같은 이름을 사용해서 서로 연결이 됨 cv2.namedWindow(winname='my_drawing') cv2.setMouseCallback('my_drawing', draw_circle) ################################## ### SHOWING IMAGE WITH OPEN CV ### ################################## img = np.zeros((512,512,3), np.int8) while True: cv2.imshow('my_drawing', img) if(cv2.waitKey(20) & 0xFF == 27): break cv2.destroyAllWindows()
💻 결과
초록색은 왼쪽 마우스를 클릭 했을 때이고, 파란색은 오른쪽 마우스를 클릭 했을 때 이다.
cv2.namedWindow(winname, flags)
winname: 창 구분자로 활용될 창 이름
flags: 창 옵션 (cv2.WINDOW_NORMAL: 사용자가 창 크기를 조정할 수 있음, cv2.WINDOW_AUTOSIZE: 이미지와 동일한 크기로 창 크기를 재조정할 수 없음)
cv2.setMouseCallback(windowName, onMouse, param=None) -> None
windowName: 마우스 이벤트 처리를 수행할 창 이름
onMouse: 마우스 이벤트 처리를 위한 콜백 함수 이름.
param: 콜백 함수에 전달할 데이터
출처 : cv2.namedWindow, cv2.setMouseCallback, OpenCV 및 딥러닝 을 이용한 Computer Vision 파이썬