2022. 1. 19. 14:43ㆍ작업/ComputerVision
CNN은 대표적인 딥러닝 모델 -> 이미지(JPG,PNG) 분류에 특화되어있다.
픽셀
이미지의 기본 단위 : 픽셀
픽셀 하나당 색깔, 밝기 정보를 가진다.
각 픽셀은 3가지 색 값을 저장할 수 있으므로 RGB 채널이 있다.
그 RGB 채널은 8비트(01001110)의 수로 이뤄져있다. R:0~255 , G:0~255 , B:0~255 가능
총 8*3 = 24 비트, 2^24개의 색을 표현 가능하다
한가지 값만 가지면 흑백, 밝기만 저장함.
딥러닝을 활용한 이미지처리 기술 분야
1. 사물인식(Object Detection)
센터 스테이지 : 사람 영상에서 사람얼굴을 인식해 화면 가운데에게 오게 해주는 apple의 기술
2. 이미지 캡셔닝 ( Image Captioning)
사진을 보고 설명하는 기술? -> 자연어처리도 필요함
3. 이미지 합성( Deep Fake)
4. 화질 개선( Super Resolution, DLSS)
4K 모니터 (고해상도) 는 게임을 돌릴 때는 애로사항이 있다. 고해상도 모니터는 픽셀 수가 많다보니 1번 그릴 때(FPS) 그려야하는 픽셀수가 많아서 FPS가 끊길 수 있다.
NVidia의 기술 : 일단 저해상도로 그리고(FPS가 높다), 실시간으로 딥러닝으로 고해상도로 바꾼다. 이 모든 작업을 그래픽카드 내부에 장착을 시킨다. -> FPS자체는 저해상도에서 그렸을 떄의 값을 고정하면서도 화면의 품질은 고해상도처럼 만든다.
5. 알파고
딥러닝 이전의 이미지 처리 기법
1. 형태 변환
2. 색상 변환
3. 필터 변환
1. 형태 변환
2. 색상변환
흑백변화 : RGB중 하나만(R)만 가져옴 그 색의 세기를 밝기로 바꿔버리면 흑백이 되는 것.
3. 필터 변환 -> CNN에서 핵심 역할을 수행
샤프닝 : noise까지도 포함, 더 선명한 이미지
블러: 인물사진(초점 같은 느낌, 모자이크)
경계선 감지 : 이미지분류(사물 구분)에도 쓰임
PIL ( Pillow) Python Imaging Library
img = Image.open('이미지.png')
img라는 변수에 Pillow의 Image 클래스 객체가 저장된다.
img클래스는 size, mode 속성이 있다.
crop : 전체 이미지 안에서 특정 영역만 잘라내는 작업을 의미, Image클래스의 crop 메소드 사용
crop 메소드는 이미지 내의 4개의 좌표를 튜플 형태로 넣어준다.
이미지 좌표는 (x,y)로 이뤄지고 0,0은 왼쪽 위가 된다.
crop메소드는 잘라낼 영역의 왼쪽상단, 오른쪽 아래 총 x1,y1, x2,y2 두 좌표가 필요하다. 이 두 개를 튜플로 요구한다
img.crop((x1,y1,x2,y2)) 이렇게 하나의 튜플에 넣어서 주면 된다.
이미지 회전 img.rotate 메소드 사용 -> 시계방향 또는 반시계 방향으로 일정 각도만큼 회전
expand = True
크기/비율 변환
img.resize 메소드 : 크기 변환은 세로,가로 길이를 변화시키는 것이고 비율 변환은 기존의 이미지가 가지고 있던 가로와 세로 길이의 비율을 변환하는 작업. resize 혹은 rescale로 부르며 resize메소드로 통일해서 수행한다.
바꾸고자 하는 가로와 세로의 픽셀 길이를 튜플로 넣어주면 된다.
원본은 (512,512)였는데 (128,128)로 resize를 했다. 그리고 픽셀 수를 줄였기 떄문에 이미지의 선명도 또한 줄어들었다.
이것은 비율은 무시한 채 원하는 크기로 바꾸는 것이다. 128,256으로 했다
전단 변환(층 밀림 변환)
사각형의 이미지를 평행사변형 꼴로 바꾸는 변환
transform메소드를 사용한다. 전단변환 뿐 아니라 다른 형태의 변환기술들도 사용할 수 있다
img.transform((픽셀,픽셀) , 변환방법)
이미지 색상 변환 - 밝기변화(Brightness), 대조변화(Contrast), 흑백변화(Grayscale)
PIL에서 ImageEnhance를 import한다.
밝기변화
ImageEnhance의 Brightness 클래스를 사용. 이 클래스는 객체 생성을 위해 image 객체를 파라미터로 요구한다.
객체.enhance(밝기 배)
대조 변화 - Contrast 클래스 사용
흑백 변화
이미지의 컬러 여부는 mode속성으로 확인하는데, 이걸 RGB에서 흑백 모드로 바꾸는 작업을 한다.
PIL에서 흑백 변화를 하려면 Image 클래스의 convert 메소드를 사용한다.
img.convert('L')
필터 변환 - 샤프닝, 블러, Edge detection
Image 클래스의 filter 메소드를 사용
블러
경계선 감지 edge detection
이미지 형태 변환하기
from elice_utils import EliceUtils
elice_utils = EliceUtils()
from PIL import Image
def crop(img, coordinates):
# TODO: [지시사항 1번] 이미지를 자르는 코드를 완성하세요.
img_crop = img.crop(coordinates)
return img_crop
def rotate(img, angle, expand=False):
# TODO: [지시사항 2번] 이미지를 회전하는 코드를 완성하세요.
img_rotate = img.rotate(angle, expand=expand)
return img_rotate
def resize(img, new_size):
# TODO: [지시사항 3번] 이미지 크기를 변경하는 코드를 완성하세요.
img_resize = img.resize(new_size)
return img_resize
def shearing(img, shear_factor):
# TODO: [지시사항 4번] 이미지를 전단 변환하는 코드를 완성하세요.
img_shearing = img.transform((int(img.size[0] * (1 + shear_factor)), img.size[1]),
Image.AFFINE, (1, -shear_factor, 0, 0, 1, 0))
return img_shearing
def show_image(img, name):
img.save(name)
elice_utils.send_image(name)
def main():
img = Image.open("Lenna.png")
# TODO: [지시사항 5번] 지시사항에 따라 적절한 이미지 변환을 수행하세요.
# 이미지 자르기
img_crop = crop(img,(150,200,450,400))
# 이미지 회전하기
img_rotate = rotate(img,160,expand=True)
# 이미지 크기 바꾸기
img_resize = resize(img,(640,360))
# 이미지 전단 변환
img_shearing = shearing(img,0.8)
print("=" * 50, "Crop 결과", "=" * 50)
show_image(img_crop, "crop.png")
print("=" * 50, "Rotate 결과", "=" * 50)
show_image(img_rotate, "rotate.png")
print("=" * 50, "Resize 결과", "=" * 50)
show_image(img_resize, "resize.png")
print("=" * 50, "Shearing 결과", "=" * 50)
show_image(img_shearing, "shearing.png")
return img_crop, img_rotate, img_resize, img_shearing
if __name__ == "__main__":
main()
from elice_utils import EliceUtils
elice_utils = EliceUtils()
from PIL import Image
from PIL import ImageEnhance
def change_brightness(img, factor):
# TODO: [지시사항 1번] 이미지의 밝기를 변화시키는 코드를 완성하세요.
bright_enhancer = ImageEnhance.Brightness(img)
img_bright = bright_enhancer.enhance(factor)
return img_bright
def change_contrast(img, factor):
# TODO: [지시사항 2번] 이미지의 대조를 변화시키는 코드를 완성하세요.
contrast_enhancer = ImageEnhance.Contrast(img)
img_contrast = contrast_enhancer.enhance(factor)
return img_contrast
def change_grayscale(img):
# TODO: [지시사항 3번] 이미지를 흑백 이미지로 변경하는 코드를 완성하세요.
img_gray = img.convert('L') # 모드를 RGB에서 L로 바꾼다.
return img_gray
def show_image(img, name):
img.save(name)
elice_utils.send_image(name)
def main():
img = Image.open("Lenna.png")
# TODO: [지시사항 4번] 지시사항에 따라 적절한 이미지 변환을 수행하세요.
# 이미지 밝게 하기
img_bright = change_brightness(img, 1.5)
# 이미지 어둡게 하기
img_dark = change_brightness(img,0.2) # 5배 어둡게
# 이미지 대조 늘리기
img_high_contrast = change_contrast(img, 3)
# 이미지 대조 줄이기
img_low_contrast = change_contrast(img, 0.1)
# 이미지 흑백 변환
img_gray = change_grayscale(img)
print("=" * 50, "밝은 이미지", "=" * 50)
show_image(img_bright, "bright.png")
print("=" * 50, "어두운 이미지", "=" * 50)
show_image(img_dark, "dark.png")
print("=" * 50, "강한 대조 이미지", "=" * 50)
show_image(img_high_contrast, "high_contrast.png")
print("=" * 50, "약한 대조 이미지", "=" * 50)
show_image(img_low_contrast, "low_contrast.png")
print("=" * 50, "흑백 이미지", "=" * 50)
show_image(img_gray, "gray.png")
return img_bright, img_dark, img_high_contrast, img_low_contrast, img_gray
if __name__ == "__main__":
main()
from elice_utils import EliceUtils
elice_utils = EliceUtils()
from PIL import Image
from PIL import ImageFilter
def sharpening(img):
# TODO: [지시사항 1번] 이미지에 샤프닝 필터를 적용시키는 코드를 완성하세요.
img_sharpen = img.filter(ImageFilter.SHARPEN)
return img_sharpen
def blur(img):
# TODO: [지시사항 2번] 이미지에 블러 필터를 적용시키는 코드를 완성하세요.
img_blur = img.filter(ImageFilter.BLUR)
return img_blur
def detect_edge(img):
# TODO: [지시사항 3번] 이미지의 경계선을 탐지하는 코드를 완성하세요.
img_edge = img.filter(ImageFilter.FIND_EDGES)
return img_edge
def show_image(img, name):
img.save(name)
elice_utils.send_image(name)
def main():
img = Image.open("Lenna.png")
# TODO: [지시사항 4번] 지시사항에 따라 적절한 이미지 변환을 수행하세요.
# 이미지 샤프닝 한번 적용하기
img_sharpen_1 = sharpening(img)
# 이미지 샤프닝 5번 적용하기
img_sharpen_5 = sharpening(img)
img_sharpen_5 = sharpening(img_sharpen_5)
img_sharpen_5 = sharpening(img_sharpen_5)
img_sharpen_5 = sharpening(img_sharpen_5)
img_sharpen_5 = sharpening(img_sharpen_5)
# 이미지 블러 한번 적용하기
img_blur_1 = blur(img)
# 이미지 블러 5번 적용하기
img_blur_5 = blur(img)
img_blur_5 = blur(img_blur_5)
img_blur_5 = blur(img_blur_5)
img_blur_5 = blur(img_blur_5)
img_blur_5 = blur(img_blur_5)
# 이미지 경계선 찾기
img_edge = detect_edge(img)
print("=" * 50, "샤프닝 한번 적용한 이미지", "=" * 50)
show_image(img_sharpen_1, "sharpen_1.png")
print("=" * 50, "샤프닝 다섯번 적용한 이미지", "=" * 50)
show_image(img_sharpen_5, "sharpen_5.png")
print("=" * 50, "블러 한번 적용한 이미지", "=" * 50)
show_image(img_blur_1, "blur_1.png")
print("=" * 50, "블러 다섯번 적용한 이미지", "=" * 50)
show_image(img_blur_5, "blur_5.png")
print("=" * 50, "경계선 이미지", "=" * 50)
show_image(img_edge, "edge.png")
return img_sharpen_1, img_sharpen_5, img_blur_1, img_blur_5, img_edge
if __name__ == "__main__":
main()
from elice_utils import EliceUtils
elice_utils = EliceUtils()
from PIL import Image
import matplotlib.pyplot as plt
import os
import numpy as np
def show_plot(img, title=" "): # 이미지 저장하고 보여주기
plt.title(title)
plt.imshow(img)
plt.savefig("tmp.png")
elice_utils.send_image("tmp.png")
def load_image(path, name):
# TODO: [지시사항 1번] 이미지를 불러오는 함수를 완성하세요
# path = 'dataset/val/dogs'
# name = 'dog.0.jpg' # 'dataset/val/dogs/dog.0.jpg'로 만들어야함
img = Image.open(os.path.join(path,name))
return img
def main():
data_path = "dataset/val/dogs"
# 이미지를 불러와 plt를 이용하여 출력합니다
names = os.listdir(data_path)
img = load_image(data_path, names[0])
# 원본 이미지를 출력
show_plot(img, "PIL original image")
# TODO: [지시사항 2번] 지시사항에 따라 이미지의 크기를 확인하는 코드를 완성하세요.
# PIL을 통해 이미지 크기 확인
pil_size = img.size
print("PIL을 통한 이미지 크기:", pil_size)
# PIL 이미지를 numpy 배열로 변환
np_img = np.array(img)
# numpy 배열의 shape 확인
np_shape = np_img.shape
print("numpy 배열 shape:", np_shape)
show_plot(np_img, "Numpy array image")
# TODO: [지시사항 3번] PIL과 numpy를 이용하여 이미지를 다루는 코드를 완성하세요.
# PIL.Image에서 x=10, y=20 의 픽셀값 가져오기
pil_pix = img.load()[10, 20]
# numpy 배열에서 x=10, y=20 의 픽셀값을 가져오세요
np_pix = np_img[20,10] # numpy랑 pil이랑 가로세로 반대로 가져와야함!
print("PIL의 픽셀값: {}, numpy의 픽셀값: {}".format(pil_pix, np_pix))
# PIL을 이용하여 이미지의 크기를 (224,224)로 변형하세요.
resized_img = img.resize((224,224))
# 224,224인 이유 ImageNet이라는 유명한 딥러닝학습방법의 데이터셋이 224,224이기 때문이다.
# resize된 이미지 출력
show_plot(resized_img, "Resized image")
print("resize 결과 사이즈:", resized_img.size)
return pil_size, np_img, np_shape, np_pix, resized_img
if __name__ == "__main__":
main()
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
data_path = "dataset"
batch_size = 2
img_height = 180
img_width = 180
# path의 데이터를 ImageDataGenerator로 불러와주는 함수
def get_dataset(path, datagen):
data_set = datagen.flow_from_directory(path,
target_size=(img_width, img_height),
batch_size=batch_size, # 한 번에 이미지 두 장씩
class_mode='categorical') # cats, dogs 두 개면 binary를 쓰기도 함.
return data_set
def main():
# TODO: [지시사항 1번] 정규화 과정이 없는 ImageDataGenerator를 만드세요.
first_gen = ImageDataGenerator()
first_set = get_dataset(os.path.join(data_path, "val"), first_gen)
x, y = first_set.__next__()
print("\n1. 데이터 제너레이터 만들기")
print("first_set")
print("x: {}, y: {}".format(x.shape, y.shape))
print(x[0][0][0]) # 픽셀이 0~255의 값을 가짐
# TODO: [지시사항 2번] 픽셀값을 0~1의 값으로 정규화 하는 ImageDataGenerator를 만드세요.
second_gen = ImageDataGenerator(rescale=1/255)
second_set = get_dataset(os.path.join(data_path, "val"), second_gen)
x, y = second_set.__next__()
print("\n2. 데이터 제너레이터에 정규화 추가하기")
print("second_set")
print("x: {}, y: {}".format(x.shape, y.shape))
print(x[0][0][0]) # 픽셀이 0~1의 값을 가지는 것을 확인하세요
# TODO: [지시사항 3번] 실제 학습을 위한 ImageDataGenerator를 만드세요.
# 학습 데이터를 위한 ImageDataGenerator를 만드세요.
train_gen = ImageDataGenerator(rescale=1/255)
# 학습 데이터셋을 불러오도록 경로명을 설정하세요.
train_set = get_dataset(os.path.join(data_path,'train'), train_gen) #dataset/train
# 검증 데이터를 위한 ImageDataGenerator를 만드세요.
valid_gen = ImageDataGenerator(rescale=1/255)
# 검증 데이터셋을 불러오도록 경로명을 설정하세요.
valid_set = get_dataset(os.path.join(data_path,'val'), valid_gen)
print("\n3. 실제 학습을 위한 데이터 제너레이터 작성")
print("학습 데이터의 길이: ", len(train_set))
print("검증 데이터의 길이: ", len(valid_set))
return first_gen, second_gen, train_gen, train_set, valid_gen, valid_set
if __name__ == "__main__":
main()
'작업 > ComputerVision' 카테고리의 다른 글
22.02.09 윈도우에서 pf-afn 환경설정 + 인공지능 가상 옷 피팅 (Virtual Try On) demo 돌려보기 (0) | 2022.02.09 |
---|---|
22.02.06 교통표지판 이미지 분류 프로젝트 공부 (0) | 2022.02.07 |
22.01.30 윈도우에 tensorflow GPU까지 연결해서 환경설정하기(cuDNN, CUDA, tensorflow, 1050Ti) (0) | 2022.01.30 |
22.01.28(중요) Tensorflow로 배우는 CNN 핵심정리 (0) | 2022.01.29 |
22.01.19 CNN(Convolutional Neural Network) (0) | 2022.01.22 |