- 案例目的
本案例的是通过图像处理算法案例,深入了解Python数据结构和基本算法流程。
- 案例内容
在科学计算和各种算法中,经常需要使用嵌套循环来处理数据。例如,图像在计算机中是由像素点组成的二维数组,每个像素点的位置被表示为两个整数的元组,像素的值根据图像模式由对应的元组组成(例如RGB模式表示为三个整数值组成的元组,分别表示构成颜色的红蓝绿的值,范围为0~255)
图像处理(例如复制,旋转裁剪和平滑图像等的算法,根本上就是用嵌套循环模式对这些像素进行处理。)
本章案例研究使用Python第三方图像处理库Pillow中PIL.Image模块的的Image类的方法getpixel()和putpixel()来读取和修改特定位置location处的像素的颜色pix,然后使用嵌套循环实现图像处理的基本算法。
- 实验环境
Pycharm、Anaconda
- 案例研究
3.1 图像复制前后对比
主要代码:
- # 作者:JohnRothan
- # 时间:2022-3-15
- # 题目信息:图像复制
- import PIL.Image
- # 复制图像并与原图像对比
- def copy(im):
- width, height = im.size
- im_new = PIL.Image.new(im.mode, im.size) #创建与原始图像相同模式和大小的新图像对象
- res = PIL.Image.new(im.mode, (2*width, height)) #创建与原始图像相同模式和2倍大小的新图像对象
- #使用嵌套循环,把旧图像位置(i,j)的像素复制到新图像的位置(i, j)
- for i in range(0, width) :
- for j in range(0, height):
- pix = im.getpixel((i,j))
- im_new.putpixel((i,j), pix)
- #复制前后的图像对比
- res.paste(im, (0, 0, width, height))
- res.paste(im_new, (width, 0, 2*width, height))
- return res
- im = PIL.Image.open("C:\\Users\\JohnRothan\\Desktop\\log.png")
- copy(im).show ()
测试结果:
图 1 图像复制前后对比
3.2 扣取特定位置图像
主要代码:
- # 作者:JohnRothan
- # 时间:2022-3-15
- # 题目信息:图像扣取
- import PIL.Image
- def crop(im, box):
- #剪切框定义左上角和右下角坐标位置
- x1, y1, x2, y2 = box
- #计算新图像的宽度width和高度height,并创建新图像
- width, height = x2-x1, y2-y1
- im_new = PIL.Image.new(im.mode, (width,height))
- #使用嵌套循环,把旧图像剪切框内的像素拷贝到新图像
- for i in range(width):
- for j in range(height):
- pix = im.getpixel((x1+i, y1+j))
- im_new.putpixel((i,j), pix)
- return im_new
- #测试代码
- im = PIL.Image.open("C:\\Users\\JohnRothan\\Desktop\\dog.jpg")
- print(im.size)
- crop(im, (1600,1700,2100,2100)).show()
测试结果:
图 2 图像扣取
3.3 平滑图像过滤器
主要代码:
- # 作者:JohnRothan
- # 时间:2022-3-15
- # 题目信息:图像平滑处理
- import PIL.Image
- def crop(im, box):
- #剪切框定义左上角和右下角坐标位置
- x1, y1, x2, y2 = box
- #计算新图像的宽度width和高度height,并创建新图像
- width, height = x2-x1, y2-y1
- im_new = PIL.Image.new(im.mode, (width,height))
- #使用嵌套循环,把旧图像剪切框内的像素拷贝到新图像
- for i in range(width):
- for j in range(height):
- pix = im.getpixel((x1+i, y1+j))
- im_new.putpixel((i,j), pix)
- return im_new
- #测试代码
- def smooth(im):
- """返回考贝后的图像对象"""
- #创建与原始图像相同模式和大小的新图像对象
- im_new = PIL.Image.new(im.mode, im.size)
- width, height = im.size
- #使用嵌套循环,进行图像平滑处理
- for i in range(0, width-1):
- for j in range(0, height-1):
- r1, g1, b1 = im.getpixel((i, j))
- r2, g2, b2 = im.getpixel((i + 1, j + 1))
- rgb = (int((r1+r2)/2), int((g1+g2)/2), int((b1+b2)/2))
- im_new.putpixel((i, j), rgb)
- return im_new
- #测试代码
- im = PIL.Image.open("C:\\Users\\JohnRothan\\Desktop\\dog.jpg")
- # 首先扣取图像
- crop(im, (1700,1700,1900,1900)).show()
- # 进行平滑处理
- smooth(crop(im, (1700,1700,1900,1900))).show()
测试结果:
图 3 图像平滑处理
3.4 图像镜像翻转(水平)
主要代码:
- # 作者:JohnRothan
- # 时间:2022-3-15
- # 题目信息:图像翻转
- import PIL.Image
- def flip(im, orient="H"):
- """返回水平或垂直翻转后的图像对象"""
- #获取图像的宽度width和高度height,并创建新图像
- width, height = im.size
- im_new = PIL.Image.new(im.mode, im.size)
- #使用嵌套循环,把旧图像的像素拷贝到新图像对应位置
- for i in range(width):
- for j in range(height):
- pix = im.getpixel ((i, j))
- if orient == "H":#水平翻转时
- #原始图像的像素(i,j)映射到目标图像的位置(width-i-1,j)
- im_new.putpixel((width-i-1, j), pix)
- else: #垂直翻转时
- #原始图像的像素(i,j)映射到目标图像的位置(i, height-j-1)
- im_new.putpixel((i, height-j-1), pix)
- return im_new
- #测试代码
- im = PIL.Image.open("C:\\Users\\JohnRothan\\Desktop\\log.png")
- im.show()
- flip(im, orient="H").show()
测试结果:
图 4 水平翻转