이번에는 앞시간에 했던 것을 응용해서 간단한 영상을 생성해보겠습니다.
opencv 의 영상 타입들은 모두 numpy.ndarray 라고 했습니다.
그리고 dtype 이 uint8 이므로 2^8 이니깐 그 범위는 0~255 라고 설명한 바 있습니다.
1) 영상 생성
그러면 이를 토대로 numpy array를 그리고 2차원, 3차원에 범위 안의 값들을 넣으면 영상(=이미지)을 생성할 수 있습니다.
5개의 이미지를 그려봤습니다.
아래 이미지 중에서 2차원과 3차원 구별이 가시나요?
자, 위 영상들을 생성하는 코드들입니다.
import numpy as np
import cv2
img1 = np.empty((160, 280), dtype=np.uint8) # grayscale
img2 = np.zeros((160, 280, 3), dtype=np.uint8) # 컬러 영상 & zeros 이므로 0 이어서 검정색
img3 = np.ones((160, 280), dtype=np.uint8) * 255 # white (1 에 255 를 곱해서 모든 원소가 255)
img4 = np.full((160, 280, 3), (0, 255, 255), dtype=np.uint8) # yellow
img5 = np. full((160, 280), 128, dtype=np.uint8) # grayscale & gray 색상
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.imshow('img4', img4)
cv2.imshow('img5', img5)
cv2.moveWindow('img1', 200, 200)
cv2.moveWindow('img2', 650, 200)
cv2.moveWindow('img3', 1100, 200)
cv2.moveWindow('img4', 200, 500)
cv2.moveWindow('img5', 650, 500)
cv2.waitKey()
cv2.destroyAllWindows()
위 numpy array 들은 기초적이여서 설명은 하지 않겠습니다.
참고에 넣은 링크에 가시면 예제가 잘 나와있으니 이를 참고해주세요.
2) 부분 영상 추출
이번에는 슬라이싱을 이용해서 일부 픽셀의 색상을 바꿔보고 또 추출까지 해보겠습니다.
우선 결과는 아래와 같습니다.
코드를 보겠습니다.
img1 의 가로 세로 일부를 슬라이싱하였고 이의 값들을 0으로 채웠습니다.(=검은색으로 변합니다)
img3은 검은색 픽셀로 바꾸기 전 값들입니다.
import cv2
img1 = cv2.imread('apple.jpg', cv2.IMREAD_COLOR)
print(img1.shape)
img2 = img1[50:100, 50:100] # 가로, 세로 50 ~ 100 을 복사
img3 = img1[50:100, 50:100].copy() # 가로, 세로 50 ~ 100 을 복사
img2.fill(0) # img2 를 검정색으로 변경
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.moveWindow('img1', 200, 200)
cv2.moveWindow('img2', 650, 200)
cv2.moveWindow('img3', 1100, 200)
cv2.waitKey()
cv2.destroyAllWindows()
여기서 잠깐!!!!
img2를 바꿨는데 왜 img1까지 해당 픽셀들이 값이 변했지? 라고 생각하시는 분이 있을 것 같아서
위 코드에서 파이썬 특징을 잠시 설명 하겠습니다.
파이썬은 기본적으로 변수를 다시 재할당하면 id 가 같습니다.
img2 = img1
과 같은 할당을 말합니다.
즉, 같은 레퍼런스를 참조하기에 img2의 적용사항이 img1 에도 적용됩니다.
그럼 img3은?
.copy() 메서드를 사용했습니다.
파이썬은 copy 메서드를 사용하면 deep copy 가 되서 value 는 같고, id 는 다르게 복사를 해줍니다.
이는 '얕은 복사' 와 '깊은 복사'라는 파이썬의 중요한 개념 중 하나입니다.
opencv 를 공부하시는 분들이라면 이정도는 알고 있을 거라 생각하지만 100명 중 한 두명은 이를 모르거나 까먹었을 수도 있으니 이를 잠시 설명하고자 했습니다. TMI 인가요? ㅎㅎ
3) 그리기 함수
opencv 는 직선이나 도형을 그리는 함수를 제공합니다.
간단하게 한 번 그려보겠습니다.
3-1) np.full 을 이용해서 3차원 shape 의 흰색 도화지를 그린 다음 line 함수로 선을 그어보겠습니다.
먼저 결과를 보겠습니다.
흰 도화지에 빨간 선을 하나 그어보았습니다.
위 결과의 코드 전문입니다.
import cv2
import numpy as np
# 도화지 만들기
img = np.full((480, 640, 3), (255, 255, 255), dtype=np.uint8)
# 직선 그리기
cv2.line(img, (50, 50), (500, 50), (255, 0, 0))
cv2.line(img, (50, 50), (50, 500), (255, 150, 0))
cv2.line(img, (100, 100), (300, 300), (0, 0, 255), 10)
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
Parameter | 내용 |
img | 이미지파일 |
pt1 | 시작점 좌표 |
pt2 | 종료점 좌표 |
color | 색상 (BGR) 0~255 |
Tthickness | 선 두께(default=1) |
line type | 선 종류 (default cv.Line_8) -LINE_8 : 8-connected line -LINE_4 : 4-connected line -LINE_AA : antialiased line |
shift | fractional bit (default 0 ) |
위 코드를 설명하자면 3개의 라인을 그렸습니다.
맨 아래 라인은 두께가 10이고 BGR 의 R(red) 값만 max 255 로 주었기에 빨간색입니다.
첫 번째 선은 수평으로 그어진 선입니다. BGR 의 B(blue) 값만 max 255 이기에 파란색입니다.
수직으로 그어진 두 번째 선은 약간 하늘색으로 보입니다.
그럼 다음으로 사각형 2개를 그려보겠습니다.
파란색 사각형과 초록색 사각형입니다.
import cv2
import numpy as np
# 도화지 만들기
img = np.full((480, 640, 3), (255, 255, 255), dtype=np.uint8)
cv2.rectangle(img, (150, 150), (400, 500), (0, 255, 0), 5) # 녹색
cv2.rectangle(img, (50, 50), (300, 400), (255, 0, 0)) # 파란색
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
rectangle 함수도 line 함수와 인자의 순서가 유사합니다. (녹색 사각형이 세로가 길어서 짤리네요 ㅎㅎ 알아서 조절해주세요!)
cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
cv2.rectangle(img, rec, color, thickness=None, lineType=None, shift=None)
rec 와 pt1,pt2 가 헷갈릴 수 있는데요. pt1,pt2 로 인자를 넣으면 사각형의 왼쪽끝, 오른쪽 끝입니다.
rec: 사각형 위치 (x,y,w,h) - 튜플
그외의 인자들은 line가 동일하니 설명을 생략하겠습니다 :)
cv2.circle(img, center, radius, color, thickness=None, lineType=None, shift=None)
원을 그리는 함수입니다.
center: 원의 중심 좌표이며 (x,y)- 튜플 형태로 넣습니다.
radius : 원의 반지름입니다. 나머지는 앞의 메서드들과 동일한 의미입니다.
원과 사각형을 그려보겠습니다.
import cv2
import numpy as np
# 도화지 만들기
img = np.full((480, 640, 3), (255, 255, 255), dtype=np.uint8)
cv2.circle(img, (200, 200), 100, (0, 0, 255))
cv2.rectangle(img, (150, 150), (400, 400), (0, 255, 0), 5) # 녹색
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
다각형 그리기
cv2.polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
입력 이미지에 입력 받은 꼭지점을 연결해서 다각형을 그려주는 메서드입니다.
pts : 꼭지점 (x,y)
isClosed: 폐곡선 여부 True/False
import cv2
import numpy as np
# 도화지 만들기
img = np.full((480, 640, 3), (255, 255, 255), dtype=np.uint8)
pts1 = np.array([[50, 50], [150, 150], [100, 140], [200, 240]], dtype=np.int32)
pts2 = np.array([[150, 300], [50, 450], [250, 450]], dtype=np.int32)
# true 일떄와 차이 비교해보기
cv2.polylines(img, [pts1], False, (255, 0, 0), 3)
# true로 해야 점들을 다 이어줘서 삼각형이 됩니다.
cv2.polylines(img, [pts2], True, (0, 0, 255), 3)
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
isClosed 의 true false 여부가 시작점과 끝점을 이어줄지 말지의 옵션입니다.
이상 opencv 로 도형그리기를 마치겠습니다 :)
** 참고 **
https://yeowool0217.tistory.com/473
https://copycoding.tistory.com/145
'머신러닝,딥러닝 > opencv' 카테고리의 다른 글
opencv 입문하기 6편 트랙바, 산술 연산 (0) | 2020.07.26 |
---|---|
opencv 입문하기 5편 마우스 이벤트(2) (0) | 2020.07.26 |
opencv 입문하기 4편 키보드, 마우스 이벤트(1) (0) | 2020.07.25 |
opencv 입문하기 2편 - 이미지 객체 속성 , 픽셀값 변경 (0) | 2020.07.20 |
opencv 입문하기 1편 - 이미지 reading (0) | 2020.07.20 |