Python3 – matplotlibでアニメーションGIFをつくる

matplotlib.animatioを使うとアニメーションがつくれます。自分の環境ではgifで保存しようとしたら、imagemagickがなくてエラーになりました。imagemagickのインストールとかはここに書いてありました。

Imagemagick

http://www.imagemagick.org/script/binary-releases.php#windows

Imagemagickのパスをmatplotlibに設定する必要がある。下記のようにするとmatplotlibが見ている設定ファイルの場所がわかる。

import matplotlib
print(matplotlib.matplotlib_fname())

自分はユーザディレクトリ内のAnaconda3の中の下記だった。

Anaconda3\lib\site-packages\matplotlib\mpl-data\matplotlibrc

matplotlibrcの最後の行らへんに、下記行があるので、ここにImagemagickのパスを入れる。

#animation.convert_path: 'convert' # Path to ImageMagick's convert binary.

コメントを外して、下記のように入力します。入力の際、パスを「’」で囲むと下記のようなエラーになります。

animation.convert_path: D:\ImageMagick-7.0.4-Q16\magick.exe


C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py:782: UserWarning: MovieWriter imagemagick unavailable
warnings.warn(“MovieWriter %s unavailable” % writer)
Traceback (most recent call last):
File “C:/Users/hoge/hoge.py”, line 15, in
ani.save(‘sample.gif’, writer=’imagemagick’)
File “C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py”, line 810, in save
writer.grab_frame(**savefig_kwargs)
File “C:\Users\hoge\Anaconda3\lib\contextlib.py”, line 66, in __exit__
next(self.gen)
File “C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py”, line 196, in saving
self.finish()
File “C:\Users\hoge\Anaconda3\lib\site-packages\matplotlib\animation.py”, line 389, in finish
+ ‘ Try running with –verbose-debug’)
RuntimeError: Error creating movie, return code: 1 Try running with –verbose-debug

サンプルコード

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def anim():
    graphs = []
    fig = plt.figure()
    x = np.arange(-50, 50, 0.1)
    y = x ** 2
    for i in range(50):
        plt.plot(x, y)
        g = plt.plot(i, i ** 2, 'o')
        graphs.append(g)
    ani = animation.ArtistAnimation(fig, graphs, interval=50)
    plt.show()
    ani.save('anim.gif', writer='imagemagick')

if __name__ == '__main__':
    anim()

Python3 – cifar10をダウンロードして画像を表示させてみる

参考:
Convolutional Neural Networks
https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10/

上記githubに実際のコードがあります。
Cifar10というのは、10種類のカラー画像が沢山入ってるやつで、機械学習によく使われるようです。場所は下記です。
http://www.cs.toronto.edu/~kriz/cifar.html
Cifar100というのもあるようです。

データは、pythonバージョンとかバイナリバージョンとかありますが、TensorFlowが使ってるのは、バイナリバージョンです。バイナリバージョンの説明として、上記本家サイトに下記のように書いてあります。

The binary version contains the files data_batch_1.bin, data_batch_2.bin, …, data_batch_5.bin, as well as test_batch.bin. Each of these files is formatted as follows:
<1 x label><3072 x pixel>

<1 x label><3072 x pixel>
In other words, the first byte is the label of the first image, which is a number in the range 0-9. The next 3072 bytes are the values of the pixels of the image. The first 1024 bytes are the red channel values, the next 1024 the green, and the final 1024 the blue. The values are stored in row-major order, so the first 32 bytes are the red channel values of the first row of the image.

Each file contains 10000 such 3073-byte “rows” of images, although there is nothing delimiting the rows. Therefore each file should be exactly 30730000 bytes long.

There is another file, called batches.meta.txt. This is an ASCII file that maps numeric labels in the range 0-9 to meaningful class names. It is merely a list of the 10 class names, one per row. The class name on row i corresponds to numeric label i.

ダウンロード&展開

ここにダウンロードのコードをいくつか書きました。ここではTensorFlowのコードサンプルと同じくurllib.request.urlretrieveを使います。

import os
import sys
import urllib.request
import tarfile
 
