画像二値化
ithat.me
このサイトを参考にしてPythonで実装した.
PILでGlayScaleにする方法はあるそうだが今回は敢えて使わずに実装した.
#coding:utf-8 from PIL import Image from PIL import ImageDraw from random import randint from os.path import exists from os import mkdir from math import fabs from random import random from copy import deepcopy from math import log def drawPicture(Pic,size,result_file_path,result_file_name,sigma): im = Image.new("RGB",size) x_size = len(Pic[0]) y_size = len(Pic[1]) for x in range(x_size): for y in range(y_size): im.putpixel((x,y),Pic[x][y]) if not exists(result_file_path): mkdir(result_file_path) result_file_name+="sigma_"+str(sigma) im.save(result_file_path+result_file_name,"PPM") del im def main(): #環境変数 file_name = "Mandrill1.ppm" sigma = int() result_file_path = "./binarizatino/result2/" result_file_name = "" #画像の読み込み print("original picture name:",file_name) im = Image.open(file_name) #RGBに変換 rgb_im = im.convert('RGB') #画像サイズを取得 size = rgb_im.size#(x:size[0],y:size[1]) print("original picture size:",size) #画像のピクセルデータ Original = [[0 for _ in range(size[1])] for __ in range(size[0])] Original_luminance = [[0 for _ in range(size[1])] for __ in range(size[0])] Result = [[0 for _ in range(size[1])] for __ in range(size[0])] Histgram = [0 for _ in range(256)] #オリジナル画像のピクセルRGBをリストOriginalに格納 for x in range(size[0]): for y in range(size[1]): r,g,b = rgb_im.getpixel((x,y))#ピクセルを取得 Original[x][y] = (r,g,b) #simple binarization white = (255,255,255) black = (0,0,0) sigma1 = float() sigma2 = float() n1 = int() n2 = int() for x in range(size[0]): for y in range(size[1]): luminance = 0.299*Original[x][y][0]+0.587*Original[x][y][1]+0.114*Original[x][y][2]#輝度 := 0.299×R + 0.587×G + 0.114×B (≒ 0.3R+0.6G+0.1B) Original_luminance[x][y] = luminance Histgram[int(luminance)]+=1 INF = 1e8 res_max = -INF res_t = -INF for t in range(256): w1 = 0 #クラス1の画素数 w2 = 0 s1 = 0 s2 = 0 m1 = 0 m2 = 0 for i in range(t):#class 1 w1 += Histgram[i] s1 += Histgram[i]*i**2#gaso * (kido - heikin_kido) for i in range(t,256):#class 2 w2 += Histgram[i] s2 += Histgram[i]*i**2 if w1>0: m1 = s1/w1 if w2>0: m2 = s2/w2 tmp = w1*w2*(m1-m2)**2 if tmp>res_max: res_max = tmp res_t = t print("best t : ",res_t) for x in range(size[0]): for y in range(size[1]): luminance = 0.299*Original[x][y][0]+0.587*Original[x][y][1]+0.114*Original[x][y][2]#輝度 := 0.299×R + 0.587×G + 0.114×B (≒ 0.3R+0.6G+0.1B) if luminance < res_t: Result[x][y]=black else: Result[x][y]=white drawPicture(Result,size,result_file_path,result_file_name,sigma) if __name__ == "__main__": main()
元の画像
生成された画像