#はじめに
こんにちは!
今回は2値画像を作成する際のファイル形式に関して話したいと思います。
ここでは「グレースケール画像(8bits/pixel)を2値画像(1bit/pixel)に変換する」場合を例に説明します。
pillowを使った画像変換を例に説明していますが、今回の話はファイル形式に起因するものですので、2値画像(1bit/pixel)を作る際には必ず知っておいた方がいい話です。
一方で、2値画像を0(黒)、255(白)として保存したい場合は8bits/pixelとなるため、ここで説明している形式では逆に期待に沿えません。(拡張子をJPEGなどに変更して保存してください。)
#2値画像(1bit/pixel)を保存できるファイル形式(format)は?
白と黒で描写される2値画像ですが、1画素(1pixel)を1bit(0:黒、1:白)とするのが一般的です。
ただ、ファイル形式によってはグレースケールのように1画素(1pixel)を1bit(0:黒、1:白)で保存できず、8bit(0:黒、255:白)で保存してしまう場合も存在します。(JPEGが該当します。)
そのため、1画素(1pixel)を1bit(0:黒、1:白)として保存したい場合は対応したファイル形式を選ぶ必要があります。
代表的なものとしては下記が挙げられます。
png
pbm
bmp
などなど
今回の例ではpillowを使用していますのでpillowが対応しているファイル形式かを確認します。
https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
pillowだとpngとbmpは対応していることが分かります。
今回は使用しませんが、openCVなど別のライブラリを活用する場合は改めて対応ファイル形式であるかを確認してください。
http://opencv.jp/opencv-2svn/cpp/highgui_reading_and_writing_images_and_video.html?highlight=write#imwrite
#開発環境
Windows10
python3.7.7
pillow=7.1.2
#「グレースケール画像(8bits/pixel)を2値画像(1bit/pixel)に変換する」
それでは実際にソースコードを示します。
今回はグレースケール画像(8bits/pixel)から2値画像(1bit/pixel)への変換を行っていますが、
フルカラー画像(RGB各8bits/pixel)から2値画像(1bit/pixel)への変換も可能です。
その際はif inimg.mode == "L":をコメントアウトしてください。(elseの方も忘れずに)
import os
import glob
from PIL import Image
if __name__ == "__main__":
get_dir = os.walk("./input")
#カレントディレクトリを取得
current_dir = os.getcwd()
#入力ディレクトリを取得
indir = current_dir + "\\input\\"
#出力ディレクトリを取得
outdir = current_dir + "\\output_bin\\"
# 出力用フォルダがない場合は作る
if os.path.isdir(outdir) == False:
os.mkdir(outdir)
#入力ディレクトリ内の画像を選択
all_images = glob.glob(indir + "\\*")
# それぞれの画像に対する処理
for img in all_images:
# 入力画像の画像名を取得(拡張子付き)
basename = os.path.basename(img)
print(basename)
# 入力画像の画像名から拡張子を分離
name, ext = os.path.splitext(basename)
# 2値画像に変換した画像の保存先
save_path = outdir + name + "_bin.png" # pbmやbmpでも大丈夫
#save_path = outdir + name + "_bin.bmp"
if ext != ".bat" and ext != ".txt":
with Image.open(img) as inimg:
# print("inimg mode:",inimg.mode) # inimg mode: RGB
# L(grayscale)か否かを確認する 問答無用で2値化したい場合はコメントアウトすること
if inimg.mode == "L":
conv_image = inimg.convert("1")
#print("inimg.mode:", conv_image.mode)
conv_image.save(save_path)
else:
print("inimg mode(not L):", inimg.mode)
#まとめ
今回は「グレースケール画像(8bits/pixel)を2値画像(1bit/pixel)に変換する」を例に、
2値画像(1bit/pixel)を保存する際の注意点を説明しました。
ここで説明したファイル形式(png/bmpなど)は代表的なものではありませすが、全てではありません。
ご自身の用途に合わせて他のファイル形式も色々試していただければと思います。
何かコメントがありましたらお願い致します。
(次あたりからgithubでも公開できるようにしたいです。)