url = 'http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'
dirpath = './hoge'
filename = url.split('/')[-1]
filepath = os.path.join(dirpath, filename)
def _progress(cnt, chunk, total):
  now = cnt * chunk
  if(now > total): now = total
  sys.stdout.write('\rdownloading {} {} / {} ({:.1%})'.format(filename, now, total, now/total))
  sys.stdout.flush()
urllib.request.urlretrieve(url, filepath, _progress)
tarfile.open(filepath, 'r:gz').extractall(dirpath)

展開された内容

$ ls -go
-rw-r--r-- 1       61 6月   5  2009 batches.meta.txt
-rw-r--r-- 1 30730000 6月   5  2009 data_batch_1.bin
-rw-r--r-- 1 30730000 6月   5  2009 data_batch_2.bin
-rw-r--r-- 1 30730000 6月   5  2009 data_batch_3.bin
-rw-r--r-- 1 30730000 6月   5  2009 data_batch_4.bin
-rw-r--r-- 1 30730000 6月   5  2009 data_batch_5.bin
-rw-r--r-- 1       88 6月   5  2009 readme.html
-rw-r--r-- 1 30730000 6月   5  2009 test_batch.bin

最初の1バッチがラベル、その次からは赤、緑、青の順で1024バイトずつ入ってる。画像の大きさは32 x 32(=1024)。画像は各ファイルに1万枚分ある。
(1024 x 3 + 1) x 10000 = 30,730,000(bytes)

試しに画像を表示させてみる

試しにdata_batch_1.binから1枚分取得して表示させてみます。下記のreshapeとかtransposeで頭がこんがらがったのでここテストして頭を整理しました。

import numpy as np
from PIL import Image

path = './hoge/cifar-10-batches-bin/data_batch_1.bin'
data_size = 32 * 32 * 3 + 1
with open(path, 'rb') as f:
    data = np.frombuffer(f.read(), np.uint8, count=data_size)
label = data[0]
img_arr = data[1:]
img = img_arr.reshape(3, 32, 32).transpose(1, 2, 0)
Image.fromarray(img).show()

10枚取得してラベルもあわせて表示してみる

コードサンプル

import numpy as np
from PIL import Image, ImageDraw

