トップページ人工知能,実世界DBOpenCV のプログラム例Python + OpenCV 4 で濃淡画像を使う(イメージヒストグラム,ヒストグラム平坦化,ノイズ除去,2値化,輪郭抽出) (Python を使用)

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


目次

【サイト内の関連ページ】

前準備

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

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

【Python, pip の使い方】

Python, pip は,次のコマンドで起動できる.

Python 開発環境のインストール】

Python 用 opencv-python 4.3 のインストール

Windows の場合

コマンドプロンプトで次のコマンドを実行

python -m pip install -U opencv-python

Ubuntu の場合

端末で次のコマンドを実行

sudo apt -y update
sudo apt -y install libopencv-dev python3-opencv
  • ラズベリーパイ の場合

    端末で次のコマンドを実行

    sudo apt -y update
    sudo apt -y install libopencv-dev python3-opencv python3-opencv-apps
    

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

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

    画像ファイル fruits.jpg, home.jpg のダウンロードは, Windows でコマンドプロンプト管理者として実行し, 次のコマンドを実行.

    mkdir c:\image
    cd c:\image
    curl -L https://github.com/opencv/opencv/blob/master/samples/data/fruits.jpg?raw=true -o fruits.jpg
    curl -L https://github.com/opencv/opencv/blob/master/samples/data/home.jpg?raw=true -o home.jpg
    

    上のコマンドがうまく実行できないときは, 別ページを参考にダウンロードを行う.

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

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

    画像やイメージヒストグラムをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      
    2. Python プログラムを動かす.
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "fruits.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      

      [image]
    3. 別の画像で試す
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "home.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      

      [image]

    イメージヒストグラム

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

    画像やイメージヒストグラムをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. イメージヒストグラムのプロット
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "fruits.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.hist(mono.ravel(), 256, [0, 256])
      plt.show() 
      

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

      [image]
    3. 別の画像でイメージヒストグラムのプロット
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "home.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.hist(mono.ravel(), 256, [0, 256])
      plt.show() 
      

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

      [image]

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

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす.
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "fruits.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      equ = cv2.equalizeHist(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

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

      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "fruits.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      equ = cv2.equalizeHist(mono)
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      plt.hist(mono.ravel(), 256, [0, 256])
      plt.show() 
      plt.hist(equ.ravel(), 256, [0, 256])
      plt.show() 
      

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

      [image]
    3. 別の画像で試す
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "home.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      equ = cv2.equalizeHist(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

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

      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "home.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      equ = cv2.equalizeHist(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      plt.hist(mono.ravel(), 256, [0, 256])
      plt.show() 
      plt.hist(equ.ravel(), 256, [0, 256])
      plt.show() 
      

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

      [image]

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

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす.
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "fruits.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
      equ = clahe.apply(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

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

      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "fruits.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
      equ = clahe.apply(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      plt.hist(mono.ravel(), 256, [0, 256])
      plt.show() 
      plt.hist(equ.ravel(), 256, [0, 256])
      plt.show() 
      

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

      [image]
    3. 別の画像で試す
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "home.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
      equ = clahe.apply(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

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

      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      IMROOT="C:/image/"
      bgr = cv2.imread(IMROOT + "home.jpg")
      mono = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
      clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
      equ = clahe.apply(mono)
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(equ, cmap='gray')
      plt.show()
      plt.hist(mono.ravel(), 256, [0, 256])
      plt.show() 
      plt.hist(equ.ravel(), 256, [0, 256])
      plt.show() 
      

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

      [image]

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

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

    ノイズ除去

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(dst, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

    OTSU の方法による2値化

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(dst, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]
    3. 別の画像で試す
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(dst, cmap='gray')
      plt.show()
      

      画像が表示されるので確認.

      [image]

    輪郭抽出

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

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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) 
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(dst, cmap='gray')
      plt.show()
      
      cv2.drawContours(bgr, contours, -1, (0, 255, 0), 3)
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      

      画像が表示されるので確認.

      [image]

      別の画像で試す

      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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) 
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      plt.imshow(dst, cmap='gray')
      plt.show()
      
      cv2.drawContours(bgr, contours, -1, (0, 255, 0), 3)
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      

      画像が表示されるので確認.

      [image]

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

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

    画像などをプロットする. ここでは Jupyter Qt Console を使用して,プロットを行う

    1. Jupyter Qt Consoleを起動
      jupyter qtconsole
      

      [image]
    2. Python プログラムを動かす
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      

      トラッキングポイントが表示される

      [image]
    3. 別の画像で試す
      import cv2
      import numpy as np
      %matplotlib inline
      import matplotlib.pyplot as plt
      import warnings
      warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
      
      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)
      
      plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
      plt.show()
      plt.imshow(mono, cmap='gray')
      plt.show()
      

      トラッキングポイントが表示される

      [image]