计算机视觉实验一——图像的基本操作
计算机视觉相关实验内容主要来自于《Python计算机视觉编程(Jan Erik Solem著)》这本书,感兴趣的同学可以系统学习。网盘下载链接: link
一、实验目标
- 分别使用 PIL 库和 OpenCV 库读取图像并实现可视化,对比OpenCV 读取和 PIL 读取的差异
- 利用 thumbnail() 函数创建图像缩略图,利用 resize() 函数处理图像,对比两者差别
- 绘制图像的轮廓与直方图
- 实现图像的灰度变换、直方图均衡化
- 实现图像的不同高斯模糊、计算导数
- ROF模型去噪
二、实验内容
1.分别使用 PIL 库和 OpenCV 库读取图像并实现可视化,对比OpenCV 读取和 PIL 读取的差异
①使用 PIL 库读取图像并实现可视化
from PIL import Image
# 读取图片
img = Image.open('img1.jpg')
# 显示图片,调用show方法
img.show()
②使用OpenCV 库读取图像并实现可视化
# 读入图像
# 1的话读取全彩图片 0读取灰度图片即黑白图片
img = cv2.imread('img1.jpg', 1)
# 显示图像
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 500, 490)
cv2.imshow('img', img)
cv2.waitKey(0) # 让程序暂停,否则图片一闪而过来不及观察图片
# 保存图像
# IMWRITE_JPEG_QUALITY的取值范围为0-100,下面写入jpg格式,数值越小,压缩比越高,图片失真严重
cv2.imwrite('img1_copy.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 0])
③二者的差异
(1)输出差异
cv2.imread()读取的是图像的真实数据。lmage.open()函数只是保持了图像被读取的状态,但是图像的真实数据并未被读取。
(2)通道差异
Image.open()读取的通道顺序是RGB,cv2.imread()读取的通道顺序为BGR。
# 读入图像
# OpenCV读取
img1 = cv2.imread('img1.jpg')
# PIL读取
img2 = Image.open('img1.jpg')
# 显示图像
plt.figure(dpi=120)
plt.subplot(121) # 1代表行,2代表列,所以一共有2个图,1代表此时绘制第一个图。
plt.axis('off') # 取消坐标轴
plt.title("OpenCV") # 标题
plt.imshow(img1) # 显示图片
plt.subplot(122) # 1代表行,2代表列,所以一共有2个图,2代表此时绘制第二个图。
plt.axis('off') # 取消坐标轴
plt.title("PIL") # 标题
plt.imshow(img2) # 显示图片
plt.show() # 显示窗口
2.利用 thumbnail() 函数创建图像缩略图,利用 resize() 函数处理图像,对比两者差别
①利用 thumbnail() 函数创建图像缩略图
from PIL import Image
img = Image.open('img1.jpg')
img.thumbnail((200, 150))
②利用 resize() 函数处理图像
img = array(Image.open('img1.jpg'))
out = img.resize((200, 150))
③二者差别
resize() 函数是修改图片的size, resample参数传入采样算法, 一般使用高质量缩放的Image.LANCZOS参数。
thumbnail() 函数是制作当前图片的缩略图, 参数size指定了图片的最大的宽度和高度。
3. 绘制图像的轮廓与直方图
# 读取图像到数组中 灰度化
im = array(Image.open('img1.jpg').convert('L'))
# 新建一个图像
figure()
# 不使用颜色信息
gray()
# 在原点的左上角显示轮廓图像
contour(im, origin='image')
axis('equal')
axis('off')
figure()
# 绘制直方图
hist(im.flatten(), 128)
show()
①图像的轮廓
②直方图:
4. 实现图像的灰度变换、直方图均衡化
①灰度变化:
from PIL import Image
from numpy import *
from matplotlib import pyplot as plt
im = array(Image.open('img1.jpg').convert('L'))
im2 = 255 - im # 对图像进行反相处理
im3 = (100.0 / 255) * im + 100 # 将图像像素值变换到100...200区间
im4 = 255.0 * (im / 255.0) ** 2 # 对图像像素值求平方后得到的图像
plt.title("opposition processing") # 标题
plt.imshow(im2) # 显示图片
plt.show()
plt.title("pixel value 100...200") # 标题
plt.imshow(im3) # 显示图片
plt.show()
plt.title("squaring pixel values") # 标题
plt.imshow(im4) # 显示图片
plt.show()
②直方图均衡化:
# 获取直方图——计算像素值出现概率
def GetHist(img):
assert isinstance(img, np.ndarray)
prob = np.zeros(shape=256)
for rv in img:
for cv in rv:
prob[cv] += 1
row, col = img.shape
prob = prob / (row * col)
return prob
# 直方图均衡化
def EqualHist(img, prob):
# 累计概率
prob = np.cumsum(prob)
# 像素值映射
img_map = [int(i * prob[i]) for i in range(256)]
# 像素值替换
assert isinstance(img, np.ndarray)
row, col = img.shape
for i in range(row):
for j in range(col):
img[i, j] = img_map[img[i, j]]
return img
# 画直方图
def Draw_plot(y, name):
plt.figure(num=name)
plt.bar([i for i in range(256)], y, width=1)
均衡化后的灰度图像:
5.实现图像的不同高斯模糊、计算导数
①不同高斯模糊(标准差为5和标准差为10)
from PIL import Image
from matplotlib import pyplot as plt
from numpy import *
from scipy.ndimage import filters
im = array(Image.open('img1.jpg'))
im2 = filters.gaussian_filter(im, 5) # 使用滤波操作模块,参数表示标准差
im3 = filters.gaussian_filter(im, 10)
plt.title("σ=5") # 标题
plt.imshow(im2) # 显示图片
plt.show()
plt.title("σ=10") # 标题
plt.imshow(im3) # 显示图片
plt.show()
②计算导数
from PIL import Image
from matplotlib import pyplot as plt
from numpy import *
from scipy.ndimage import filters
im = array(Image.open('img1.jpg').convert('L'))
imx = zeros(im.shape) # Sobel导数滤波器
filters.sobel(im, 0, imx) # 选择x方向导数
imy = zeros(im.shape)
filters.sobel(im, 1, imy) # 选择y方向导数
magnitude = sqrt(imx**2+imy**2)
plt.title("x") # 标题
plt.imshow(imx) # 显示图片
plt.show()
plt.title("y") # 标题
plt.imshow(imy) # 显示图片
plt.show()
6.ROF模型去噪
figure()
gray()
im = array(Image.open('img1.jpg').convert('L'))
subplot(1, 3, 1)
imshow(im)
axis("off")
U, T = rof.denoise(im, im)
G = filters.gaussian_filter(im, 10)
subplot(1, 3, 2)
imshow(U)
axis("off")
subplot(1, 3, 3)
imshow(G)
axis("off")
show()
使用denoise() 函数
可以看到,ROF 去噪后的图像保留了边缘和图像的结构信息,同时模糊了“噪声”。