[OpenCV] 03-1. Basic Operations on Images
🐍Python/OpenCV

[OpenCV] 03-1. Basic Operations on Images

728x90
반응형

<3-1. Basic Operations on Images>

  • 픽셀 값에 접근 및 수정
  • 이미지 특성에 접근
  • ROI를 세팅한다.(Region of Image)
  • 이미지를 합치고 나눈다.

이번 섹션에서는 OpenCV보다는 Numpy가 더 주로 사용된다. OpenCV로 더 잘 최적화된 코드를 작성하려면 Numpy에 대한 충분한 지식이 필요하다.

Accessing and Modifying pixel values

먼저 컬러 이미지를 불러오자.

import cv2
import numpy as np

img = cv2.imread('soccer.jpg')

행과 열 좌표로 픽셀 값에 접근할 수 있다. BGR 이미지의 경우, 파랑 초록 빨강 값의 array를 출력한다. 흑백 이미지의 경우, 그냥 강도에 대응하여 출력된다.

px = img[100,100]
print(px)
## [50,64,62]

# 파란 픽셀에만 접근
blue = img[100,100,0]
print(blue)
## 50

같은 방법으로 픽셀을 수정할 수도 있다.

img[100,100] = [255,255,255]
print(img[100,100])
## [255,255,255]

Numpy array 방법으로, array.item() 이나 array.itemset()이 더 나을 것이다. 하지만 항상 scalar 값을 출력한다. 그러니 BGR 값에 접근하고 싶다면, array.item()으로 전부에 대해 각각 불러야한다.

# 빨간색 값에 접근
img.item(10,10,2)

# 빨간색 값 수정
img.itemset((10,10,2),100)
img.item(10,10,2)

처음에 24였다가 100으로 수정해 준 것이다.

Accessing Image Properties

이미지 특성에는 행,열,채널, 이미지 데이터의 타입, 픽셀의 수 등이 포함되어 있다.

이미지의 shape은 img.shape를 통해 접근 가능하다.

img.shape
# (342,548,3)

이미지 데이터타입은 img.dtype으로 확인한다.

img.dtype
# dtype('uint8')

Image ROI

가끔, 이미지의 한 영역에 대해서 갖고 놀아야 할 것 이다. 이미지에서 눈을 감지하려면 먼저 얼굴이 발견될 때까지 영상에서 얼굴 감지를 수행한 다음 얼굴 영역 내에서 눈을 검색하는 것이다. 이 접근법은 정확성을 향상시킨다. (왜냐면 눈은 항상 얼굴에 있기 때문이다 :D)

Numpy 인덱싱을 이용해서 ROI를 다시 얻는다.

원본이미지는 다음과 같다.


여기서 공을 추출해서, 머리 옆에 갖다 놓을 것 이다.

ball = img[:,:,::-1][370:430,350:420]
plt.imshow(ball)
plt.show()


# 머리 옆부분을 추출하여 공으로 바꾼다. 
img[:,:,::-1][50:110,350:420] = ball
plt.imshow(img[:,:,::-1])
plt.show()

중요한 것은 [세로축 : 가로축] 이고, 잘라낸 사이즈와 똑같은 크기의 공간을 골라서 바꿔야한다.


Splitting and Merging Image Channels

이미지의 B,G,R 채널은 각각의 공간으로 쪼개질 수 있다. 그리고는 다시 BGR 채널로 합쳐질 수도 있다.

b,g,r = cv2.split(img)
img = cv2.merge((b,g,r))
# Or
# 채널에서 0번째 (BGR -> B)
b = img[:,:,0]
# Blue를 0으로 만들고 싶다면
b = img[:,:,0] = 0

cv2.split()은 시간적인 측면에서 비용이 많이 든다. 그러니 필요할 때만 사용하는 것이 좋다.


Making Borders for Images (Padding)

사진 액자처럼, 이미지 주변에 경계를 만들고 싶다면 cv2.copyMakeBorder() 함수를 사용하면 된다. 하지만 이는 convolution 기능, zero-padding 등을 위한 기능을 가지고 있다. arguments는 다음과 같다.

  • src : 입력 이미지
  • top,bottom,left,right : 해당 방향의 픽셀 수에서 테두리
  • borderType : flag에 따라 어떤 테두리가 더해질지 정해진다.
    • cv2.BORDER_CONSTANT - 연속된 컬러 테두리를 더한다. 값은 다음 argument에서 주어진다.
    • cv2.BORDER_REFLECT - 테두리는 경계 값에 반사된 값으로 구성된다.
    • cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT : 조금의 변화만 있고 위와 같이 변한다.
    • cv2.BORDER_REPLICATE - 마지막 원소가 복제 된다. 11111 | 123 | 33333
    • cv2.BORDER_WRAP - 설명하기 힘들고 보면 된다.
  • value : 테두리의 색 (만약 테두리 타입이 cv2.BORDER_CONSTANT일 때)

아래 코드는 위의 테두리 타입들을 이해하기 쉽게 보여준다.


plt.figure(figsize=(9,6))
plt.subplot(231), plt.imshow(img[:,:,::-1]), plt.title('Original')
plt.subplot(232), plt.imshow(replicate[:,:,::-1]), plt.title('Replicate')
plt.subplot(233), plt.imshow(reflect[:,:,::-1]), plt.title('Reflect')
plt.subplot(234), plt.imshow(reflect101[:,:,::-1]), plt.title('Reflect_101')
plt.subplot(235), plt.imshow(wrap[:,:,::-1]), plt.title('Wrap')
plt.subplot(236), plt.imshow(constant[:,:,::-1]), plt.title('Constant')
plt.show()


728x90
반응형