Pillow のImage.convert メソッドによる二値化処理の境界を調べる

はじめに、以前書いた記事を引用します。

一方、Pillow のbilevel におけるconvert の説明によると、

If dither is NONE, all values larger than 128 are set to 255 (white), all other values to 0 (black).

とあるので、128の値を持つピクセルは0になるのではないかと判断しおります。 しかしこの結果を考えると、Pillow のconvert による二値化では128の値を持つピクセルは255になるのではないかと思います(未検証)。

今回この未検証事項について検証しました。

環境

本題

調査に用いたコードは以下の通りです。

# -*- coding: utf-8 -*-

from PIL import Image, ImageDraw, ImageFont

def createTestImage():
    img = Image.new('L', (960, 540))
    font = ImageFont.truetype(font='meiryo.ttc', size=24)
    draw = ImageDraw.Draw(img)

    vals = [x + 126 for x in range(4)]
    ax = img.size[0] / len(vals)
    for i, val in enumerate(vals):
        tl = (i * ax, 0)
        br = ((i + 1) * ax, img.size[1])
        draw.rectangle([tl, br], fill=val)
        draw.text(tl, str(val), fill=0, font=font)

    img.save('L126-129.png')
    return img

def convert(in_img):
    img = in_img.convert('1', dither=Image.NONE)
    img.save('L126-129_output.png')

if __name__ == '__main__':
    img = createTestImage()
    convert(img)

上記コードのcreateTestImage 関数で生成する画像がこちらです。 一見すると一色のグレースケール画像ですが、 幅を4等分して左から126, 127, 128, 129 となっています。 f:id:kakashibata:20190224171944p:plain 結果で出力される画像がこちらです。 f:id:kakashibata:20190224171951p:plain この結果、127以下が黒で128以上が白になることがわかりました。