本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的 Python 工具包,并介绍用于读取图像、图像转换和缩放、计算导数、画图和保存结果等的 基本工具。这些工具的使用将贯穿本书的剩余章节。
1、PIL
PIL(Python Imaging Library,图像处理类库)提供了通用的图像处理功能,以及大 量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。PIL 是免费的, 可以从 http://www.pythonware.com/products/pil/ 下载。
(1)转换图像格式
# -*- coding: utf-8 -*-
# from PCV.tools.imtools import get_imlist
from PIL import Image
import os
from imtools import *
import pickle
filelist = get_imlist('../data/convert_images_format_test/') #获取convert_images_format_test文件夹下的图片文件名(包括后缀名)
file = '../data/convert_images_format_test/imlist.txt'
imlist = open(file,'wb') #将获取的图片文件列表保存到imlist.txt中
pickle.dump(filelist,imlist) #序列化
imlist.close()
for infile in filelist:
outfile = os.path.splitext(infile)[0] + ".jpg" #分离文件名与扩展名
if infile != outfile:
try:
Image.open(infile).save(outfile)
except IOError:
print ("cannot convert", infile)
(2)创建缩略图
(3)复制和粘贴图像区域
(4)调整尺寸和旋转
在PIL库实现以上图像操作代码如下:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
figure()
# 显示原图
pil_im = Image.open('../data/empire.jpg')
print(pil_im.mode, pil_im.size, pil_im.format)
subplot(231)
title(u'原图', fontproperties=font)
axis('off')
imshow(pil_im)
# 显示灰度图
pil_im = Image.open('../data/empire.jpg').convert('L')
gray()
subplot(232)
title(u'灰度图', fontproperties=font)
axis('off')
imshow(pil_im)
#拷贝粘贴区域
pil_im = Image.open('../data/empire.jpg')
box = (100,100,400,400)
region = pil_im.crop(box)
region = region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)
subplot(233)
title(u'拷贝粘贴区域', fontproperties=font)
axis('off')
imshow(pil_im)
# 缩略图
pil_im = Image.open('../data/empire.jpg')
size = 128, 128
pil_im.thumbnail(size)
print(pil_im.size)
subplot(234)
title(u'缩略图', fontproperties=font)
axis('off')
imshow(pil_im)
pil_im.save('../images/ch01/thumbnail.jpg') #保存缩略图
# 调整图像尺寸
pil_im = Image.open('../data/empire.jpg')
pil_im = pil_im.resize(size)
print(pil_im.size)
subplot(235)
title(u'调整尺寸后的图像', fontproperties=font)
axis('off')
imshow(pil_im)
# 旋转图像45°
pil_im = Image.open('../data/empire.jpg')
pil_im = pil_im.rotate(45)
subplot(236)
title(u'旋转45°后的图像', fontproperties=font)
axis('off')
imshow(pil_im)
show()
代码运行结果如下:
2、Matplotlib
我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib 是个很好的类库,具有比 PIL 更强大的绘图功能。Matplotlib 可以绘制出高质量的 图表,就像本书中的许多插图一样。Matplotlib 中的 PyLab 接口包含很多方便用户 创建图像的函数。Matplotlib 是开源工具,可以从 http://matplotlib.sourceforge.net/ 免费下载。该链接中包含非常详尽的使用说明和教程。下面的例子展示了本书中需 要使用的大部分函数。
(1)绘制图像、点和线
绘图点线代码实现如下:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
im = array(Image.open('../data/empire.jpg'))
figure()
# 画有坐标轴的
subplot(121)
imshow(im)
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]
plot(x, y, 'r*')
plot(x[:2], y[:2])
title(u'绘图: "empire.jpg"', fontproperties=font)
# 不显示坐标轴
subplot(122)
imshow(im)
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]
plot(x, y, 'r*')
plot(x[:2], y[:2])
axis('off') #显示坐标轴
title(u'绘图: "empire.jpg"', fontproperties=font)
show()
代码运行结果:
代码中plot函数参数说明:
plot(x,y) #默认为蓝色实线
plot(x,y,'xxx') #xxx代表三组符号:第一组为颜色符号:b g r c m y k w,第二组为形状符号:· o s * + x,第三组为虚实符号:- -- : 比如plot(x,y,'go-'),其中‘go-’代表绿色 圈 实线
(2)图像轮廓和直方图
代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
im = array(Image.open('../data/empire.jpg').convert('L')) # 打开图像,并转成灰度图像
figure()
subplot(121)
gray()
contour(im, origin='image')
axis('equal')
axis('off')
title(u'图像轮廓', fontproperties=font)
subplot(122)
hist(im.flatten(), 128)
title(u'图像直方图', fontproperties=font)
plt.xlim([0,300])
plt.ylim([0,12000])
show()
运行结果:
(3)交互式标注
代码实现:
from PIL import Image
from pylab import *
im = array(Image.open('../data/empire.jpg'))
imshow(im)
print('Please click 3 points')
imshow(im)
x = ginput(3)
print('You clicked:', x)
show()
运行结果:
3、Numpy
(1)图像数组表示
代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
im = array(Image.open('../data/empire.jpg'))
print(im.shape, im.dtype)
im = array(Image.open('../data/empire.jpg').convert('L'),'f')
print(im.shape, im.dtype)
运行结果:
位于坐标 i、j,以及颜色通道 k 的像素值可以像 下面这样访问:value = im[i,j,k]
多个数组元素可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问 该数组的元素值。下面是有关灰度图像的一些例子:
im[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行
im[:,i] = 100 # 将第 i 列的所有数值设为 100
im[:100,:50].sum() # 计算前 100 行、前 50 列所有数值的和
im[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
im[i].mean() # 第 i 行所有数值的平均值
im[:,-1] # 最后一列
im[-2,:] (or im[-2]) # 倒数第二行
(2)灰度变换
代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from numpy import *
from pylab import *
im = array(Image.open('../data/empire.jpg').convert('L'))
print(int(im.min()), int(im.max()))
im2 = 255 - im # invert image
print(int(im2.min()), int(im2.max()))
im3 = (100.0/255) * im + 100 # clamp to interval 100...200
print(int(im3.min()), int(im3.max()))
im4 = 255.0 * (im/255.0)**2 # squared
print(int(im4.min()), int(im4.max()))
figure()
gray()
subplot(1, 3, 1)
imshow(im2)
axis('off')
title(r'$f(x)=255-x$')
subplot(1, 3, 2)
imshow(im3)
axis('off')
title(r'$f(x)=\frac{100}{255}x+100$')
subplot(1, 3, 3)
imshow(im4)
axis('off')
title(r'$f(x)=255(\frac{x}{255})^2$')
show()
运行结果:
(3)图像缩放
将图像缩放函数imresize添加到imtool.py文件里:
def imresize(im,sz):
""" Resize an image array using PIL. """
pil_im = Image.fromarray(uint8(im))
return array(pil_im.resize(sz))
(4)直方图均衡化
代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
# from PCV.tools import imtools
import imtools
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
im = array(Image.open('../data/empire.jpg').convert('L')) # 打开图像,并转成灰度图像
#im = array(Image.open('../data/AquaTermi_lowcontrast.JPG').convert('L'))
im2, cdf = imtools.histeq(im)
figure()
subplot(2, 2, 1)
axis('off')
gray()
title(u'原始图像', fontproperties=font)
imshow(im)
subplot(2, 2, 2)
axis('off')
title(u'直方图均衡化后的图像', fontproperties=font)
imshow(im2)
subplot(2, 2, 3)
axis('off')
title(u'原始直方图', fontproperties=font)
#hist(im.flatten(), 128, cumulative=True, normed=True)
# hist(im.flatten(), 128, normed=True)
hist(im.flatten(), 128)
subplot(2, 2, 4)
axis('off')
title(u'均衡化后的直方图', fontproperties=font)
#hist(im2.flatten(), 128, cumulative=True, normed=True)
# hist(im2.flatten(), 128, normed=True)
hist(im2.flatten(), 128)
show()
empire.jpg运行结果:
AquaTermi_lowcontrast.JPG运行结果:
(5)图像平均
代码实现:
# -*- coding: utf-8 -*-
# from PCV.tools.imtools import get_imlist
from PIL import Image
from pylab import *
# from PCV.tools import imtools
import imtools
from imtools import get_imlist
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
filelist = get_imlist('../data/avg/') #获取convert_images_format_test文件夹下的图片文件名(包括后缀名)
avg = imtools.compute_average(filelist)
for impath in filelist:
im1 = array(Image.open(impath))
subplot(2, 2, filelist.index(impath)+1)
imshow(im1)
imNum=str(filelist.index(impath)+1)
title(u'待平均图像'+imNum, fontproperties=font)
axis('off')
subplot(2, 2, 4)
imshow(avg)
title(u'平均后的图像', fontproperties=font)
axis('off')
show()
运行结果:
(6)图像主成分分析(PCA)
代码实现:
# -*- coding: utf-8 -*-
import pickle
from PIL import Image
from numpy import *
from pylab import *
# from PCV.tools import imtools, pca
import imtools, pca
# Uses sparse pca codepath.
#imlist = imtools.get_imlist('../data/selectedfontimages/a_selected_thumbs')
# 获取图像列表和他们的尺寸
imlist = imtools.get_imlist('../data/fontimages/a_thumbs') # fontimages.zip is part of the book data set
im = array(Image.open(imlist[0])) # open one image to get the size
m, n = im.shape[:2] # get the size of the images
imnbr = len(imlist) # get the number of images
print("The number of images is %d" % imnbr)
# Create matrix to store all flattened images
immatrix = array([array(Image.open(imname)).flatten() for imname in imlist], 'f')
# PCA降维
V, S, immean = pca.pca(immatrix)
# # 保存均值和主成分
# f = open('../data/fontimages/font_pca_modes.pkl', 'wb')
# pickle.dump(immean,f)
# pickle.dump(V,f)
# f.close()
# # 载入均值和主成分数据
# f = open('../data/fontimages/font_pca_modes.pkl', 'rb')
# immean = pickle.load(f)
# V = pickle.load(f)
# f.close()
# # 打开文件并保存
# with open('font_pca_modes.pkl', 'wb') as f:
# pickle.dump(immean,f)
# pickle.dump(V,f)
# # 打开文件并载入
# with open('font_pca_modes.pkl', 'rb') as f:
# immean = pickle.load(f)
# V = pickle.load(f)
# Show the images (mean and 7 first modes)
# This gives figure 1-8 (p15) in the book.
figure()
gray()
subplot(2, 4, 1)
axis('off')
imshow(immean.reshape(m, n))
for i in range(7):
subplot(2, 4, i+2)
imshow(V[i].reshape(m, n))
axis('off')
show()
运行结果:
(7)使用pickle模块
Python 中的 pickle 模块非常有 用。pickle 模块可以接受几乎所有的 Python 对象,并且将其转换成字符串表示,该 过程叫做封装(pickling)。从字符串表示中重构该对象,称为拆封(unpickling)。 这些字符串表示可以方便地存储和传输。
将使用pickle模块进行封装和拆封上一节字体图像的平均图像和主成分数据的代码加入上一节代码文件里。
# 保存均值和主成分
f = open('../data/fontimages/font_pca_modes.pkl', 'wb')
pickle.dump(immean,f)
pickle.dump(V,f)
f.close()
# 载入均值和主成分数据
f = open('../data/fontimages/font_pca_modes.pkl', 'rb')
immean = pickle.load(f)
V = pickle.load(f)
f.close()
# # 打开文件并保存
# with open('font_pca_modes.pkl', 'wb') as f:
# pickle.dump(immean,f)
# pickle.dump(V,f)
# # 打开文件并载入
# with open('font_pca_modes.pkl', 'rb') as f:
# immean = pickle.load(f)
# V = pickle.load(f)
4、SciPy
SciPy(http://scipy.org/)是建立在 NumPy 基础上,用于数值运算的开源工具包。 SciPy 提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及对 我们来说最重要的图像处理功能。接下来,本节会介绍 SciPy 中大量有用的模块。 SciPy 是个开源工具包,可以从 http://scipy.org/Download 下载。
(1)图像模糊
图像的高斯模糊是非常经典的图像卷积例子。本质上,图像模糊就是将(灰度)图像 I 和一个高斯核进行卷积操作:
其中 * 表示卷积操作;Gσ 是标准差为 σ 的二维高斯核,定义为 :
高斯模糊通常是其他图像处理操作的一部分,比如图像插值操作、兴趣点计算以及很多其他应用。
代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from scipy.ndimage import filters
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
#im = array(Image.open('board.jpeg'))
im = array(Image.open('../data/empire.jpg').convert('L'))
figure()
gray()
axis('off')
subplot(1, 4, 1)
axis('off')
title(u'原图', fontproperties=font)
imshow(im)
for bi, blur in enumerate([2, 5, 10]):
im2 = zeros(im.shape)
im2 = filters.gaussian_filter(im, blur)
im2 = np.uint8(im2)
imNum=str(blur)
subplot(1, 4, 2 + bi)
axis('off')
title(u'标准差为'+imNum, fontproperties=font)
imshow(im2)
#如果是彩色图像,则分别对三个通道进行模糊
#for bi, blur in enumerate([2, 5, 10]):
# im2 = zeros(im.shape)
# for i in range(3):
# im2[:, :, i] = filters.gaussian_filter(im[:, :, i], blur)
# im2 = np.uint8(im2)
# subplot(1, 4, 2 + bi)
# axis('off')
# imshow(im2)
show()
运行结果:
(2)图像导数
使用 Sobel 导数滤波器计算导数图像代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpy
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
im = array(Image.open('../data/empire.jpg').convert('L'))
gray()
subplot(1, 4, 1)
axis('off')
title(u'(a)原图', fontproperties=font)
imshow(im)
# Sobel derivative filters
imx = zeros(im.shape)
filters.sobel(im, 1, imx)
subplot(1, 4, 2)
axis('off')
title(u'(b)x方向差分', fontproperties=font)
imshow(imx)
imy = zeros(im.shape)
filters.sobel(im, 0, imy)
subplot(1, 4, 3)
axis('off')
title(u'(c)y方向差分', fontproperties=font)
imshow(imy)
#mag = numpy.sqrt(imx**2 + imy**2)
mag = 255-numpy.sqrt(imx**2 + imy**2)
subplot(1, 4, 4)
title(u'(d)梯度幅度', fontproperties=font)
axis('off')
imshow(mag)
show()
使用 Sobel 导数滤波器计算导数图像运行结果:
使用高斯导数计算图像导数代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpy
# 添加中文字体支持
#from matplotlib.font_manager import FontProperties
#font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
def imx(im, sigma):
imgx = zeros(im.shape)
filters.gaussian_filter(im, sigma, (0, 1), imgx)
return imgx
def imy(im, sigma):
imgy = zeros(im.shape)
filters.gaussian_filter(im, sigma, (1, 0), imgy)
return imgy
def mag(im, sigma):
# there's also gaussian_gradient_magnitude()
#mag = numpy.sqrt(imgx**2 + imgy**2)
imgmag = 255 - numpy.sqrt(imgx ** 2 + imgy ** 2)
return imgmag
im = array(Image.open('../data/empire.jpg').convert('L'))
figure()
gray()
sigma = [2, 5, 10]
for i in sigma:
subplot(3, 4, 4*(sigma.index(i))+1)
axis('off')
imshow(im)
imgx=imx(im, i)
subplot(3, 4, 4*(sigma.index(i))+2)
axis('off')
imshow(imgx)
imgy=imy(im, i)
subplot(3, 4, 4*(sigma.index(i))+3)
axis('off')
imshow(imgy)
imgmag=mag(im, i)
subplot(3, 4, 4*(sigma.index(i))+4)
axis('off')
imshow(imgmag)
show()
使用高斯导数计算图像导数运行结果:
(3)形态学:对象计数
形态学(或数学形态学)是度量和分析基本形状的图像处理方法的基本框架与集合。 形态学通常用于处理二值图像,但是也能够用于灰度图像。二值图像是指图像的每 个像素只能取两个值,通常是 0 和 1。二值图像通常是,在计算物体的数目,或者 度量其大小时,对一幅图像进行阈值化后的结果。你可以从 http://en.wikipedia.org/ wiki/Mathematical_morphology 大体了解形态学及其处理图像的方式。
代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from numpy import *
from scipy.ndimage import measurements, morphology
from pylab import *
""" This is the morphology counting objects example in Section 1.4. """
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
# load image and threshold to make sure it is binary
figure()
gray()
im = array(Image.open('../data/houses.png').convert('L'))
subplot(221)
imshow(im)
axis('off')
title(u'原图', fontproperties=font)
im = (im < 128)
labels, nbr_objects = measurements.label(im)
print("Number of objects:", nbr_objects)
subplot(222)
imshow(labels)
axis('off')
title(u'标记后的图', fontproperties=font)
# morphology - opening to separate objects better
im_open = morphology.binary_opening(im, ones((9, 5)), iterations=2)
subplot(223)
imshow(im_open)
axis('off')
title(u'开运算后的图像', fontproperties=font)
labels_open, nbr_objects_open = measurements.label(im_open)
print("Number of objects:", nbr_objects_open)
subplot(224)
imshow(labels_open)
axis('off')
title(u'开运算后进行标记后的图像', fontproperties=font)
show()
运行结果:
(4)一些有用的SciPy模块
SciPy 中包含一些用于输入和输出的实用模块。下面介绍其中两个模块:io 和 misc。
1. 读写.mat文件
data = scipy.io.loadmat('test.mat')#读.mat文件
data = {}
data['x'] = x scipy.io.savemat('test.mat',data) #写.mat文件
2. 以图像形式保存数组
from scipy.misc import imsave
imsave('test.jpg',im)
scipy.misc 模块同样包含了著名的 Lena 测试图像: lena = scipy.misc.lena()
5、高级示例:图像去噪
使用 ROF 模型对合成图像去噪代码实现:
# -*- coding: utf-8 -*-
from pylab import *
from numpy import *
from numpy import random
from scipy.ndimage import filters
from scipy.misc import imsave
# from PCV.tools import rof
import rof
""" This is the de-noising example using ROF in Section 1.5. """
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
# create synthetic image with noise
im = zeros((500,500))
im[100:400,100:400] = 128
im[200:300,200:300] = 255
im = im + 30*random.standard_normal((500,500))
U,T = rof.denoise(im,im)
G = filters.gaussian_filter(im,10)
# save the result
#imsave('synth_original.pdf',im)
#imsave('synth_rof.pdf',U)
#imsave('synth_gaussian.pdf',G)
# plot
figure()
gray()
subplot(1,3,1)
imshow(im)
#axis('equal')
axis('off')
title(u'原噪声图像', fontproperties=font)
subplot(1,3,2)
imshow(G)
#axis('equal')
axis('off')
title(u'高斯模糊后的图像', fontproperties=font)
subplot(1,3,3)
imshow(U)
#axis('equal')
axis('off')
title(u'ROF降噪后的图像', fontproperties=font)
show()
说明:以上代码运行时可能会报错scipy.misc没有imsave模块,这是由于在最新版本中imsave模块已经被删除,所以可安装旧版本运行,比如pip3 install scipy==1.2.1
使用 ROF 模型对合成图像去噪运行结果:
使用 ROF 模型对灰度图像去噪代码实现:
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from numpy import *
from numpy import random
from scipy.ndimage import filters
from scipy.misc import imsave
# from PCV.tools import rof
import rof
""" This is the de-noising example using ROF in Section 1.5. """
# 添加中文字体支持
# from matplotlib.font_manager import FontProperties
# font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="/System/Library/Fonts/PingFang.ttc", size=14)
im = array(Image.open('../data/empire.jpg').convert('L'))
U,T = rof.denoise(im,im)
G = filters.gaussian_filter(im,10)
# save the result
#imsave('synth_original.pdf',im)
#imsave('synth_rof.pdf',U)
#imsave('synth_gaussian.pdf',G)
# plot
figure()
gray()
subplot(1,3,1)
imshow(im)
#axis('equal')
axis('off')
title(u'原噪声图像', fontproperties=font)
subplot(1,3,2)
imshow(G)
#axis('equal')
axis('off')
title(u'高斯模糊后的图像', fontproperties=font)
subplot(1,3,3)
imshow(U)
#axis('equal')
axis('off')
title(u'ROF降噪后的图像', fontproperties=font)
show()
使用 ROF 模型对灰度图像去噪运行结果:
6、其他
(1)开发环境
本代码是在mac电脑sublimetxt编辑器python3.7.8下调试出来的,如果你要在windows/linux下编辑器/IDE的其他python版本运行的话,请对代码做相应的调整。
(2) opencv版本
1)s = cv2.SURF() 报错 AttributeError: module 'cv2.cv2' has no attribute 'SURF'。这是因为早期SURF函数是在cv2库直接调用的,后期cv2将SURF、SIFT、Harris等算子整合到opencv-contrib-python这个包里了,所以不再能直接调用。SURF、SIFT、Harris等算子被封装在cv2.xfeatures2d中了,安装opencv-contrib-python这个包后,调用cv2.xfeatures2d.SURF_create()就可以替代早期版本中的cv2.SURF()。
2)s = cv2.xfeatures2d.SURF_create() 报错AttributeError: module 'cv2' has no attribute 'xfeatures2d'。这是因为SURF、SIFT、Harris算子都已经申请专利了,所以这些算子不免费,在opencv3.4.2之后的版本都不再包含这两个算子。如1)所述,opencv3.4.2之前的版本将SURF、SIFT、Harris等算子整合到opencv-contrib-python里了,做一些特征检测匹配,所以需要用到opencv-contrib-python这个包。综合考虑我使用3.4.2.16版本的opencv-python和opencv-contrib-python。
(3)源码和图片
已经调试过的源码和图片详见:
https://github.com/Abonaventure/pcv-book-code.git
或