본문 바로가기
머신러닝 딥러닝

0917 Image 처리의 기본

by 대금부는개발자 2021. 9. 17.
SMALL

이미지를 구성하고 있는 가장 작은 단위 - picxel

 

모니터의 해상도(1024 * 768),

이미지의 해상도 => picxel의 개수(개수에 따라 고해상도, 저해상도)

각 picxel은 밝기 값, 컬러 값을 가질 수 있는데, 이런 picxel들이 모여서 이미지 패턴을 만들어요.

 

일반적으로 우리가 생각하는 좌표계는 - 데카르트 좌표계 (수학적 2차원 형태의 좌표계 x축, y축)

이미지를 표현하는 좌표계 - Image Coordinate ( y축이 밑으로 가요- 이미지를 행렬 구조로 이용하기 위해 )

이미지 좌표계는 'Matrix 구조'

이미지의 y축의(세로 길이) M(행)에 매칭

이미지의 x의(가로길이) N(열)에 매칭

picxwl [ 세로, 가로 ]

 

코드로 알아보아요!! 만약 pillow 모듈이 설치가 되어 있지 않다면,

conda install pillow

컴퓨터에 jpg를 위한 폴더 하나 만들고, 이미지를 집어넣은 후 실행해 보아요.

 

 

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image # 이미지 처리를 위한 pillow 모듈

 

img = Image.open('./images/justice.jpg') # pillow에서 만든 class type 이미지 객체화

# print(type(img)) 
# <class 'PIL.JpegImagePlugin.JpegImageFile'>

plt.imshow(img)
plt.show() # 이미지 좌표계 → 세로가 밑으로 내려오고 있어요! 높이가 행(raw) 가로길이가 열(column)

 

# color 이미지 기본은 3차원 - 첫 번째는 red 두 번째는 green 세 번째는 blue
# 흑백은 2차원
pixcel = np.array(img)
print(pixcel)   # 3차원으로 표시됐어요! RGB 각각의 값입니다.

#[[[ 14  30  90]
#  [ 14  30  90]
#  [ 15  31  91]
#  ...
#  [ 12  25  78]
#  [ 11  24  77]
#  [ 11  24  77]]
print(pixcel.shape) # (426, 640, 3) 세로, 가로, 3 채널
img.save('./images/my_image.jpg') # save를 이용한 이미지 저장

 

# crop - 내가 원하는 영역만 잘라내요.
# 칼만 잘라낼 거예요.
# crop( 좌상 우하 ) 왼쪽 위, 오른쪽 아래 순서로 tuple형태
crop_image = img.crop((30,100,150,300)) (가로 시작점, 세로 시작점, 가로 범위, 세로 범위)
plt.imshow(crop_image)
plt.show()

 

# resize - 사이즈 늘렸다 줄였다.
# 사이즈의 형태대로 [0] 640
# 8은 임의의 값 ,img.size[0] 세로 , img.size[1] 가로, int 실수 → 정수


resize_img = img.resize((int(img.size[0] / 8), int(img.size[1]/8)))
plt.imshow(resize_img)
plt.show()


# pixel의 개수가 줄어서 이미지가 흐릿해요.

 

# ratate - 회전
rotate_img = img.rotate(180)
plt.imshow(rotate_img)
plt.show()

 

 

Digital image의 형태

 

이진 이미지(binary image) : 각 pixel의 값을 0(어두움), 1(밝음)으로 표현

장점 : 각 pixel을 표현할 때 1bit(칸 하나)면 가능할 거 같아요!

 

일반적으로 bit를 8개로 모아서 컴퓨터로 표현해요. 8 bit → 1byte

1byte로 표현할 수 있는 값의 개수(경우의 수)는 2^8, 총 256가지

숫자로 표현하면 0 ~ 255

음수를 표현할 때 MSB(Most Significant Bit) 부호를 가리켜요 -128 ~ 127

 

하지만 실제로는 1pixel을 표현할 때 1 bite를 이용해요. 굳이 2진 이미지를 쓸 필요가 없어요(공간 낭비)
→ image의 모양만 볼 때아니면, 사이즈를 줄일 수도 없고 이미지를 잘 표현 못 해서 이진 이미지는 잘 안 써요.

 

흑백 이미지(Gray-scale image) : 각 pixel의 값으로 0~ 255 사이의 값으로 표현한 이미지.

흔히들 흑백 이미지는 2차원으로 표현할 수 있구나라고 생각

