# スタンフォード大学/CS131/宿題0 PARTⅡ

チュートリアルなので、前回よりは多少がやり甲斐があることを期待している。

スポンサーリンク

## Part 2: Image Manipulation¶

#Imports the print function from newer versions of python
from __future__ import print_function

#Setup

# The Random module for implements pseudo-random number generators
import random

# Numpy is the main package for scientific computing with Python.
# This will be one of our most used libraries in this class
import numpy as np

#Imports all the methods in each of the files: linalg.py and imageManip.py
from linalg import *
from imageManip import *

#Matplotlib is a useful plotting library for python
import matplotlib.pyplot as plt
# This code is to make matplotlib figures appear inline in the
# notebook rather than in a new window.
%matplotlib inline
plt.rcParams['figure.figsize'] = 14, 8 # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

# Some more magic so that the notebook will reload external python modules;

The autoreload extension is already loaded. To reload it, use:

image1_path = './image1.jpg'
image2_path = './image2.jpg'


### Question 2.1¶

Implement the load method in imageManip.py and read the display method below. We will use these two methods through the rest of the notebook to visualize our work.

def display(img):
# Show image
plt.imshow(img)
plt.axis('off')
plt.show()

def load(image_path):
""" Loads an image from a file path
Args:
image_path: file path to the image
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
out = None
# out = np.array(Image.open())
return out

image1 = load(image1_path)

display(image1)
display(image2)

スポンサーリンク

## Question 2.2¶

Implement the change_value method by converting images according to $x_n = 0.5*x_p^2$ for every pixel, where $x_n$ is the new value and $x_p$ is the original value.
「change_valueメソッドを、$x_n$が新しい値で$x_p$が元の値である全画素に対して$x_n = 0.5*x_p^2$に従って画像を変換することで実装する。」

def change_value(image):
""" Change the value of every pixel by following x_n = 0.5*x_p^2
where x_n is the new value and x_p is the original value
Args:
image: numpy array of shape(image_height, image_width, 3)
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
out = None
image = image.astype(np.int8)
out = 0.5 * np.square(image*255)
return out

new_image = change_value(image1)
display(new_image)

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

スポンサーリンク

## Question 2.3¶

Implement the convert_to_grey_scale method and convert the image into grey scale.
「convert_to_grey_scaleメソッドを実装して画像をグレースケールに変換する。」

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import math
from skimage import color
from skimage import io

def convert_to_grey_scale(image):
""" Change image to gray scale
Args:
image: numpy array of shape(image_height, image_width, 3)
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
out = None
#return np.dot(image[...,:3], [0.299, 0.587, 0.114])
out = np.sum(image * np.array([3, 6, 1]) / 10, axis=2)
return out

grey_image = convert_to_grey_scale(image1)
display(grey_image)

スポンサーリンク

## Question 2.4¶

Implement the rgb_decomposition, in which the input image is decomposed into the three channels: R, G and B and return the image excluding the specified channel.
「入力したイメージを、R, G, Bの3つのチャンネルに分解し、指定したチャンネルを取り除いた画像を返すrgb_decompositionを実装する。」

def rgb_decomposition(image, channel):
""" Return image **excluding** the rgb channel specified
Args:
image: numpy array of shape(image_height, image_width, 3)
channel: str specifying the channel
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
out = None
image = image.astype(np.uint8)
#dic = {'b':image[:,:,0], 'g':image[:,:,1], 'r':image[:,:,2]}
#mat = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]])
#rgb = np.array(image)
#out = dic[channel.lower()]
image = image.copy().astype(np.uint8) # Make a copy
out = image
if channel == 'R':
image[:,:,0] = 0
if channel == 'G':
image[:,:,1] = 0
if channel == 'B':
image[:,:,2] = 0
return out

without_red = rgb_decomposition(image1, 'R')
without_blue = rgb_decomposition(image1, 'B')
without_green = rgb_decomposition(image1, 'G')

display(without_red)
display(without_blue)
display(without_green)

