打印

用python实现图像处理

[复制链接]
181|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近在看数字图像处理方面的东东,书看多了,就想实验一下,本想用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__ == "__main__":

  if len(sys.argv)<2:

    print "arg error!! ", sys.argv[0], " filename"

    exit(1)

  else:

    filename = sys.argv[1]

  

  ## 转为灰色的YUV

  img = rgb2gray(filename)

  img.save("gray.jpg")

  

  ## Downsample

  yuv = downsample(img, 2)

  yuv.save("downsample.jpg")

  

  ## 旋转

  rotate(yuv, 45).save("rotate-45.jpg")

  rotate(yuv, 180).save("rotate-180.jpg")

  rotate(yuv, 270).save("rotate-270.jpg")

  

  ## 中值滤波

  median_value_filter(img, 3).save("median-value-filter.jpg")

  

  ## 模糊

  vect = [[1, 1, 1],

          [1, 1, 1],

          [1, 1, 1]]

  iv = filter(img, vect)

  iv.save("filter.jpg")

  

  ## 锐化

  vect1 = [[0, -1, 0],

           [-1, 6, -1],

           [0, -1, 0]]

  iv1 = filter(img, vect1)

  iv1.save("filter1.jpg")

  

  ## 反转

  reverse(img).save("back.jpg")

  

  ## 二值化

  c = img_bin(img)

  c.save("bin.jpg")

  

  ## 腐蚀

  ee = erosion(c, (0, 0), c.size, 3)

  ee.save("erosion.jpg")

  

  ## 膨胀

  ee = dilation(ee, (0, 0), c.size, 3)

  ee.save("dilation.jpg")

  

  ## 相加

  img_add(img, iv).save("add.jpg")

  

  ## 相减

  img_del(iv, iv1).save("del.jpg")

  

  ## 直方图均衡化

  e = histogram_equa(img)

  e.save("histogram_equa.jpg")

  

  ## 输出直方图

  histogram(img).save("histo.jpg")

  

  histogram(e).save("histo-equa.jpg")

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

384

主题

384

帖子

0

粉丝