: 디지털 이미지를 분석하거나 수정하여 정보를 추출하거나 생성하는 기술
목적
활용 사례
1. 픽셀(Pixel)
이미지를 구성하는 가장 작은 단위
Red, Green, Blue로 구성된 RGB 채널(3차원 행렬)로 나타낼 수 있음
(각 색상은 0~255(밝기)로 표현됨)
image=np.array([[[255,0,0], [0,255,0],
[0,0,0],[255,255,255]]])
plt.figure(figsize=(5,5))
plt.imshow(image)
plt.show()

import numpy as np
import matplotlib.pyplot as plt
# RGB 색상 정의
R = [1.0, 0.0, 0.0] # Red
B = [0.0, 0.0, 1.0] # Blue
S = [0.9, 0.8, 0.6] # Skin
W = [1.0, 1.0, 1.0] # White
K = [0.0, 0.0, 0.0] # Black
Br = [0.5, 0.2, 0.0] # Brown
image1 = np.array([
[K, K, R, R, R, R, K, K],
[K, K, R, R, R, W, R, K],
[K, K, S, B, S, B, K, K],
[K, K, S, S, Br, Br, K, K],
[S, R, B, R, R, B, R, S],
[K, K, B, B, B, B, K, K],
[K, K, B, B, B, B, K, K],
[K, K, Br, K, K, Br, K, K]
])
# 시각화
plt.figure(figsize=(5, 5))
plt.imshow(image1)
plt.show()

2. Image Loader
from PIL import Image
img_pil=Image.open(r'/content/sample.png')
img_pil.show()
plt.imshow(img_pil)
plt.show()

print(img_pil)

import cv2
from google.colab.patches import cv2_imshow
img_cv = cv2.imread('/content/sample.png')
cv2_imshow(img_cv)

print(img_cv)

3. Image 변형하기
h,w,c=img_cv.shape
img_resized=cv2.resize(img_cv, (w//10, h//10))
img_resized=cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(5,5))
plt.imshow(img_resized)
plt.axis('off')
plt.show()

흑백 이미지로 변환하는 것으로, 0~255(밝기 정보)를 가지는 채널 하나로만 구성됨
RGB -> Gray 변환
Gray Scale의 장점
import cv2
from google.colab.patches import cv2_imshow
import numpy as np
img_cv = cv2.imread('/content/sample.png')
B, G, R = cv2.split(img_cv)
gray = 0.299 * R + 0.587 * G + 0.114 * B
gray = gray.astype(np.uint8)
cv2_imshow(gray)

4. 이미지와 신경망
이미지를 신경망으로 표현하는데 있어서, 문제점 존재
Pixel의 위치는 ( or )로 표현됨
(일반적으로 은 왼쪽 위를 표현)

신경망과 이미지가 1:1로 mapping 되려면 이미지를 1차원 배열로 전처리 필요
5. DataLoader 만들기
torchvision.datasets.ImageFolder 는 이미지 데이터셋을 손쉽게 불러올 수 있도록 도와주는 클래스
이미지를 폴더 구조에 따라 자동으로 레이블링

향후 transforms를 이용한 전처리 및 데이터 증강 가능
Pytorch 학습을 위한 Dataset 객체 반환
from torchvision.datasets import ImageFolder
from sklearn.model_selection import train_test_split
dataset = ImageFolder(train_test_set_small)
train_data, test_data = train_test_split(dataset.imgs, test_size=0.2, random_state=42)
print(train_data)
class ImageLoader(Dataset):
def __init__(self, dataset):
self.dataset=dataset
def __len__(self):
return len(self.dataset)
def __getitem__(self, item):
image=cv2.imread(self.dataset[item][0])
image=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image=cv2.resize(image,(28,28))
image=image.reshape(28*28)
label=self.dataset[item][1]
return image, label
6. 신경망 학습하기
class ImageLoader(Dataset):
def __init__(self, dataset):
self.dataset = dataset
self.imgs = dataset
def __len__(self):
return len(self.dataset)
def __getitem__(self, index):
image_path, label = self.dataset[index]
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.resize(image, (28, 28))
image = image.astype(np.float32) / 255.0 # 정규화
image = image.reshape(1, 28, 28) # 채널 차원 추가
return torch.tensor(image), torch.tensor(label)
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28 * 28, 512)
self.relu1 = nn.ReLU()
self.fc2 = nn.Linear(512, 256)
self.relu2 = nn.ReLU()
self.fc3 = nn.Linear(256, 2)
def forward(self, x):
x = self.flatten(x)
x = self.relu1(self.fc1(x))
x = self.relu2(self.fc2(x))
x = self.fc3(x)
return x
batch_size = 64
train_dataset = ImageLoader(train_data)
test_dataset = ImageLoader(test_data)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size)
model = SimpleNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
num_epochs = 10
for epoch in range(num_epochs):
model.train()
total_loss = 0
for images, labels in train_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss:.4f}")

import matplotlib.pyplot as plt
import torch
target_img = 4
plt.figure(figsize=(2, 2))
plt.imshow(images[target_img].view(28, 28).cpu().numpy(), cmap='gray')
plt.axis('off')
plt.show()
with torch.no_grad():
pred = model(images[target_img].view(1, 28*28)) # 배치 차원 추가
pred = torch.argmax(pred)
# 예측 결과 출력
if pred == 0:
print("예측한 이미지는 고양이 입니다.")
else:
print("예측한 이미지는 강아지 입니다.")
# 정답과 비교
if pred == labels[target_img]:
print("정답입니다!")
else:
print("오답입니다!")
