最近在看数字图像处理方面的东东,书看多了,就想实验一下,本想用C之类的来实现的,可是感觉太麻烦,于是就从操旧业,用python来实验更快些。当然,这稍牺牲了处理速度。后面要处理速度时再使用opencv或自己实现。
最后附上这两天的实验代码,当然这都是最基础的,如果高手发现错误之处请指出,谢谢!
#!/usr/bin/python
# -*- coding: utf-8 -*-
## desc: 数字图像处理(digital image processing)
## author: 布智道
## date: 2010.05.18
import sys
import math
import Image
import ImageDraw
## 转为YUV格式,并把颜色置灰
def rgb2yuv(filename):
img = Image.open(filename)
img_new = img.convert("YCbCr") ## 转为YUV格式
data = img_new.load()
width, height = yuv.size
for x in range(width):
for y in range(height):
data[x,y] = data[x,y][0], 0x80, 0x80 ## 颜色置灰
return img_new
## 转为灰度图
def rgb2gray(filename):
img = Image.open(filename)
img_new = img.convert("L")
return img_new
## 反转
def reverse(img):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
width, height = img.size
for x in range(width):
for y in range(height):
dst_data[x,y] = 255 - src_data[x,y] ## 反转
return img_new
## 直方图
def histogram(img):
data = img.load()
width, height = img.size
r = [0 for x in range(256)] ## 生成数组并初始为0
## 统计灰度值
for x in range(width):
for y in range(height):
r[data[x,y]] += 1
## 求平均
for x in range(256):
r[x] = r[x] * 1000 / (width * height)
## 生成直方图
img_new = Image.new("L", (512, 500)) ## 建图
draw = ImageDraw.Draw(img_new)
for x in range(256):
if x % 10 == 0:
draw.line([2*x, 0, 2*x, 500], fill=64)
for x in range(100):
if x % 10 == 0:
draw.line([0, 5*x, 512, 5*x], fill=64)
m = 500 / max(r)
for x in range(256):
draw.line([2*x, 500, 2*x, 500-r[x]*m], fill=255) ## 画线
del draw
return img_new
## 直方图均衡化
def histogram_equa(img):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
width, height = img.size
r = [0 for x in range(256)] ## 生成数组并初始为0
## 统计灰度值
for x in range(width):
for y in range(height):
r[src_data[x,y]] += 1
## 均衡化
for x in range(1, 256):
r[x] = r[x] + r[x-1]
## 求平均
for x in range(256):
r[x] = r[x] * 256 / (width * height)
for x in range(width):
for y in range(height):
dst_data[x,y] = r[src_data[x,y]]
return img_new
## 两图相加
def img_add(img1, img2):
img_new = img.copy()
dst_data = img_new.load()
data1 = img1.load()
data2 = img2.load()
w1, h1 = img1.size
w2, h2 = img2.size
w = min(w1, w2)
h = min(h1, h2)
for x in range(w):
for y in range(h):
dst_data[x,y] = data1[x,y] + data2[x,y]
return img_new
## 两图相减
def img_del(img1, img2):
img_new = img.copy()
dst_data = img_new.load()
data1 = img1.load()
data2 = img2.load()
w1, h1 = img1.size
w2, h2 = img2.size
w = min(w1, w2)
h = min(h1, h2)
for x in range(w):
for y in range(h):
dst_data[x,y] = data1[x,y] + data2[x,y]
return img_new
## 滤波器, 均值滤波, 高斯滤波
def filter(img, vect):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
width, height = img.size
l = len(vect)
r = l / 2
sum = 0
for i in range(l):
for j in range(l):
sum += vect[j]
for x in range(r, width-r):
for y in range(r, height-r):
xy = 0
for i in range(-r, r+1):
for j in range(-r, r+1):
xy += src_data[x+i,y+j] * vect[i+r][j+r]
dst_data[x,y] = (xy / sum) % 256
return img_new
## 中值滤波器
def median_value_filter(img, v):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
width, height = img.size
r = v / 2
for x in range(r, width-r):
for y in range(r, height-r):
xy = [0 for i in range(v*v)]
n = 0
for i in range(-r, r+1):
for j in range(-r, r+1):
xy[n] = src_data[x+i,y+j]
n += 1
xy.sort()
dst_data[x,y] = xy[n/2]
return img_new
## DownSample
def downsample(img, n):
width, height = img.size
new_width = width / n
new_height = height / n
img_new = Image.new("L", (new_width, new_height)) ## 建图
src_data = img.load()
dst_data = img_new.load()
for x in range(new_width):
for y in range(new_height):
dst_data[x,y] = src_data[x*n,y*n] ## 抽点
return img_new
## 二值化
def img_bin(img):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
width, height = img.size
for x in range(width):
for y in range(height):
if src_data[x,y] >= 128:
tmp = 255
else:
tmp = 0
dst_data[x,y] = tmp
return img_new
## 腐蚀
def erosion(img, point, size, v):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
px, py = point
width, height = size
r = v / 2
for x in range(r, width-r):
for y in range(r, height-r):
xy = 0
for i in range(-r, r+1):
for j in range(-r, r+1):
if src_data[px+x+i,py+y+j] == 0:
xy = 1
if xy == 1:
dst_data[px+x,py+y] = 0
else:
dst_data[px+x,py+y] = 255
return img_new
## 膨胀
def dilation(img, point, size, v):
img_new = img.copy()
dst_data = img_new.load()
src_data = img.load()
px, py = point
width, height = size
r = v / 2
for x in range(r, width-r):
for y in range(r, height-r):
xy = 0
for i in range(-r, r+1):
for j in range(-r, r+1):
if src_data[px+x+i,py+y+j] == 255:
xy = 1
if xy == 1:
dst_data[px+x,py+y] = 255
else:
dst_data[px+x,py+y] = 0
return img_new
## 旋转
def rotate(img, degree):
img_new = Image.new("L", img.size)
dst_data = img_new.load()
src_data = img.load()
width, height = img.size
r = math.radians(degree) ## 角度转弧度
x0 = width / 2
y0 = height / 2
## 绕中心点旋转
for x in range(width):
for y in range(height):
xx = x * math.cos(r) + y * math.sin(r) - x0 * math.cos(r) - y0 * math.sin(r) + x0
yy = -1 * x * math.sin(r) + y * math.cos(r) + x0 * math.sin(r) - y0 * math.cos(r) + y0
if xx < width and xx >= 0 and yy < height and yy >= 0:
dst_data[xx,yy] = src_data[x,y]
return img_new
## 主函数
if __name__ == &quot;__main__&quot;:
if len(sys.argv)<2:
print &quot;arg error!! &quot;, sys.argv[0], &quot; filename&quot;
exit(1)
else:
filename = sys.argv[1]
## 转为灰色的YUV
img = rgb2gray(filename)
img.save(&quot;gray.jpg&quot;)
## Downsample
yuv = downsample(img, 2)
yuv.save(&quot;downsample.jpg&quot;)
## 旋转
rotate(yuv, 45).save(&quot;rotate-45.jpg&quot;)
rotate(yuv, 180).save(&quot;rotate-180.jpg&quot;)
rotate(yuv, 270).save(&quot;rotate-270.jpg&quot;)
## 中值滤波
median_value_filter(img, 3).save(&quot;median-value-filter.jpg&quot;)
## 模糊
vect = [[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]
iv = filter(img, vect)
iv.save(&quot;filter.jpg&quot;)
## 锐化
vect1 = [[0, -1, 0],
[-1, 6, -1],
[0, -1, 0]]
iv1 = filter(img, vect1)
iv1.save(&quot;filter1.jpg&quot;)
## 反转
reverse(img).save(&quot;back.jpg&quot;)
## 二值化
c = img_bin(img)
c.save(&quot;bin.jpg&quot;)
## 腐蚀
ee = erosion(c, (0, 0), c.size, 3)
ee.save(&quot;erosion.jpg&quot;)
## 膨胀
ee = dilation(ee, (0, 0), c.size, 3)
ee.save(&quot;dilation.jpg&quot;)
## 相加
img_add(img, iv).save(&quot;add.jpg&quot;)
## 相减
img_del(iv, iv1).save(&quot;del.jpg&quot;)
## 直方图均衡化
e = histogram_equa(img)
e.save(&quot;histogram_equa.jpg&quot;)
## 输出直方图
histogram(img).save(&quot;histo.jpg&quot;)
histogram(e).save(&quot;histo-equa.jpg&quot;) |