30 7 0 180
50 180 0 ..
.. .. .. ..
.. .. .. ..

하지만 흑백이든 칼라든 이미지의 기본은 3차원이예요.

가로 픽셀의 개수, 세로 픽셀의 개수, 채널 r의 값과 g의 값과 b의 값의 평균 → Gray-scale

 

컬러 이미지(color image) : R, G, B 3개의 channel을 이용Red 0 ~ 255 , Green 0 ~ 255, Blue 0 ~ 255총 2^24 개의 색상을 표현 → True color

 

학습을 할 때 색깔이 필요한 경우, 모양이 필요한 경우가 있는데,

일반적으로 해당 이미지가 어떤 이미지인지 판단할 때는 컬러 값이 크게 중요하지 않아요.

일부로 더 적은 size의 데이터를 가지고 표현하려고 2차원 Gray-scale로 바꿔요.(연산속도)

 

확장자 .png → 투명도가 들어가 있어요 RGBA, 4 채널

A는 알파(α)의 의미 

 

code를 통해 컬러 이미지(3차원)를 흑백 이미지(2차원, 3차원)로 변환할 거예요.

color 이미지 1개의 pixel(R, G, B) → (50, 100, 75)

흑백 이미지 1개의 pixel(R, G, B)의 평균 → ( 75, 75, 75)

흑백으로 바꾸는 방법 중 하나 : RGB의 평균을 구해서 각 RGB 값을 평균으로 setting

 

import numpy as np 
import matplotlib.pyplot as plt
from PIL import Image

color_img = Image.open('./images/fruits.jpg')

plt.imshow(color_img)
plt.show() 
print(color_img.size) # (640, 426)

color_pixel = np.array(color_img)
print(color_pixel.shape) # (426, 640, 3)

 

 

gray_pixel = color_pixel.copy() 

# 각 픽셀의 RGB 값의 평균을 구해서, 각 픽셀의 RGB 값을 그 평균값으로 설정

# gray_pixel[0,0,0] # 이미지의 제일 상단 구석에 있는 하나의 픽셀 

# print(gray_pixel[0,0,0]) # 108 Red 
# print(gray_pixel[0,0,1]) # 117 Green 
# print(gray_pixel[0,0,2]) # 0   Blue 

# print(gray_pixel[0,0]) # [108 117   0] 두 개만 명시하면 세게의 RGB 값에 대한 ndarray, 
# [0,0] 세로, 가로

for y in range(gray_pixel.shape[0]): #0 ~ 425,  gray_pixel의 높이
    for x in range(gray_pixel.shape[1]):
        gray_pixel[y,x] = int(np.mean(gray_pixel[y,x])) # 평균을 구한 값
        
plt.imshow(gray_pixel)
plt.show()

print(gray_pixel[0,0]) # [75 75 75] 평균값 setting

 

gray_channel3_img = Image.fromarray(gray_pixel) # fromarray 어디서부터~
gray_channel3_img.save('./images/fruits_gray(3channel).jpg') # 저장

 



# 3차원 이미지를 2차원으로 바꿀 거예요!
print(gray_pixel[0,0]) # [75 75 75] 

gray_2d_pixel = gray_pixel[:,:,0]  # 모든 행에 대한 모든 가로 → 모든 픽셀의 0번째 2번 슬라이싱 → 2차원
print(gray_2d_pixel.shape)         # (426, 640) 2차원이 되었어요!
print(gray_2d_pixel[0,0])            # 75         평균값

plt.imshow(gray_2d_pixel)
plt.show()

 

# 흑백이 아니라 물 빠진... 색

 

plt.imshow(gray_2d_pixel, cmap='gray')    # color map -칼라 색상 추가
plt.show()

 

gray_2d_img = Image.fromarray(gray_2d_pixel)
gray_2d_img.save('./images/fruits_gray(2d).jpg') # 저장

 

원칙은 칼라든 흑백이든 3차원, 흑백은 size 줄여 표현할 수 있도록 2차원으로 표현 가능해요!

LIST

'머신러닝 딥러닝' 카테고리의 다른 글

0927 CNN(Convolution Neural Network)  (0) 2021.09.27
0917 CNN 합성곱 신경망  (0) 2021.09.17
0916 Deep Learning  (0) 2021.09.16
0915 mnist  (0) 2021.09.16
0915 Neural Networks, XOR  (0) 2021.09.15

댓글