path = './hoge/cifar-10-batches-bin/data_batch_1.bin'
names = ['airplane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
label_size = 1
img_size = 32 * 32 * 3
data_size = label_size + img_size
data_num = 10

with open(path, 'rb') as f:
    data = np.frombuffer(f.read(), np.uint8, count=data_size*data_num)
label = np.zeros(data_num)
img_arr = np.zeros([data_num, img_size])
for i in range(data_num):
    start = i * data_size
    label[i] = data[start]
    img_arr[i] = data[start + 1 : start + data_size]
img = img_arr.reshape(data_num, 3, 32, 32).transpose(0, 2, 3, 1)

canvas = Image.new('RGB', (320, 175), (240, 240, 240))
draw = ImageDraw.Draw(canvas)
for i in range(data_num):
    num = i if i < 5 else i - 5
    x = 20 + (32 + 30) * num
    y = 20 if i < 5 else 20 + 32 + 45
    canvas.paste(Image.fromarray(np.uint8(img[i])), (x, y))
    draw.text((x, y + 32 + 10), names[int(label[i])], fill='#000000')
canvas.show()

結果

Python3 – PIL.Imageで画像を合体してテキストを書く

コードサンプル

from PIL import Image, ImageDraw

a = Image.open('img/seven.jpeg') #28 x 28
b = Image.open('img/cifar1.png') #32 x 32
b = b.resize((28, 28))
a_txt = 'seven'
b_txt = 'cifar10'

new = Image.new('RGB', (160, 100), (230, 230, 230))
new.paste(a, (20, 20))
new.paste(b, (20 + 28 + 50, 20))
draw = ImageDraw.Draw(new)
draw.text((20, 60), a_txt, fill='#000000')
draw.text((20 + 28 + 50, 60), b_txt, fill='#000000')
new.save('img/new.png')

結果

Numpy – 配列の形を変えるテスト

TensorFlowでは頻繁に配列の形を変換しますが、結構混乱して理解するのに時間がかかります。Numpy.reshapeとかNumpy.transposeの動きをシンプルな配列で確認してみます。

これから操作する配列は、下記のようなCifar10の画像データの構造をイメージしてます。
最初の4個は赤。次の4個は緑、最後の4個は青。
最初は上記が一次元の配列に格納されている状態にして、最終的にはこれを下記の並びにしたいです。縦、横、チャンネルの3次元配列にしたいということです。

[縦、横、チャンネル]

4個ずつ赤・緑・青があるとういことは、2×2の画像サイズになります。よって、配列のshapeは、[2, 2, 3]になることを想定しております。このshapeになりつつ、配列データの構造に不整合がなければ形の変換が成功したことになります。

コード

import numpy as np

arr = np.array([1, 2, 3, 4, 11, 12, 13, 14, 21, 22, 23, 24])

print('これだとダメ')
arr2 = arr.reshape(2, 2, 3)
print(arr2)
print('----------------------')

print('引数の順番に全体を分割していくと考えたら良さそう')
print('今は赤、緑、青の順に並んでるので、最初にチャンネル数で分けるしかない')
print('最初に全体を3つに分割して、次に2つ(縦)に分割して、最初に2つ(横)に分割する')
arr3 = arr.reshape(3, 2, 2)
print(arr3)
print('----------------------')

print('最終的に縦、横、チャンネルの順にしたいのでtransposeで順番変える')
arr4 = arr3.transpose(1, 2, 0)
print(arr4)

結果

これだとダメ
[[[ 1  2  3]
  [ 4 11 12]]

 [[13 14 21]
  [22 23 24]]]
----------------------
引数の順番に全体を分割していくと考えたら良さそう
今は赤、緑、青の順に並んでるので、最初にチャンネル数で分けるしかない
最初に全体を3つに分割して、次に2つ(縦)に分割して、最初に2つ(横)に分割する
[[[ 1  2]
  [ 3  4]]

 [[11 12]
  [13 14]]

 [[21 22]
  [23 24]]]
----------------------
最終的に縦、横、チャンネルの順にしたいのでtransposeで順番変える
[[[ 1 11 21]
  [ 2 12 22]]

 [[ 3 13 23]
  [ 4 14 24]]]

畳み込みフィルターで画像をぼかしてみる

畳み込みニューラルネットワークは、畳み込みフィルターを使ってますが、畳み込みフィルターを使うと画像を加工出来ます。ぼかすには、画像の明るさを周辺の明るさの平均をとってそれで埋めていくことでぼけます。

適当な画像をぼかしてみようと思います。

まずこの画像をNumpy配列として取得します。画像は、幅800px、高さ600pxです。

import numpy as np
from PIL import Image

img = np.array(Image.open('sample_pic.jpg'))
print(img.shape)

結果

(600, 800, 3)

次に5×5のフィルターを作ります。フィルターの全領域の合計が1になるようにします。

filter_size = 5
filter = np.zeros((filter_size, filter_size))
filter += 1 / (filter_size * filter_size)
print(filter)

結果

[[ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]]

このフィルターをチャンネル毎に画像の左から順に適用していきます。

new_img = np.zeros(img.shape)
for h in range(0, img.shape[0], filter.shape[0]):
    for w in range(0, img.shape[1], filter.shape[1]):
        for c in range(img.shape[2]):
            num = 0
            for hi in range(filter.shape[0]):
                for wi in range(filter.shape[1]): 
                    num += img[h + hi][w + wi][c]
            num /= filter.size
            for hi in range(filter.shape[0]):
                for wi in range(filter.shape[1]):
                    new_img[h + hi][w + wi][c] = num

画像を表示します。

Image.fromarray(np.uint8(new_img)).show()

これだとモザイクって感じなので、全体的にぼやっとさせるには、下記のようにしたらいいと思います。効率性はよろしくないと思いますが、とりあえず出来ました。変えたところは、全ピクセルで別々に平均を計算するようにしたところです。

new_img = np.zeros(img.shape)
for h in range(img.shape[0] - filter_size):
    for w in range(img.shape[1] - filter_size):
        for c in range(img.shape[2]):
            num = 0
            for hi in range(filter.shape[0]):
                for wi in range(filter_size): 
                    num += img[h + hi][w + wi][c]
            num /= filter.size
            for hi in range(filter_size):
                for wi in range(filter.shape[1]):
                    new_img[h + hi][w + wi][c] = num

TensorFlow – MNISTで機械学習してみる(入力層・出力層のみ)

MNISTを取得する

TensorFlowのチュートリアル用にMNISTが簡単に取り込めるようになっているらしい。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('.', one_hot=True)

上記を実行するとまだMNISTをダウンロードしてない場合はダウンロードしてくれる。

batch_x, batch_t = mnist.train.next_batch(100)

上記を実行すると、100件分のトレーニング用データとトレーニング用正解ラベルをもらえる。numpyの配列としてもらえる。input_data.read_data_setsの引数で、one_hot=Trueにすると、正解ラベルも正解を1、違うものを0とした配列でもらえる。

やってみること

  • MNISTのトレーニングデータで学習して、テストデータでテストする。
  • トレーニングデータは100件ずつ使って学習する。
  • 最も単純な入力層と出力層しかないものを試してみる。

コード

参考:jupyter_tfbook/Chapter02/MNIST softmax estimation.ipynb

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('.', one_hot=True)

x = tf.placeholder(tf.float32, [None, 784])
w = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
f = tf.matmul(x, w) + b
y = tf.nn.softmax(f)
t = tf.placeholder(tf.float32, [None, 10])
loss = -tf.reduce_sum(t * tf.log(y))
train_step = tf.train.AdamOptimizer().minimize(loss)

correct = tf.equal(tf.argmax(y, 1), tf.argmax(t, 1))
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))

sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())

i = 0
for _ in range(1500):
    i += 1
    batch_x, batch_t = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_x, t: batch_t})
    if i % 100 == 0:
        loss_val, acc_val = sess.run([loss, accuracy], feed_dict={x: mnist.test.images, t: mnist.test.labels})
        print ('Step: %d, Loss: %f, Accuracy: %f' % (i, loss_val, acc_val))

Step: 100, Loss: 7747.071777, Accuracy: 0.848400
Step: 200, Loss: 5439.357910, Accuracy: 0.879900
Step: 300, Loss: 4556.465332, Accuracy: 0.890900
Step: 400, Loss: 4132.032715, Accuracy: 0.896100
Step: 500, Loss: 3836.136963, Accuracy: 0.902600
Step: 600, Loss: 3657.867920, Accuracy: 0.904100
Step: 700, Loss: 3498.280762, Accuracy: 0.907500
Step: 800, Loss: 3376.391602, Accuracy: 0.909400
Step: 900, Loss: 3292.480713, Accuracy: 0.910000
Step: 1000, Loss: 3207.918213, Accuracy: 0.912700
Step: 1100, Loss: 3147.843018, Accuracy: 0.914700
Step: 1200, Loss: 3092.903320, Accuracy: 0.916300
Step: 1300, Loss: 3057.232666, Accuracy: 0.915900
Step: 1400, Loss: 3010.664307, Accuracy: 0.916200
Step: 1500, Loss: 2972.114746, Accuracy: 0.917300

Python – MNISTを使う

機械学習で使えるサンプル画像の有名なのがMNISTだそうです。0-9までの手書き文字画像と、正解ラベルデータが、トレーニング用とテスト用で分けられています。
http://yann.lecun.com/exdb/mnist/

バイナリデータになっていて、画像等は全部データとしてつながっているらしい。機械学習は画像を数値として扱う必要があります。

参考:https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/dataset/mnist.py

Pythonでダウンロード・読み込み

ダウンロード

import urllib.request
import os.path

