<jupyter_start><jupyter_text>8장. 이미지 다루기 이 노트북을 주피터 노트북 뷰어(nbviewer.jupyter.org)로 보거나 구글 코랩(colab.research.google.com)에서 실행할 수 있습니다.      주피터 노트북 뷰어로 보기        구글 코랩(Colab)에서 실행하기    8.1 이미지 로드<jupyter_code># 코랩에서 실행하는 경우 다음 주석을 제거하고 실행하세요.
#!mkdir images
#!wget https://github.com/rickiepark/machine-learning-with-python-cookbook/raw/master/images/plane.jpg -O images/plane.jpg
# 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane.jpg", cv2.IMREAD_GRAYSCALE)
# 이미지를 출력합니다.
plt.imshow(image, cmap="gray"), plt.axis("off")
plt.show()
# 데이터 타입을 확인합니다.
type(image)
# 이미지 데이터를 확인합니다.
image
# 차원을 확인합니다.
image.shape
# 컬러로 이미지를 로드합니다.
image_bgr = cv2.imread("images/plane.jpg", cv2.IMREAD_COLOR)

# 픽셀을 확인합니다.
image_bgr[0,0]
# RGB로 변환합니다.
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

# 이미지를 출력합니다.
plt.imshow(image_rgb), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.2 이미지 저장<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane.jpg", cv2.IMREAD_GRAYSCALE)

# 이미지를 저장합니다.
cv2.imwrite("images/plane_new.jpg", image)<jupyter_output><empty_output><jupyter_text>8.3 이미지 크기 변경하기<jupyter_code># 코랩에서 실행하는 경우 다음 주석을 제거하고 실행하세요.
#!wget https://github.com/rickiepark/machine-learning-with-python-cookbook/raw/master/images/plane_256x256.jpg -O images/plane_256x256.jpg
# 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 이미지 크기를 50x50 픽셀로 바꿉니다.
image_50x50 = cv2.resize(image, (50, 50))

# 이미지를 출력합니다.
plt.imshow(image_50x50, cmap="gray"), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.4 이미지 지르기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 열의 처음 절반과 모든 행을 선택합니다.
image_cropped = image[:,:128]

# 이미지를 출력합니다.
plt.imshow(image_cropped, cmap="gray"), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.5 이미지 흐리게 하기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 이미지를 흐리게 합니다.
image_blurry = cv2.blur(image, (5,5))

# 이미지를 출력합니다.
plt.imshow(image_blurry, cmap="gray"), plt.axis("off")
plt.show()
# 이미지를 흐리게 합니다.
image_very_blurry = cv2.blur(image, (100,100))

# 이미지를 출력합니다.
plt.imshow(image_very_blurry, cmap="gray"), plt.xticks([]), plt.yticks([])
plt.show()
# 커널을 만듭니다.
kernel = np.ones((5,5)) / 25.0

# 커널을 확인합니다.
kernel
# 커널을 적용합니다.
image_kernel = cv2.filter2D(image, -1, kernel)

# 이미지를 출력합니다.
plt.imshow(image_kernel, cmap="gray"), plt.xticks([]), plt.yticks([])
plt.show()<jupyter_output><empty_output><jupyter_text>붙임<jupyter_code>#  가우시안 블러를 적용합니다.
image_very_blurry = cv2.GaussianBlur(image, (5,5), 0)

# 이미지를 출력합니다.
plt.imshow(image_very_blurry, cmap="gray"), plt.xticks([]), plt.yticks([])
plt.show()
gaus_vector = cv2.getGaussianKernel(5, 0)
gaus_vector
# 벡터를 외적하여 커널을 만듭니다.
gaus_kernel = np.outer(gaus_vector, gaus_vector)
gaus_kernel
# 커널을 적용합니다.
image_kernel = cv2.filter2D(image, -1, gaus_kernel)

# 이미지를 출력합니다.
plt.imshow(image_kernel, cmap="gray"), plt.xticks([]), plt.yticks([])
plt.show()<jupyter_output><empty_output><jupyter_text>8.6 이미지를 선명하게 하기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 커널을 만듭니다.
kernel = np.array([[0, -1, 0],
                   [-1, 5,-1],
                   [0, -1, 0]])

# 이미지를 선명하게 만듭니다.
image_sharp = cv2.filter2D(image, -1, kernel)

# 이미지를 출력합니다.
plt.imshow(image_sharp, cmap="gray"), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.7 대비 향상<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 이미지 대비를 향상시킵니다.
image_enhanced = cv2.equalizeHist(image)

# 이미지를 출력합니다.
plt.imshow(image_enhanced, cmap="gray"), plt.axis("off")
plt.show()
# 이미지를 로드합니다.
image_bgr = cv2.imread("images/plane.jpg")

# YUV로 바꿉니다.
image_yuv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2YUV)

# 히스토그램 평활화를 적용합니다.
image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])

# RGB로 바꿉니다.
image_rgb = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2RGB)

