end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

画像をグレースケールで開き、opencv or numpy or matplotlib.pylab でヒストグラム

画像ファイルを、線画と写真に分類したいと思ったのが、きっかけ

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
from PIL import Image
import cv2
import matplotlib
matplotlib.use('Agg')
import matplotlib.pylab as plb
import numpy as np
import sys

def main():
    org_file = sys.argv[1]

    hist_by_opencv(org_file)     # opencvで算出(高速)
    hist_by_numpy(org_file)      # numpy で算出
    hist_by_matplotlib(org_file) # matplotlib.pylab で算出&描画


def hist_by_opencv(org_file):
    # 強制的にグレー画像として読む
    # http://opencv.jp/opencv-2.1/cpp/reading_and_writing_images_and_video.html
    img = cv2.imread(org_file, 0)

    histr = cv2.calcHist([img],[0],None,[256],[0,256])

    # 線画と写真を判定する為、試しに値のある度数をカウント
#    print bins_size_has_val(histr)

    bins  = range(256)
    
    plb.figure()  # 新規図
    plb.title("by opencv calcHist()")
    # ヒストグラム 描画
    # https://matplotlib.org/examples/pylab_examples/index.html
    plb.step(bins, histr)

    plb.savefig( 'hist_by_opencv.png' )


def hist_by_numpy(org_file):
    # 画像をグレースケールで開き、配列に読み込む
    img = np.array(Image.open(org_file).convert('L'))
    # ヒストグラム算出
    histr, bins = np.histogram(img, bins=256)

    plb.figure()  # 新規図
    plb.title("by numpy histogram()")
    # ヒストグラム 描画
    # https://matplotlib.org/examples/pylab_examples/index.html
    plb.step(bins[:-1], histr)

    plb.savefig( 'hist_by_numpy.png' )

def hist_by_matplotlib(org_file):
    # 画像をグレースケールで開き、配列に読み込む
    img = np.array(Image.open(org_file).convert('L'))

    plb.figure()                    # 新規図
    plb.title("by matplotlib.pylab hist()")
    plb.hist(img.flatten(),256)     # ヒストグラム算出 & 描画
    plb.savefig( 'hist_by_matplotlib.png' )


def bins_size_has_val(histr):
    bins_size = 0
    for val in histr:
        if val[0] > 0:
            bins_size += 1
    return bins_size

if __name__ == '__main__':
    main()

↑こう書くと↓このように3種類、算出&表示されます

f:id:end0tknr:20171103163202j:plain:w300

f:id:end0tknr:20171103163258p:plain:w260 f:id:end0tknr:20171103163308p:plain:w260 f:id:end0tknr:20171103163317p:plain:w260

または↓こう算出&表示されます

f:id:end0tknr:20171103163626p:plain:w300

f:id:end0tknr:20171103163644p:plain:w260 f:id:end0tknr:20171103163700p:plain:w260 f:id:end0tknr:20171103163706p:plain:w260