url_base = 'http://yann.lecun.com/exdb/mnist/'
key_file = {
    'train_img':'train-images-idx3-ubyte.gz',
    'train_label':'train-labels-idx1-ubyte.gz',
    'test_img':'t10k-images-idx3-ubyte.gz',
    'test_label':'t10k-labels-idx1-ubyte.gz'
}
dataset_dir = os.path.dirname(os.path.abspath(__file__))

def _download(filename):
    file_path = dataset_dir + '/' + filename
    if os.path.exists(file_path):
        return print('already exist')
    print('Downloading ' + filename + ' ...')
    urllib.request.urlretrieve(url_base + filename, file_path)
    print('Done')

def download_mnist():
    for v in key_file.values():
       _download(v)

download_mnist()

読み込み

gzipを使います。

def load_mnist(filename):
    file_path = dataset_dir + '/' + filename
    with gzip.open(file_path, 'rb') as f:
        data = np.frombuffer(f.read(), np.uint8, offset=16)
    return data.reshape(-1, img_size)

試しに画像データを読み込んで1つ表示させてみます。

data = load_mnist(key_file['train_img'])
img1 = data[0].reshape(28, 28)
pil_img = Image.fromarray(np.uint8(img1))
pil_img.show()

手書きの5っぽい画像が表示されました。
load_mnist関数は、gzipで読み込んで、np.frombufferというので、Numpyの配列に格納してます。data.reshapeで、画像サイズの784ずつに配列を分割してます。
784ずつに分割された配列で実際には機械学習すればいいと思います。実際の画像にするために、さらに1つの画像の縦横に合わせて配列を変換してます。

amazon linux – ffmpegインストール

引用:amazon linuxにffmpegをyumでインストールする

$ wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
$ sudo rpm -ivh rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
$sudo vim /etc/yum.repos.d/centos.repo

# そのまま書く
[base]
name=CentOS-6 - Base
mirrorlist=http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os
enabled=0
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6
# 書く部分ここまで

sudo yum install -y --enablerepo=base ffmpeg-devel

FFmpeg – mac・PHPで使う

macのバージョンは、10.11.4。El Capitan。

参考: Mac OS XでFFmpegのインストールとWebM動画の作り方

brewでインストールした。ここまで長いオプションは必要ないのかもしれない。

brew install automake celt faac fdk-aac git lame \
libass libtool libvorbis libvpx \
libvo-aacenc opencore-amr openjpeg \
opus sdl schroedinger shtool speex texi2html \
theora wget x264 xvid yasm

FFmpegとは?

FFmpeg(エフエフエムペグ)は動画と音声を変換することのできるUNIX系OS生まれのフリーソフトウェアであり、libavcodec(動画/音声のコーデックライブラリ)、libavformat(動画/音声のコンテナライブラリ)、libswscale(色空間・サイズ変換ライブラリ)、libavfilter(動画のフィルタリングライブラリ)などを含む。ライセンスはコンパイル時のオプションによりLGPLかGPLに決定される。コマンドラインから使用することができる。対応コーデックが多く、多彩なオプションを使用可能なため、幅広く利用されている。

引用:FFmpeg

PHP-FFMpegを使う

最初ffmpeg-phpを使おうとしたけど、エラーでインストールできなかった。2012年で開発終了しているらしい。

PHPでffmpegを利用するには、PHP-FFMpegがおすすめです。Composer対応のモダンなPHP実装なので、PHP5.3以上のコードベースではとても扱いやすいです。

ffmpeg-phpというPHP拡張もありますが、2012年で開発が止まっているのであまりおすすめしません。

引用:FFmpegによる動画エンコードの基本

PHP-FFMpegを使ってみる。

PHP-FFMpeg

上記のREADMEに詳しく書いてあった。composerに追加してupdateしたら下記のような感じで使えるようになる。

composer.json

{
    "require": {
        "php-ffmpeg/php-ffmpeg": "~0.5"
    }
}

fuelphpのコントローラ内でテスト。保存されている動画を取得して、jpgのサムネイル画像を作成して保存している。その後、fuelphpのImageクラスでリサイズして保存した。

