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

今日は前回途中までやったHW0の続きの部分をやる。今回のパートは画像加工を扱った
チュートリアルなので、前回よりは多少がやり甲斐があることを期待している。

スポンサーリンク

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;
# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython
%load_ext autoreload
%autoreload 2
%reload_ext autoreload
The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload
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.
「imageManip.pyにloadメソッドを実装して下のdisplayメソッドを読み込む。これら2つのメソッドは今後もノートブックに画像を表示するのに使うことになる。」

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
    ### YOUR CODE HERE
    # Use skimage io.imread
    # out = np.array(Image.open())
    out = io.imread(image_path)
    ### END YOUR CODE
    return out
image1 = load(image1_path)
image2 = load(image2_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
    ### YOUR CODE HERE
    image = image.astype(np.int8)
    out = 0.5 * np.square(image*255)
    ### END YOUR CODE
    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
    ### YOUR CODE HERE  
    #return np.dot(image[...,:3], [0.299, 0.587, 0.114])
    out = np.sum(image * np.array([3, 6, 1]) / 10, axis=2)
    ### END YOUR CODE
    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
    ### YOUR CODE HERE
    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        
    ### END YOUR CODE
    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
    ### YOUR CODE HERE
    if channel == 'L':
        out = lab[:,:,0]
    if channel == 'A':
        out = lab[:,:,1]
    if channel == 'B':
        out = lab[:,:,2]
    ### END YOUR CODE
    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
    ### YOUR CODE HERE
    if channel == 'H':
        out = hsv[:,:,0]
    if channel == 'S':
        out = hsv[:,:,1]
    if channel == 'V':
        out = hsv[:,:,2]
    ### END YOUR CODE
    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
    ### YOUR CODE HERE
    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
    ### END YOUR CODE
    return out
image_mixed = mix_images(image1, image2, channel1='R', channel2='G')
display(image_mixed)

homework0は触りの宿題にしては非常にハードだと思う。これは先がかなり思いやられる。