トップページ -> データベース関連技術 -> コンピュータビジョン(OpenCV, Dlib などの機能とプログラム例) -> Python + OpenCV 4 で濃淡画像を使う(イメージヒストグラム,ヒストグラム平坦化,ノイズ除去,2値化,輪郭抽出)
[サイトマップへ], [サイト内検索へ]

Python + OpenCV 4 で濃淡画像を使う(イメージヒストグラム,ヒストグラム平坦化,ノイズ除去,2値化,輪郭抽出)


目次

サイト内の関連ページ


前準備

Python のインストール,pip の更新,Python 開発環境のインストール

Windows の場合

  1. Python のインストール

    Python の URL: http://www.python.org/

    インストール手順の詳細は: 別ページで説明している.

  2. pip と setuptools の更新Python 開発環境(JupyterLab, spyder)のインストール

    コマンドプロンプトを管理者として実行し,次のコマンドを実行.

    python -m pip install -U pip setuptools
    python -m pip install -U jupyterlab jupyter jupyter-console jupytext spyder
    

Ubuntu の場合

システム Python を使用(インストール操作は不要)

  1. pip と setuptools の更新Python 開発環境(JupyterLab, spyder)のインストール

    次のコマンドを実行.

    sudo apt -yV install python3-dev python3-pip python3-setuptools
    sudo apt -yV install jupyter-qtconsole jupyter-notebook python3-jupyter-client python3-jupyter-console python3-spyder spyder3
    

Python 3 用 opencv-python, matplotlib, numpy パッケージのインストール


このページで説明のために使用する画像

画像ファイル fruits.jpg, home.jpg のダウンロード

画像ファイル fruits.jpg, home.jpg のダウンロード手順は,別ページで説明している.

https://github.com/opencv/opencv/tree/master/samples/data で公開されている fruits.jpg, home.jpg を使用する(謝辞:画像の作者に感謝します)


カラー画像から濃淡画像への変換

Python プログラムを動かす.

import cv2
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
cv2.imshow("", mono)
cv2.waitKey(0)
cv2.destroyAllWindows()

※ Python プログラムを動かすために, Windows では,「python」コマンドを使う. Ubuntu では「python3」コマンドを使う.

開発環境や Python コンソール(Jupyter Qt ConsolespyderPyCharmPyScripter など)も便利である.

[image]

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

別の画像で試す

import cv2
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
cv2.imshow("", mono)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]


イメージヒストグラム

ここでのイメージヒストグラムは,画素の明るさによるヒストグラム.横軸が明るさ(右に行くほど明るい).縦軸が画素数.

import cv2
import numpy as np
from matplotlib import pyplot as plt
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.hist(mono.ravel(), 256, [0, 256])
plt.show() 

ヒストグラムが表示されるので確認.

[image]

別の画像で試す

import cv2
import numpy as np
from matplotlib import pyplot as plt
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.hist(mono.ravel(), 256, [0, 256])
plt.show() 

ヒストグラムが表示されるので確認.

[image]


ヒストグラム平坦化 (histogram equalization)

ヒストグラム平坦化は、モノクロ画像の表示をあざやかにするなどで役に立つ方法. イメージヒストグラムが平坦化するように,画素の輝度を調整する.

Python プログラムを動かす.

import cv2
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
cv2.imshow("mono", mono)
equ = cv2.equalizeHist(mono)
cv2.imshow("equ", equ)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

今度は、ヒストグラムを表示する

import cv2
import numpy as np
from matplotlib import pyplot as plt
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.hist(mono.ravel(), 256, [0, 256])
plt.show() 
equ = cv2.equalizeHist(mono)
plt.hist(equ.ravel(), 256, [0, 256])
plt.show() 

ヒストグラムが表示されるので確認.

[image]

別の画像で試す

import cv2
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
cv2.imshow("mono", mono)
equ = cv2.equalizeHist(mono)
cv2.imshow("equ", equ)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

今度は、ヒストグラムを表示する

import cv2
import numpy as np
from matplotlib import pyplot as plt
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.hist(mono.ravel(), 256, [0, 256])
plt.show() 
equ = cv2.equalizeHist(mono)
plt.hist(equ.ravel(), 256, [0, 256])
plt.show() 

ヒストグラムが表示されるので確認.

[image]

CLAHE (Contrast Limited Adaptive Histogram Equalization) によるヒストグラム平坦化

CLAHE は,輪郭線が、残りやすくなるようなヒストグラム平坦化とされる.

Python プログラムを動かす.