//ffmpegテスト
$ffmpeg = FFMpeg\FFMpeg::create(array(
	'ffprobe.binaries' => '/usr/local/bin/ffprobe',
	'ffmpeg.binaries' => '/usr/local/bin/ffmpeg'
));
$video = $ffmpeg->open(DOCROOT.'assets/movie/'.$movie['file_name']);
//		$video
//			->filters()
//			->resize(new FFMpeg\Coordinate\Dimension(320, 180))
//			->synchronize();
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(15));
$img_path = DOCROOT.'assets/movie/thumb/'.$movie['id'].'.jpg';
$frame->save($img_path);

//画像のリサイズ
//ffmpegのリサイズが効かない為
Image::load($img_path)->resize(320, null, true, true)->save($img_path);

SVGでロゴを作成してみる

SVGはベクター画像。PNGはラスター画像。ラスター画像は、1ピクセル x 1ピクセルを色で表現するもの。ベクターは頂点座標と線の種類・太さとかで表現するもの。ベクターは拡大・縮小しても頂点座標とか計算できるので、画像がぼやけたり、文字がつぶれたりしない。

XMLで書いてみる

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 70 70">
	<polygon id="poly" points="35,0 28.5,11 41.5,11" style="fill:gray;"/>
	<use xlink:href="#poly" transform="rotate(30, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(60, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(90, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(120, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(150, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(180, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(210, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(240, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(270, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(300, 35, 35)"/>
	<use xlink:href="#poly" transform="rotate(330, 35, 35)"/>
	<circle cx="35" cy="35" r="25" fill="#c21"/>
	<circle cx="35" cy="35" r="20" fill="#d80"/>
	<circle cx="35" cy="35" r="15" fill="#fff"/>
	<circle cx="35" cy="35" r="10" fill="#b50"/>
	<circle cx="35" cy="35" r="5" fill="#fb5"/>
</svg>

logicky.svgで保存したらsvgファイルが出来上がります。1KBと書いてある。

圧縮する

$ gzip logicky.svg

できたファイルを、logicky.svgzとします。これが圧縮されたSVGファイルで、ブラウザでも大体表示できます。(ローカル環境のchromでしか確認していません)サイズは385バイトと書いてある。pngで作ったロゴは64×64で3KBだから、全然違う。

WordPressにアップしようと思ったらセキュリティの関係上アップロードできません的なエラーが表示された。SVGに対応していないらしい。

HTMLで表示させる

<html>
<head></head>
<body>
<h1>Test</h1>
<img src="logicky.svgz" width=100 height=100>
<p>上記はSVGロゴです。</p>
</body>
</html>

スクリーンショット 2015-09-29 5.34.59

imgタグのwidthとheightを500に変えるだけで、拡大された画像がきれいに表示されます。

スクリーンショット 2015-09-29 5.35.38

Python – NumPyで画像を配列として取得する

from PIL import Image
from numpy import *

im  = array(Image.open('img.jpg').convert('L'))
print(im.shape, im.dtype)
print(im)

(533, 800) uint8
[[156 159 162 …, 135 132 130]
[156 155 155 …, 133 132 133]
[155 153 155 …, 134 133 131]
…,
[ 87 88 85 …, 71 71 70]
[ 86 87 87 …, 70 72 73]
[ 89 95 95 …, 74 73 73]]

と表示される。最初の行のタプルは、(行数、列数、色数)を表してる。上記はグレースケールに変換しており、その場合は、色数は表示されない。uint8は、要素のデータ型。通常、画像は符号なし8ビット整数で符号化されるらしい。im自体を出力したら上記のような配列が表示された。

im  = array(Image.open('img.jpg'))
print(im.shape, im.dtype)

これだとグレースケール変換していないので、下記のように色数も表示される。赤、緑、青という並びなんだろうか。
(533, 800, 3) uint8

im  = array(Image.open('img.jpg'))
print(im)

これだと、色が3色があるので、配列は下記のようになっている。

