虽说是刚刚学习机器学习,但还是编写了一个小小的代码,可能有不足之处,请指出与谅解。
这个代码是手势识别必不可少的一步,大致内容就是将一张手的图片转化为黑白照片,再转化为模糊的黑白照片,最后化为只有手的轮廓(黑)和背景颜色(白),代码如下:
# -*- coding:utf-8 -*-
from PIL import Image, ImageFilter
import numpy as np
def f(c):
r, g, b = c
return int(float(r)*0.21 + float(g)*0.72 + float(b)*0.07)
def ff(c):
r, g, b = c
return (r+g+b)/3
# stage 1: convert 2 gray
def rgb2gray(im):
w, h = im.size
ret = Image.new("L",(w,h))
for i in range(w):
for j in range(h):
ret.putpixel([i,j],f(im.getpixel((i, j))))
return ret
# stage 2: Gaussian Blur
def GaussianBlur(im):
ftr = ImageFilter.GaussianBlur(22.0)
new_im = im.filter(ftr)
return new_im
def OTSU(im):
w, h = im.size
arr = []
total = 0
points = w*h
for i in range(w):
for j in range(h):
c = im.getpixel((i,j))
arr.append(c)
total += c
# 颜色为x的点一共有d[x]个
d = {}
for i in range(256):
d[i] = 0
for i in arr:
d[i] += 1
# 颜色为0的点,到颜色为x的点,一共有count[x]个
# count[x] = d[0] + d[1] + ... + d[x]
count = []; count.append(d[0])
# 颜色小于等于x的点的加权和为color[x]
# color[x] = 0*d[0] + 1*d[1] + ... + x*d[x]
color = []; color.append(0)
for i in range(1, 256): # i = 1 to 255
#print i
count.append(count[i-1] + d[i])
color.append(color[i-1] + d[i]*i)
"""
print "-"*40
print count
print "-"*40
print color
"""
"""
c 为分界的颜色的灰度值
w1 = d[0] + d[1] + ... + d[c] = count[c]
w2 = d[c+1] + d[c+2] + ... + d[255]
= (d[1] + d[2] + ... + d[255]) - w1
= (w * h) - w1
u1 = (d[0]*0 + d[1]*1 + ... + d[c]*c) / (d[0] + d[1] + ... + d[c])
= color[c] / w1
u2 = (d[c+1]*(c+1) + d[c+2]*(c+2) + ... + d[255]*255) / (d[c+1] + d[c+2] + ... + d[255])
= (d[0]*0 + d[1]*1 + ... + d[255]*255 - color[c]) / w2
= (color[255] - color[c]) / w2
求c的值使得
delta = w1*w2*((u1-u2)**2)最大
"""
maxDelta = 0.0
gray = 0
for c in range(256):
w1 = count[c]
w2 = points - w1
if w1 == 0 or w2 == 0:
continue
u1 = float(color[c]) / w1
u2 = float(color[255] - color[c]) / w2
delta = w1*w2*((u1-u2)**2)
print "[w1] ", w1, "[u1] ", u1,
print "[w2] ", w2, "[u2] ", u2,
print "\t", delta, "\t", maxDelta,
if delta > maxDelta:
maxDelta = delta
gray = c
print " BINGO! ", gray
else:
print ""
return gray
def threshold(t, image):
# 二值化
intensity_array = []
w,h = image.size
for i in range(w):
for j in range(h):
intensity = image.getpixel((i,j))
if (intensity <= t):
x = 0
else:
x = 255
image.putpixel([i, j], x)
return image
#####################################################
# 程序执行过程
#####################################################
# 转换成黑白
im = Image.open('hand.jpg')
im = rgb2gray(im)
im.save("gray.jpg")
# 进行模糊
im = GaussianBlur(im)
im.save("Gaussian.jpg")
# 求二值化的分界点
g = OTSU(im)
print g
# 使用分界点进行二值化
im = threshold(g, im)
im.save("OTSU.jpg")