画像のデータ構造を理解して3値化を行う
1. 誰に向けた記事か
・pythonを勉強している人
・OpenCVに興味がある初心者
・画像の二値化をやりたい人
※初心者向けにpythonの勉強法とその手順を記事にしました。
2. はじめに
以前、OpenCVに標準で搭載されている関数を使って、簡単に画像の二値化を行いました。
今回、3値化を行っています。
OpenCVに3値化の標準関数はないので、自分で作ってみます。
3. コードと実行結果と説明
3.1 3値化とは何か
3値化とは画像を白と黒と灰色の3つの色で表すことです。
2値化は白と黒だけで表す処理だったので、3値化はもう一つ色を増やしたと考えられます。
下の画像は左が元画像、中央が二値化、右が3値化です。
ヒストグラムで見ると何をしてるか分かりやすいです。
以下が元画像のヒストグラムです。
黒(=0)から白(=255)まで広く分布していることが分かります。
2値化すると以下のヒストグラムになります。
2値化とは画像を白と黒だけに変換する処理だったので、黒(=0)と白(=255)だけピークがあることが分かります。
3値化すると以下のヒストグラムになります。
3値化なので白(=255)と黒(=0)以外に灰色(=100)にもピークがあることが分かります。
なお灰色の画素値は自分で指定できます。私は今回100にしましたが70や150にしても問題ありません。
3.2 説明1:画像を読み込み大きさを取得
まずこれまで通りcv2.imread()で画像を読み込みます。
また後ほど3値化の処理で使うので、shapeを使って画像の大きさを取得します。
shapeは画像の縦と横の大きさを返します。
今回は400×600の大きさの画像を使っているので、height=400、width=600になります。
3.3 説明2:3値化の閾値を決定
次に3値化の閾値を決めていきます。
今回は画素値が100以下は白(=0)に、画素値が100~150の間なら灰色(=100)に、画素値が100以上なら黒(=255)にします。
そのためのパラメータを上記コードで決めています。
3.4 説明3:3値化をする
次に3値化をしていきます。
まず画像のデータ構造について説明します。
imread()で画像を読みこんだ時に、pythonでどんな構造で取り込まれるかを以下の文で確認しましょう。
結果は次のように行列になります。
この行列の見方ですが、行列の位置と画像の位置が対応しており、値は色になります。
つまり0行0列目の88は、画像の左上の画素値が88(=黒に近い灰色)ということになります。その横の0行1列目の87は、画像の左上から右に1つずれた画素の値が87(=黒に近い灰色)ということになります。
イメージは以下の画像です。
例えば左上の画素値が88、右上の画素値が66、左下の画素値が137、右下の画素値が221になります。このように画像内の全ての位置と画素値が行列で書かれています。
そこでfor文を使って左上から順番に全ての画素値に対して判定を行い、画素値が100以下は白(=0)に、画素値が100~150の間なら灰色(=100)に、画素値が100以上なら黒(=255)にしています。
4. 最後に
次回もOpenCVを使って簡単な画像処理を行ってみたいと思います。