[[[150 156 178]
[153 159 181]
[154 162 183]
…,
[121 137 163]
[119 134 163]
[116 131 162]]

[[148 156 177]
[149 155 177]
[149 155 177]
…,
[119 135 161]
[118 134 160]
[119 134 165]]

[[147 155 176]
[147 153 175]
[149 155 177]
…,
[120 136 162]
[119 135 161]
[118 132 167]]

…,
[[ 88 88 86]
[ 88 89 84]
[ 86 86 84]
…,
[ 72 71 76]
[ 72 71 76]
[ 71 70 75]]

[[ 87 87 85]
[ 87 88 83]
[ 88 88 86]
…,
[ 69 70 74]
[ 71 72 76]
[ 72 73 77]]

[[ 91 90 86]
[ 97 96 92]
[ 96 95 93]
…,
[ 73 74 78]
[ 72 73 77]
[ 72 73 77]]]

色を反転させて保存する

これはhtmlでつかってる0-255の数字と一緒であります。各数値を255から引くことで色を反転させることができます。

from PIL import Image
from numpy import *

im  = array(Image.open('img.jpg'))
Image.fromarray(255 - im).save('img2.jpg')

下記のようになりました。

img2

配列から画像を作ってみる

下記のようにすると、白から黒に向けたグラデーションになる。[赤、緑、青]なので、赤を全部0にすると、青緑の薄いから濃いのグラデーションになる。

from PIL import Image
import numpy as np

a = np.array([
    [
        [230,230,230],[210,210,210],[190,190,190],[170,170,170],[150,150,150]
    ],
    [
        [230,230,230],[210,210,210],[190,190,190],[170,170,170],[150,150,150]
    ],
    [
        [230,230,230],[210,210,210],[190,190,190],[170,170,170],[150,150,150]
    ],
    [
        [230,230,230],[210,210,210],[190,190,190],[170,170,170],[150,150,150]
    ],
    [
        [230,230,230],[210,210,210],[190,190,190],[170,170,170],[150,150,150]
    ],
])

Image.fromarray(np.uint8(a)).save('img2.jpg')

for row in a:
    for col in row:
        col[0] = 0

Image.fromarray(np.uint8(a)).save('img3.jpg')

img2.jpg
img2

img3.jpg
img3

Python3 – Pillowの使い方

参考:Python3.3対応画像処理ライブラリ Pillow(PIL) の使い方

from PIL import Image
import os

file_name = 'img.jpg'

#画像ファイル開く
img = Image.open(file_name)

#グレースケール変換
img_gray = img.convert('L')

#リサイズ
img_resize = img.resize((100, 100))

#ファイル形式変換
file_name_png = os.path.splitext(file_name)[0] + ".png"
try:
    img.save(file_name_png)
except:
    print("cannot convert", file_name_png)

#サムネイル作成
file_name_thumbnail = os.path.splitext(file_name)[0] + "_thumb.jpg"
img_gray.thumbnail((100, 100))
img_gray.save(file_name_thumbnail)

macでOpenCVを使う

インストール

$ port install opencv

Warning: port definitions are more than two weeks old, consider using selfupdate
Error: Insufficient privileges to write to MacPorts install prefix.

参考:YosemiteでMacportsが動かない & cmakeがインストールできない

$ sudo port selfupdate
$ sudo install opencv

opencvの場所

macportsでインストールすると、/opt/local/libにdylibファイルがあり、/opt/local/includeにhppファイルがあります。

xcodeでc++のサンプルプログラムつくる

参考:OpenCVをインストールしてXCodeで使う方法
上記に書いてあるとおりに設定します。

ウインドウが開いて1秒後に閉じるプログラム

#include "opencv2/highgui.hpp"

int main()
{
    cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
    cvWaitKey(1000);
    cvDestroyWindow("Example1");
    return 0;
}

SVG

svgを表示するには、apacheのhttpd.confに下記を追加する。

AddType image/svg+xml .svg
AddType image/svg+xml .svgz

pngをSVGに変換するとサイズが小さくなる。下記サイトで変換してくれる。
http://quasimondo.com/ZorroSVG/

SVGは大きくしても画像が綺麗になるとか書いてあったけど、写真とかは実際サイズより大きくすると汚くなった。