Pythonで写真の中の線を抽出してみた

Pythonでグレースケールの写真に書き込まれた線を抽出してみました。イメージとしては、X線写真の後処理で書き込まれた線を取り出してみるという感じです。

目次

  1. サンプル
  2. 線を取り出す手順
  3. プログラム
  4. 背景を白色にする

サンプル

グレースケールの写真に各色で書き込まれた線があります。

サンプル写真

この写真から、各色で描かれた線を取り出してみます。

線を取り出す手順

白色以外の色の部分

まず、HSV形式に色形式を変換します。S成分(彩度)がどのように分布しているか見てみると、このようになります。

彩度の分布

グレースケールの箇所は彩度が低く、色が付いているところだけが彩度が高くなっていることがわかりますね。この彩度の分布画像を2値化して、マスクとして使います。

カラー部のマスク

白色部分

まず、グレースケールに変換します。

グレースケール変換

そして、閾値を高めに設定して2値化をします。これが白色部分のマスクになります。

白色部のマスク

マスクを使って色抽出をする

2つのマスクを合成します。

マスク画像

この合成したマスクを元画像に適用します。マスクを画像に適用すると、マスクの画素の色が0の部分(上記マスク画像で黒色の部分)だけが黒色に塗りつぶされます。その結果、色の付いた線の部部だけが残って表示されるのです。

出力画像

元画像がJPEGだったりすると、JPEG特有のブロックノイズの影響で線の輪郭がうまく出ない場合があります。画像処理ソフトからの出力は、できればBMPかPNGが良いです。

プログラム

上記の処理をプログラムにすると下記のようになります。OpenCVを使いますので、予めPythonのOpenCVモジュールをインストールしておいてください。

import cv2

im = cv2.imread('sample.png', cv2.IMREAD_COLOR)

# 彩度によるマスクを生成する
# BGRからHSVへ変換する
im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

# S成分を抜き出す
im_h, im_s, im_v = cv2.split(im_hsv)

# S成分を2値化する
r_, im_s_mask = cv2.threshold(im_s, 200, 255, cv2.THRESH_BINARY)

# 白色部分のマスクを生成する
im_gr = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
r_, im_w_mask = cv2.threshold(im_gr, 253, 255, cv2.THRESH_BINARY)

# マスクを合成する
im_mask = cv2.bitwise_or(im_s_mask, im_w_mask)

# マスクを画像に適用する
im_m = cv2.bitwise_and(im, im, mask=im_mask)
cv2.imwrite('out.jpg', im_m)

背景を白色にする

背景が黒色では利用しにくい場合もありますので、背景を白色にしてみます。また、白色の線の部分は黒色に変換します。

import numpy as np
import cv2

im = cv2.imread('sample.png', cv2.IMREAD_COLOR)

# 彩度によるマスクを生成する
# BGRからHSVへ変換する
im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

# S成分を抜き出す
im_h, im_s, im_v = cv2.split(im_hsv)

# S成分を2値化する
r_, im_s_mask = cv2.threshold(im_s, 200, 255, cv2.THRESH_BINARY)

# 白色部分のマスクを生成する
im_gr = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
r_, im_w_mask = cv2.threshold(im_gr, 253, 255, cv2.THRESH_BINARY)

# マスクを画像に適用する
im[im_s_mask==0] = [255,255,255]
im[im_w_mask==255] = [0,0,0]
cv2.imwrite('out.jpg', im)

白色部分と白色以外の部分を分けて元画像に適用するので、マスクの合成は不要になります。

元画像へのマスクの適用の仕方が最初のプログラムと異なっています。こちらは、NumPyを使用した例です。

[255,255,255]の部分を変更すれば、好きな背景色に変更できます。

このプログラムの出力はこうなります。

出力画像(背景白)

公開日

広告