[openCV] Numpy Array
openCV

[openCV] Numpy Array

저번주에 작성했던 

2021/01/02 - [Nefus] - openCV - 기초부터 다지기에 이어서

오늘은 Numy Array가 openCV에서 어떻게 활용되는지에 대해서 정리를 해볼려고 한다.

 

우선 어떻게 활용되는지 알아보기 전에 Numpy Array가 뭔지

알아야하지 않겠는가? 🤔

 

Nump Array이란?

 

Numpy는 과학 계산을 위한 라이브러리로 만들어졌다.

다차원 배열을 처리하는데 필요한 여러 유용한 기능을 제공한다.

 

 

openCV에서 Image는 사용하는 언어에 따라 다른 Object에 저장이 된다.

 

 

C++의 경우는 Mat Class Type의 객체가 저장이 된다.

Python의 경우에서는 Numpy Array에 저장이 된다.

 

RelationShip between Numpy And Image

나는 Python으로 openCV를 공부하는 입장이므로 Numpy 활용법에

대해 공부를 하려 한다.😴

 

1. Using_Numpy

import cv2

img_gray = cv2.imread("Image_Sample.jpg", cv2.IMREAD_GRAYSCALE)

#Substitute

img_copyed1 = img_gray

#Equal
print(id(img_gray), id(img_copyed1))

#Draw Line
cv2.line(img_gray, (0, 0), (100, 100), 0, 10)

#Making Binary
ret, img_copyed1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)

print(id(img_gray), id(img_copyed1))


while True:
    cv2.imshow("Img_Gray", img_gray)
    cv2.imshow("Img_Copyed", img_copyed1)
    cv2.waitKey(0)

cv2.destroyAllWindows()

위 예제는 openCV에서 Numpy가 어떻게 활용되는지 아주 기본적인 예제이다.

 

우선 img_gray 변수에 GratScale로 변환된 사진을 넣어주고

' = '를 활용하여 img_copyed1에 대입해준다.

 

이로써 2개의 변수가 같은 Numpy Array를 가르치게 된거다.

 

그 후 cv2.line Function을 이용하여서 선을 그리게 된다면

현재 img_gray와 img_copyed1이 똑같은 넘파이 배열을 가지고 있으므로

두 사진 위에 똑같은 선이 그려지게 된다.

 

하지만 cv2.threshold 함수를 이용해서 Binary화를 해준다면

서로 다른 Numpy Array를 가르킬 수 있다.

 

왜냐하면 openCV Function 적용 전후의 Numpy Array가 달라지기 때문이다. 👏

 

[ Result ]

 

Original Image [ img_gray ]

 

Copyed Image [ img_copyed1 ]

 

 

2. Numpy_With_ROI

import cv2

img_gray = cv2.imread('Image_Sample.jpg', cv2.IMREAD_GRAYSCALE)

# [start_y : end_y, start_x, end_x] -> ROI
img_sub1 = img_gray[20:20+170, 20:20+170]

#Equal
print(img_sub1.base is img_gray)

cv2.line(img_sub1, (0,0 ), (100,100), 0, 10)

ret, img_sub1 = cv2.threshold(img_sub1, 127, 255, cv2.THRESH_BINARY)

#Not Equal
print(img_sub1.base is img_gray)

cv2.imshow("Img_Gray", img_gray)
cv2.imshow("Img_Sub1", img_sub1)

cv2.waitKey(0)
cv2.destroyAllWindows()

이 코드는 Numpy Array에서 ROI Region을 어떻게 공유하는지에 대해

이해할 수 있는 코드이다.

 

[ ROI란? : Region Of Interest의 약자로 사용자 관심구역을 의미한다. ]

 

 

전 코드와 다를것없이 img_gray에 Image를 GRAYSCALE로 대입해준다.

 

그 후 img_sub1에 img_gray의 ROI를 추출하여 대입해준다.

 

여기서도 두 변수가 똑같은 Numpy Array를 가르키게된다.

 

하지만 이진화를 해준다면 다른 Numpy Array를 가르키게 될거다.

 

위 코드와 크게 다를 바 없다.

 

[ Result ]