スポンサーリンク

## Question 2.5¶

Implement the lab_decomposition, in which the input image is decomposed into the three channels: L, A and B and return the values for the specified channel.
「入力したイメージを、L, A, Bの3つのチャンネルに分解し、指定したチャンネルに対する値を返すlab_decompositionを実装する。」

def lab_decomposition(image, channel):
""" Return image decomposed to just the lab channel specified
Args:
image: numpy array of shape(image_height, image_width, 3)
channel: str specifying the channel
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
lab = color.rgb2lab(image)
out = None
if channel == 'L':
out = lab[:,:,0]
if channel == 'A':
out = lab[:,:,1]
if channel == 'B':
out = lab[:,:,2]
return out

image_l = lab_decomposition(image1, 'L')
image_a = lab_decomposition(image1, 'A')
image_b = lab_decomposition(image1, 'B')

display(image_l)
display(image_a)
display(image_b)

スポンサーリンク

## Question 2.6¶

Implement the hsv_decomposition, in which the input image is decomposed into the three channels: H, S and V and return the values for the specified channel.
「入力したイメージを、H, S, Vの3つのチャンネルに分解し、指定したチャンネルに対する値を返すhsv_decompositionを実装する。」

def hsv_decomposition(image, channel='H'):
""" Return image decomposed to just the hsv channel specified
Args:
image: numpy array of shape(image_height, image_width, 3)
channel: str specifying the channel
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
hsv = color.rgb2hsv(image)
out = None
if channel == 'H':
out = hsv[:,:,0]
if channel == 'S':
out = hsv[:,:,1]
if channel == 'V':
out = hsv[:,:,2]
return out

image_h = hsv_decomposition(image1, 'H')
image_s = hsv_decomposition(image1, 'S')
image_v = hsv_decomposition(image1, 'V')

display(image_h)
display(image_s)
display(image_v)

スポンサーリンク

## Question 2.7¶

In mix_images method, create a new image such that the left half of the image is the left half of image1 and the
right half of the image is the right half of image2. If the channels are specified, exclude the specified channel for the given image.
「mix_imagesメソッドでは、画像の左半分はimage1の左半分で、右半分がimage2の右半分になる新しい画像を生成する。もし、チャンネルが指定されれば、所与の画像に対して指定チャンネルを除外する。」

#先ずは画像を半分にする方法を考える必要がある。
h, w, c = image1.shape
a = image1[:, :w//2]
plt.imshow(a)

<matplotlib.image.AxesImage at 0x7f9e9807f748>
#今度は右半分を残す。
b = image1[:, w//2:]
plt.imshow(b)

<matplotlib.image.AxesImage at 0x7f9e95f32dd8>
#次にimage2を半分にする。
b = image2[:, w//2:]
plt.imshow(b)

<matplotlib.image.AxesImage at 0x7f9e96773c50>
#最後にaとbをくっつける必要がある。
c = a+b
plt.imshow(c)

<matplotlib.image.AxesImage at 0x7f9e95f07898>
c = np.empty_like(image2)
c[:, :w//2]=a
c[:, w//2:]=b
plt.imshow(c)

<matplotlib.image.AxesImage at 0x7f9e967c92b0>

def mix_images(image1, image2, channel1, channel2):
""" Return image which is the left of image1 and right of image 2 excluding
the specified channels for each image
Args:
image1: numpy array of shape(image_height, image_width, 3)
image2: numpy array of shape(image_height, image_width, 3)
channel1: str specifying channel used for image1
channel2: str specifying channel used for image2
Returns:
out: numpy array of shape(image_height, image_width, 3)
"""
out = None
image1 = rgb_decomposition(image1, channel1)
image2 = rgb_decomposition(image2, channel2)
h, w, c = image1.shape
a = image1[:, :w//2]
b = image2[:, w//2:]
out = np.empty_like(image2)
out[:, :w//2]=a
out[:, w//2:]=b

image_mixed = mix_images(image1, image2, channel1='R', channel2='G')