OpenCVで二値化は比較的簡単に実施可能ですが、いざ二値化をしてみると
うまく分離できなくて、画像の特徴が表せない!
画像の違いがはっきりしないな・・・
という悩みを持った方はいませんか?今回はOpenCVの二値化について、簡単に二値化をするところから一歩踏み込んだ内容を確認していきたいと思います。
OpenCVとは
OpenCVはオープンソースのコンピュータビジョン用ライブラリです。主に
- 画像・動画の読み込み
- 画像処理
- 画像認識
などを実施ずることが可能です。
OpenCV全般に関しては、以下の記事でも取り扱っていますので、参考にしてください。
OpenCVのインストールから全般的な使い方に関しては、以下の記事でも取り扱っていますので、参考にしてください。
OpenCVの二値化
「二値化」とは、その名の通り画像を「白」と「黒」の2色に変換する処理のことです。その際に閾値を決め、その閾値に従って二値化を行います。
二値化を行うことで、画像を鮮明にしたり単純にしたりすることができるので分析の際に多く使われます。
しかし単純に二値化をするだけでは、画像を鮮明にしたくて二値化したものの、下の画像のように全体的にもやっとした画像になってしまうこともあります。
今回はいろいろな操作をすることによりきれいに二値化できないか試してみたいと思います。
openCV二値化の操作
まずは二値化の操作をおさらいしておきましょう。
img = cv2.imread('./Sample.jpg' ,0)
thr, img_th = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
cv2.imshow('Image', img_th)
cv2.waitKey()
img = cv2.imread('./Sample.jpg' ,0)
まずは「cv2.imread()」で対象となる画像を読み込んでいます。カッコの中は一つ目が読み込む画像、二つ目の「0」はグレースケールで読み込むことを指定しています。
thr, img_th = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
「thr, img_th = cv2.threshold()」の部分で二値化を行っています。2変数が取り出され、1つ目、今回の場合は「thr」には閾値が入ります。2つ目、今回の場合は「img_th」に二値化されたデータが入ります。
引数は、前から順番に「入力する画像」「閾値(下限)」「閾値(上限)」「閾値指定方法」です。
4つ目の閾値指定方法を以下にまとめておきます。
- cv2.THRESH_BINARY:閾値(下限)以下の値を0、それ以外の値を閾値(上限)にして2値化を行います。
- cv2.THRESH_BINARY_INV:閾値(下限)以下の値を閾値(上限)、それ以外の値を0にして2値化を行います。
- cv2.THRESH_TRUNC:閾値(下限)以下の値はそのままで、それ以外の値を閾値(上限)にします。
- cv2.THRESH_TOZERO:閾値(下限)以下の値を0、それ以外の値はそのままにします。
- cv2.THRESH_TOZERO_INV:閾値(下限)以下の値はそのままで、それ以外の値を0にします。
- cv2.THRESH_OTSU:大津の手法で閾値を自動的に決める場合に指定します。
- cv2.THRESH_TRIANGLE:ライアングルアルゴリズムで閾値を自動的に決める場合に指定します。
OpenCV二値化の閾値の調整について
閾値を自動で設定する
さきほど手動で設定した場合になんとなくうまく分けることができなかったので、自動で閾値を設定してみましょう。
img = cv2.imread('./Sample.jpg' ,0)
thr, img_th = cv2.threshold(img, 100, 255, cv2.THRESH_OTSU)
cv2.imshow('Image', img_th)
cv2.waitKey()
2行目の閾値分離方法を「cv2.THRESH_OTSU」大津の二値化に変更してみました。この時に使用した閾値は、2行目で「thr」に格納しているので、これを確認すると数値がわかります。
今回使用した大津の二値化ですが、画像内に存在する画素をヒストグラムに取り、左側の黒に属するクラスと、右側の白に属するクラスに分け、一番分離ができる部分で閾値を自動で決める方法です。
よい閾値を探してみる
list1 = [25, 50, 75, 100, 125, 150, 175, 200]
img = cv2.imread('./Sample.jpg' ,0)
plt.figure(figsize=(20, 10))
for i, j in enumerate(list1):
plt.subplot(2, 4, i+1)
thr, img_th = cv2.threshold(img, j, 255, cv2.THRESH_BINARY)
img_th = cv2.cvtColor(img_th, cv2.COLOR_RGB2BGR)
plt.title(f'threshold:{j}')
plt.imshow(img_th)
実際に閾値によって画像がどのように変化するかはやってみるのが一番なので、グリッドサーチ的に閾値を変化させ二値化をしてみました。実際には大津の方法であたりをつけた後、さらにこの方法で確認すると好みの値に仕上がると思います。
list1 = [25, 50, 75, 100, 125, 150, 175, 200]
img = cv2.imread('./Sample.jpg' ,0)
実際に試してみる閾値をリストで渡してやります。その後、二値化するデータを読み込みます。
plt.figure(figsize=(20, 10))
画像を書く準備をします。今回は一覧で表示したいので、matplotlibで描画する前提にしています。
for i, j in enumerate(list1):
for文でリストの内容分だけ二値化をします。enumerateはlistの内容と別に、試行回数を0から順番に出力します。今回の場合だと
- i=0, j=25
- i=1, j=50
- i=2, j=75
- ・・・
- i=7, j=200
の順でi, jに数値が入った状態でfor文が回ります。
plt.subplot(2, 4, i+1)
for文ごとに画像を表示する位置を指定します。今回は「i+1」番目のところに画像を表示します。
thr, img_th = cv2.threshold(img, j, 255, cv2.THRESH_BINARY)
リストの値、for文でjの部分に代入した値で二値化の処理を行います。
img_th = cv2.cvtColor(img_th, cv2.COLOR_RGB2BGR)
cv2はRGBで処理をしているのに対し、matplotlibはBGRで処理をしているので変換を行います。変換を行わないとこのような色で表示されます。
plt.title(f'threshold:{j}')
plt.imshow(img_th)
最後にタイトルを設定して、画像を描画します。
データサイエンスを学習するならTech Teacherで!
『Tech Teacher』3つの魅力
魅力1. オーダーメイドのカリキュラム
『Tech Teacher』では、決められたカリキュラムがなくオーダーメイドでカリキュラムを組んでいます。「質問だけしたい」「相談相手が欲しい」等のご要望も実現できます。
魅力2. 担当教師によるマンツーマン指導
Tech Teacherでは、完全マンツーマン指導で目標達成までサポートします。
東京大学を始めとする難関大学の理系学生・院生・博士の教師がが1対1で、丁寧に指導しています。
そのため、理解できない箇所は何度も分かるまで説明を受けることができます。
魅力3. 3,960円/30分で必要な分だけ受講
Tech Teacherでは、授業を受けた分だけ後払いの「従量課金制」を採用しているので、必要な分だけ授業を受講することができます。また、初期費用は入会金22,000円のみです。一般的なプログラミングスクールとは異なり、多額な初期費用がかからないため、気軽に学習を始めることができます。
まとめ
・魅力1. 担当教師によるマンツーマン指導
・魅力2. オーダーメイドのカリキュラム
・魅力3. 3,960円/30分で必要な分だけ受講
質問のみのお問い合わせも受け付けております。
『Tech Teacher』3つの魅力
魅力1. オーダーメイドのカリキュラム
『Tech Teacher』では、決められたカリキュラムがなくオーダーメイドでカリキュラムを組んでいます。「質問だけしたい」「相談相手が欲しい」等のご要望も実現できます。
魅力2. 担当教師によるマンツーマン指導
Tech Teacherでは、完全マンツーマン指導で目標達成までサポートします。
東京大学を始めとする難関大学の理系学生・院生・博士の教師がが1対1で、丁寧に指導しています。
そのため、理解できない箇所は何度も分かるまで説明を受けることができます。
魅力3. 3,960円/30分で必要な分だけ受講
Tech Teacherでは、授業を受けた分だけ後払いの「従量課金制」を採用しているので、必要な分だけ授業を受講することができます。また、初期費用は入会金22,000円のみです。一般的なプログラミングスクールとは異なり、多額な初期費用がかからないため、気軽に学習を始めることができます。
まとめ
・魅力1. 担当教師によるマンツーマン指導
・魅力2. オーダーメイドのカリキュラム
・魅力3. 3,960円/30分で必要な分だけ受講
質問のみのお問い合わせも受け付けております。
まとめ
今回はいくつかの方法で二値化を試してみました。二値化はいろいろな局面で非常に有効な手段になりえますが、うまく二値化できずに画像がまっくろになったり、白飛びしたような画像になってしまったことも多々あると思います。
今回の内容を確認いただき、うまく二値化を使いこなしていただければと思います。