import cv2
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
cv2.imshow("mono", mono)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
equ = clahe.apply(mono)
cv2.imshow("equ", equ)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

今度は、ヒストグラムを表示する

import cv2
import numpy as np
from matplotlib import pyplot as plt
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.hist(mono.ravel(), 256, [0, 256])
plt.show() 
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
equ = clahe.apply(mono)
plt.hist(equ.ravel(), 256, [0, 256])
plt.show() 

ヒストグラムが表示されるので確認.

[image]

別の画像で試す

import cv2
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
cv2.imshow("mono", mono)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
equ = clahe.apply(mono)
cv2.imshow("equ", equ)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

今度は、ヒストグラムを表示する

import cv2
import numpy as np
from matplotlib import pyplot as plt
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
plt.hist(mono.ravel(), 256, [0, 256])
plt.show() 
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
equ = clahe.apply(mono)
plt.hist(equ.ravel(), 256, [0, 256])
plt.show() 

ヒストグラムが表示されるので確認.

[image]


濃淡画像のノイズを加える、ノイズを除去する

乱数を使ってノイズを加えてみる

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
h,w = mono.shape
for i in range(30000):
    x = np.random.randint(w)    
    y = np.random.randint(h)    
    mono[y][x] = np.random.randint(255)

cv2.imshow("mono", mono)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

ノイズ除去

濃淡画像には、「cv2.fastNlMeansDenoising」を使う. カラー画像に対しては,「cv2.fastNlMeansDenoisingColored」を使う. ビデオの場合には 「cv2.fastNlMeansDenoisingMulti」を使う. ここでは、一度ノイズを加えてから、処理を行っている.

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
h,w = mono.shape
for i in range(30000):
    x = np.random.randint(w)    
    y = np.random.randint(h)    
    mono[y][x] = np.random.randint(255)

dst = cv2.fastNlMeansDenoising(mono, None, 30, 10, 7)
cv2.imshow("mono", mono)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]


OTSU の方法による2値化

2値化は,画像を変換して,全ての画素が 2値になるようにすること.2値化された画像の表示は,白と黒で行っている.

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
bgr, dst = cv2.threshold(mono, 0, 255, cv2.THRESH_OTSU)
cv2.imshow("mono", mono)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

別の画像で試す

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
r, dst = cv2.threshold(mono, 0, 255, cv2.THRESH_OTSU)
cv2.imshow("mono", mono)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]


輪郭抽出

ここでの輪郭抽出は、2値化の結果を利用して輪郭を抽出している

OpenCV 4 では「contours, hierarchy = cv2.findContours ...」を使う。 OpenCV 3 では「image, contours, hierarchy = cv2.findContours」を使う

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
r, dst = cv2.threshold(mono, 0, 255, cv2.THRESH_OTSU)
# image, contours, hierarchy = cv2.findContours(dst, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
contours, hierarchy = cv2.findContours(dst, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
cv2.imshow("dst", dst)
cv2.drawContours(bgr, contours, -1, (0, 255, 0), 3)
cv2.imshow("img", bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

別の画像で試す

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
r, dst = cv2.threshold(mono, 0, 255, cv2.THRESH_OTSU)
# image, contours, hierarchy = cv2.findContours(dst, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
contours, hierarchy = cv2.findContours(dst, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
cv2.imshow("dst", dst)
cv2.drawContours(bgr, contours, -1, (0, 255, 0), 3)
cv2.imshow("img", bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

参考 Web ページ: http://end0tknr.hateblo.jp/entry/20171105/1509845707


トラッキングポイント(Shi-Tomasi の手法)

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "fruits.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
d = cv2.goodFeaturesToTrack(mono, 80, 0.01, 5, 3)
d = np.int0(d)
for i in d:
    x, y = i.ravel()
    cv2.circle(mono, (x,y), 3, 255, -1)

cv2.imshow("hoge", mono)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

別の画像で試す

import cv2
import numpy as np
IMROOT="C:/image/"
bgr = cv2.imread(IMROOT + "home.jpg")
mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
d = cv2.goodFeaturesToTrack(mono, 80, 0.01, 5, 3)
d = np.int0(d)
for i in d:
    x, y = i.ravel()
    cv2.circle(mono, (x,y), 3, 255, -1)

cv2.imshow("hoge", mono)
cv2.waitKey(0)
cv2.destroyAllWindows()

画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる

[image]

本サイトは金子邦彦研究室のWebページです.サイトマップは,サイトマップのページをご覧下さい. 本サイト内の検索は,サイト内検索のページをご利用下さい.

問い合わせ先: 金子邦彦(かねこ くにひこ) [image]