
今すぐ試したい!機械学習・深層学習(ディープラーニング)画像認識プログラミングレシピ [ 川島 賢 ]
こんにちは、monachan_papaです。
スマホのカメラで日々、色々な写真を撮るのがもう当たり前の世の中ですね。
私は写真を趣味にしているわけではないですが、撮ることが好きです。撮った写真を必要に応じて加工するのも。
どこまでも楽しめる無限の可能性が写真にはあります。写真のプロでなくても、カメラ愛好家でもなくても構わない、そんな魅力が詰まっています。
ということで、今回はPythonの写真関連のテーマを扱います。
いわゆる画像処理です。その中でも、輪郭抽出(エッジ抽出) について解説します。
この機能自体は、写真加工アプリを使えば簡単にできます。でも、自分でPythonを使って実装できたら楽しいと思いませんか?
本テーマを読むことにより、以下のことが理解できるようになり、画像処理の楽しさを体験することができます。
- 輪郭抽出の仕組み
- ピクセル関連の知識
- 画像の輪郭をPythonで抽出し出力する
輪郭抽出とは?
人間が「物体」の認識をするとき、どうやっているかをまず考えてみます。
どれくらいの大きさをしているのか、形状はどうなのか、色はどうなのか。パッと思いつくのはこんなところでしょう。
これらを「輪郭」という観点で考えてみると、人間は色の変化、影の様子をもとに認識しています。試しに、目を細めて目の前にあるものを見ると、このことが大変理解できるはずです。
一方、写真加工アプリはどうなのか。実は、人間とやっていることの基本は同じです。
画像の濃淡・色の情報を見ながら、「このピクセルについては、隣りのピクセルと比べて値が急激に変化しているぞ!」というところを輪郭と判断しています。
つまり、この急激な変化は、ピクセルごとに隣りのピクセル(X軸方向、Y軸方向)との差分をとることで算出できます。
輪郭抽出の実装
いよいよ実装です。以下の手順で行います。
- モジュールインポート
- もと画像読み込み
- もと画像サイズ取得
- 輪郭出力用のキャンバス生成
- もと画像のグレースケール変換
- 輪郭抽出
なお、テスト用の画像は私の推しである 名古屋のちんどん べんてんや マーサさんの写真を使います。
モジュールインポート
定番モジュールの matplotlib.pyplot、PILのImage だけあればOKです。
numpy はグレイスケールの説明用に使っているので、インポートしているだけです。輪郭抽出自体には使っていません。
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
もと画像読み込み
もと画像を読み込んで表示します。
src_img = Image.open('martha.JPG')
plt.imshow(src_img)
plt.show()
もと画像サイズ取得
輪郭出力用のキャンバスをこの後用意するので、もと画像サイズをもとに、サイズ取得しておきます。
w, h = src_img.size
w, h
(690, 920)
輪郭出力用のキャンバス生成
輪郭出力用のキャンバスを生成します。
このキャンバスにピクセル単位で輪郭を描画していきます。
dst_img = Image.new('RGB', (w, h))
plt.imshow(dst_img)
plt.show()
もと画像のグレースケール変換
画像処理において、定番の処理です。
グレースケールは、白から黒の濃淡 だけで表現する画像です。0〜255までの明るさ情報だけで表現されているので、取り扱いもシンプルです。よって、処理も高速です。
src_img = src_img.convert('L')
plt.imshow(src_img, cmap='gray')
plt.show()
各ピクセルの値は、以下のようになっています。(※量が多いので、部分表示になっています。)
np.array(src_img)
array([[136, 136, 136, ..., 92, 92, 92],
[135, 136, 136, ..., 92, 92, 92],
[135, 136, 136, ..., 92, 92, 92],
...,
[190, 190, 190, ..., 75, 71, 70],
[190, 190, 190, ..., 72, 70, 70],
[190, 190, 190, ..., 69, 69, 69]], dtype=uint8)

今すぐ試したい!機械学習・深層学習(ディープラーニング)画像認識プログラミングレシピ [ 川島 賢 ]
輪郭抽出
ピクセルごとに隣りのピクセル(X軸方向、Y軸方向)との差分をとるわけなので、二重ループにすることですべてのピクセルにアクセスできます。
そして、プロットX軸方向の差分、Y軸方向の差分。この2つの差分合計が10以上であれば、白色をプロットしています。それ以外は黒色をプロットします。
この10以上という条件(閾値) は必要に応じて、変えればOKです。
for y in range(0, h-1):
for x in range(0, w-1):
# 差分計算
diff_x = src_img.getpixel((x+1, y)) - src_img.getpixel((x, y))
diff_y = src_img.getpixel((x, y+1)) - src_img.getpixel((x, y))
diff = diff_x + diff_y
# 差分を出力
if diff >= 10:
dst_img.putpixel((x, y), (255, 255, 255))
else:
dst_img.putpixel((x, y), (0, 0, 0))
plt.imshow(dst_img)
plt.show()
以上で、輪郭抽出についての解説を終わります。画像処理の楽しさが体感できたでしょうか?
Pythonによる画像処理で出来ることは、この他にもたくさんあります。ディープ・ラーニングも取り入れれば、もっとすごいことも可能となります。スマホの顔認証など身近な例ですね。
画像処理にもっと詳しく触れてみたい!という御方は、今すぐ試したい!機械学習・深層学習(ディープラーニング)画像認識プログラミングレシピ [ 川島 賢 ]が大変おすすめです。もし、画像処理でやってみたい事がすぐにでも思いつかない場合でも、お題がちゃんと用意されています。
例えば、犬なのか猫なのかを認識する犬猫認識など。Pythonで画像処理をもっと楽しみましょう。

今すぐ試したい!機械学習・深層学習(ディープラーニング)画像認識プログラミングレシピ [ 川島 賢 ]
また、爆速で Python画像処理 を学びたい御方にはプログラミングスクールを考えるのも、ひとつの手です。独学よりも効果が出やすいですが、いかんせん投資がけっこうかかります。しかし、techgymというスクールは通うか通わないかは別として、無料のサンプルテキスト&解説動画がもらえます。これをとりあえず getしてまずは試しに体験学習するのもありでしょう。

コメント