# 이미지를 출력합니다.
plt.imshow(image_rgb), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.8 색깔 구분하기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 이미지를 로드합니다.
image_bgr = cv2.imread('images/plane_256x256.jpg')

# BGR에서 HSV로 변환합니다.
image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)

# HSV에서 파랑 값의 범위를 정의합니다.
lower_blue = np.array([50,100,50])
upper_blue = np.array([130,255,255])

# 마스크를 만듭니다.
mask = cv2.inRange(image_hsv, lower_blue, upper_blue)

# 이미지에 마스크를 적용합니다.
image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)

# BGR에서 RGB로 변환합니다.
image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)

# 이미지를 출력합니다.
plt.imshow(image_rgb), plt.axis("off")
plt.show()
# 마스크를 출력합니다.
plt.imshow(mask, cmap='gray'), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.9 이미지 이진화<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image_grey = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 적응적 임계처리를 적용합니다.
max_output_value = 255
neighborhood_size = 99
subtract_from_mean = 10
image_binarized = cv2.adaptiveThreshold(image_grey,
                                        max_output_value,
                                        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                        cv2.THRESH_BINARY,
                                        neighborhood_size,
                                        subtract_from_mean)

# 이미지를 출력합니다.
plt.imshow(image_binarized, cmap="gray"), plt.axis("off")
plt.show()
# cv2.ADAPTIVE_THRESH_MEAN_C를 적용합니다.
image_mean_threshold = cv2.adaptiveThreshold(image_grey,
                                             max_output_value,
                                             cv2.ADAPTIVE_THRESH_MEAN_C,
                                             cv2.THRESH_BINARY,
                                             neighborhood_size,
                                             subtract_from_mean)

# 이미지를 출력합니다.
plt.imshow(image_mean_threshold, cmap="gray"), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.10 배경 제거<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 이미지를 로드하고 RGB로 변환합니다.
image_bgr = cv2.imread('images/plane_256x256.jpg')
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

# 사각형 좌표: 시작점의 x, 시작점의 y, 너비, 높이
rectangle = (0, 56, 256, 150)

# 초기 마스크를 만듭니다.
mask = np.zeros(image_rgb.shape[:2], np.uint8)

# grabCut에 사용할 임시 배열을 만듭니다.
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

# grabCut을 실행합니다.
cv2.grabCut(image_rgb, # 원본 이미지
            mask, # 마스크
            rectangle, # 사각형
            bgdModel, # 배경을 위한 임시 배열
            fgdModel, # 전경을 위한 임시 배열
            5, # 반복 횟수
            cv2.GC_INIT_WITH_RECT) # 사각형을 사용한 초기화

# 배경인 곳은 0, 그외에는 1로 설정한 마스크를 만듭니다.
mask_2 = np.where((mask==2) | (mask==0), 0, 1).astype('uint8')

# 이미지에 새로운 마스크를 곱해 배경을 제외합니다.
image_rgb_nobg = image_rgb * mask_2[:, :, np.newaxis]

# 이미지를 출력합니다.
plt.imshow(image_rgb_nobg), plt.axis("off")
plt.show()
# 마스크를 출력합니다.
plt.imshow(mask, cmap='gray'), plt.axis("off")
plt.show()
# 마스크를 출력합니다.
plt.imshow(mask_2, cmap='gray'), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.11 경계선 감지하기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image_gray = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 픽셀 강도의 중간값을 계산합니다.
median_intensity = np.median(image_gray)

# 중간 픽셀 강도에서 위아래 1 표준 편차 떨어진 값을 임계값으로 지정합니다.
lower_threshold = int(max(0, (1.0 - 0.33) * median_intensity))
upper_threshold = int(min(255, (1.0 + 0.33) * median_intensity))

# 캐니 경계선 감지기를 적용합니다.
image_canny = cv2.Canny(image_gray, lower_threshold, upper_threshold)

# 이미지를 출력합니다.
plt.imshow(image_canny, cmap="gray"), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.12 모서리 감지<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image_bgr = cv2.imread("images/plane_256x256.jpg")
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
image_gray = np.float32(image_gray)

# 모서리 감지 매개변수를 설정합니다.
block_size = 2
aperture = 29
free_parameter = 0.04

# 모서리를 감지합니다.
detector_responses = cv2.cornerHarris(image_gray,
                                      block_size,
                                      aperture,
                                      free_parameter)

# 모서리 표시를 부각시킵니다.
detector_responses = cv2.dilate(detector_responses, None)

# 임계값보다 큰 감지 결과만 남기고 흰색으로 표시합니다.
threshold = 0.02
image_bgr[detector_responses >
          threshold *
          detector_responses.max()] = [255,255,255]

# 흑백으로 변환합니다.
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 이미지를 출력합니다.
plt.imshow(image_gray, cmap="gray"), plt.axis("off")
plt.show()
# 가능성이 높은 모서리를 출력합니다.
plt.imshow(detector_responses, cmap='gray'), plt.axis("off")
plt.show()
# 이미지를 로드합니다.
image_bgr = cv2.imread('images/plane_256x256.jpg')
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 감지할 모서리 개수
corners_to_detect = 10
minimum_quality_score = 0.05
minimum_distance = 25