Original Image [ img_gray ]
ROI [ img_sub1 ]

 

3. Copy_To_Numpy_Array

 

import cv2

img_gray = cv2.imread("Image_Sample.jpg", cv2.IMREAD_GRAYSCALE)

# Numpy Copy
img_copyed1 = img_gray.copy()

#Not Equal
print(id(img_copyed1), id(img_gray))

cv2.line(img_gray, (0,0), (100,100), 0, 10)

ret, img_copyed1 = cv2.threshold(img_copyed1, 127, 255, cv2.THRESH_BINARY)

#Not Equal
print(id(img_gray), id(img_copyed1))

cv2.imshow("Img_Gray", img_gray)
cv2.imshow("Img_Copyed", img_copyed1)

cv2.waitKey(0)
cv2.destroyAllWindows()

이 코드는 Numpy Array를 복사하는 방법이다

 

위에서도 말했든 Python으로 openCV를 개발할때 Image를 저장할때

Numpy Array를 사용한다.

 

그래서 우리는 이미지를 복사할때는 copy Method를 사용한다.

 

copy Method와  ' = '(대입 연산자) 의 차이점은

' = '는 같은 Numpy Array를 가르키는 반면에

copy Method를 이용하면 다른 Numpy Array를 지니게 된다. 👀

 

그 이유는 copy Method를 사용하면 새로운 메모리 공간에

Image 데이터를 복사하기 때문에 다른 값을 지닐 수 있다.

 

그래서 위 예제도 실행시키면 알 수 있듯이 Original Image에 선을 그어도

Copied Image에는 영향이 없다.

 

[ Result ]

 

Original Image Have a Line
Can't Find The Line In Copied Image

 

 

4. How_To_Deal_Pixel

import cv2
import numpy as np 

Img_Color = cv2.imread('Image_Sample.jpg', cv2.IMREAD_COLOR)

# 이미지의 높이와 너비를 가져온다.
height, width = Img_Color.shape[:2]

#Gray Scale 이미지를 저장할 넘파이 배열 생성
img_gray = np.zeros((height, width), np.uint8)

#for 문을 돌리면서 x,y에 있는 픽셀을 하나씩 접근
for y in range(0, height):
    for x in range(0, width):
        
        #컬러 이미지 x,y에 있는 픽셀의 bgr채널을 읽는다.
        #Argument = (First_Position, Second_Position, Number, RGB)
        b = Img_Color.item(y, x, 0)
        g = Img_Color.item(y, x ,1)
        r = Img_Color.item(y, x, 2)

        #x, y 위치의 픽셀에 그레이 스케일 값 저장
        gray = int((r+g+b) / 3.0)

        img_gray.itemset(y, x, gray)

#컬러 이미지 변환
img_result = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)

# 150부터 201 / 200부터 251까지 초록색 픽셀로 변환
for y in range(150, 201):
    for x in range(200, 251):
        img_result.itemset(y, x, 0, 0)
        img_result.itemset(y, x, 1, 255)
        img_result.itemset(y, x, 2, 0)

cv2.imshow("color", Img_Color)
cv2.imshow("result", img_result)

cv2.waitKey(0)

cv2.destroyAllWindows()

이 코드는 사진의 일부 픽셀만 색깔을 조절하는 것이다.

 

위 코드는 그리 어렵지 않으니 직접 주석을 읽어보면서 이해를 하면 좋을거 같다.

 

정말 간략한 설명을 붙이자면

 

zeros Method는 넘파이 배열을 생성하는 것이며

 

itemset을 통해서 GrayScale로 변환을 해준다.

 

그 후 원하는 Pixel을 잡아서 초록색으로 변환을 해준다.

 

[ Result ]

 

 

Orignal Image
Deal WIth Pixel

 

끄-읕

 

나 왜 18살이지🤔.

'openCV' 카테고리의 다른 글

[openCV] Draw Function  (0) 2021.02.06
[ openCV ] Image Operation ( Blending, Operate Image Bit, ROI )  (0) 2021.02.02
[openCV] Binarization  (0) 2021.01.23
[openCV] Graphic User Interface  (0) 2021.01.16
openCV - 기초부터 다지기  (0) 2021.01.02