# 모서리를 감지합니다.
corners = cv2.goodFeaturesToTrack(image_gray,
                                  corners_to_detect,
                                  minimum_quality_score,
                                  minimum_distance)
corners = np.float32(corners)

# 모서리마다 흰 원을 그립니다.
for corner in corners:
    x, y = corner[0].astype('int')
    cv2.circle(image_bgr, (x,y), 10, (255,255,255), -1)

# 흑백 이미지로 변환합니다.
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 이미지를 출력합니다.
plt.imshow(image_rgb, cmap='gray'), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.13 머신러닝 특성 만들기<jupyter_code># 이미지를 로드합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 흑백 이미지로 로드합니다.
image = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 이미지를 10x10 픽셀 크기로 변환합니다.
image_10x10 = cv2.resize(image, (10, 10))

# 이미지 데이터를 1차원 벡터로 변환합니다.
image_10x10.flatten()
plt.imshow(image_10x10, cmap="gray"), plt.axis("off")
plt.show()
image_10x10.shape
image_10x10.flatten().shape
# 컬러 이미지로 로드합니다.
image_color = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_COLOR)

# 이미지를 10 × 10 픽셀 크기로 변환합니다.
image_color_10x10 = cv2.resize(image_color, (10, 10))

# 이미지 데이터를 1차원 벡터로 변환하고 차원을 출력합니다.
image_color_10x10.flatten().shape
# 흑백 이미지로 로드합니다.
image_256x256_gray = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)

# 이미지 데이터를 1차원 벡터로 변환하고 차원을 출력합니다.
image_256x256_gray.flatten().shape
# 컬러 이미지로 로드합니다.
image_256x256_color = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_COLOR)

# 이미지 데이터를 1차원 벡터로 변환하고 차원을 출력합니다.
image_256x256_color.flatten().shape<jupyter_output><empty_output><jupyter_text>8.14 평균 색을 특성으로 인코딩하기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# BGR 이미지로 로드합니다.
image_bgr = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_COLOR)

# 각 채널의 평균을 계산합니다.
channels = cv2.mean(image_bgr)

# 파랑과 빨강을 바꿉니다(BGR에서 RGB로 만듭니다)
observation = np.array([(channels[2], channels[1], channels[0])])

# 채널 평균 값을 확인합니다.
observation
# 이미지를 출력합니다.
plt.imshow(observation), plt.axis("off")
plt.show()<jupyter_output><empty_output><jupyter_text>8.15 컬러 히스토그램을 특성으로 인코딩하기<jupyter_code># 라이브러리를 임포트합니다.
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 이미지를 로드합니다.
image_bgr = cv2.imread("images/plane_256x256.jpg", cv2.IMREAD_COLOR)

# RGB로 변환합니다.
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

# 특성 값을 담을 리스트를 만듭니다.
features = []

# 각 컬러 채널에 대해 히스토그램을 계산합니다.
colors = ("r","g","b")

# 각 채널을 반복하면서 히스토그램을 계산하고 리스트에 추가합니다.
for i, channel in enumerate(colors):
    histogram = cv2.calcHist([image_rgb], # 이미지
                        [i], # 채널 인덱스
                        None, # 마스크 없음
                        [256], # 히스토그램 크기
                        [0,256]) # 범위
    features.extend(histogram)

# 샘플의 특성 값으로 벡터를 만듭니다.
observation = np.array(features).flatten()

# 처음 다섯 개의 특성을 출력합니다.
observation[0:5]
# RGB 채널 값을 확인합니다.
image_rgb[0,0]
# 판다스를 임포트합니다.
import pandas as pd

# 예시 데이터를 만듭니다.
data = pd.Series([1, 1, 2, 2, 3, 3, 3, 4, 5])

# 히스토그램을 출력합니다.
data.hist(grid=False)
plt.show()
# 각 컬러 채널에 대한 히스토그램을 계산합니다.
colors = ("r","g","b")

# 컬러 채널을 반복하면서 히스토그램을 계산하고 그래프를 그립니다.
for i, channel in enumerate(colors):
    histogram = cv2.calcHist([image_rgb], # 이미지
                        [i], # 채널 인덱스
                        None, # 마스크 없음
                        [256], # 히스토그램 크기
                        [0,256]) # 범위
    plt.plot(histogram, color = channel)
    plt.xlim([0,256])

# 그래프를 출력합니다.
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12696872434127043, 'fraction_numerical': 0.04045681869075166, 'mean_word_length': 3.5463182897862233, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 66, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 21, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '477831', 'license': 'MIT', 'n_tokens_mistral': 7355, 'n_tokens_neox': 7905, 'n_words': 1159, 'path': '08.ipynb', 'repo_name': 'rickiepark/machine-learning-with-python-cookbook', 'size': '13397'}