机器学习CV代码练习(八)之数字图像处理

  • 读取和显示图像---- 方法一:matplotlib.image显示图像
  • 读取和显示图像---- 方法二:cv2
  • 读取和显示图像---- 方法三:常用的图像处理库 - PIL
  • 缩放图像
  • 画图
  • 查看图像的数值特征
  • 查看--直方图
  • 查看--累积分布函数 (CDF)图
  • 调整调整图像的像素值使得其值变为均匀分布
  • 使用滤波器去噪声
  • 添加随机噪声:模拟低亮度时拍摄的照片, 包括大量随机噪声
  • 高斯滤波器:使用一个像素临近区域的像素的加权均值代替原来的值.
  • 中值滤波:使用一个像素临近区域的像素的中间值代替原来的值.
  • 特征提取——边缘检测
  • Sobel 边缘检测:寻找图像中在纵横方向上面值变化比较大的区域
  • Canny边缘检测
  • Harris Corner Detector 哈里斯边角侦测:检测在所有方向像素值变化都比较大的区域, 这些区域被称为corner, 边角.


  • 使用OpenCV进行数字图像处理和计算机视觉任务。例如:读写图像、旋转缩放、图像滤波、亮度调整、边缘检测、Hough 变换检测几何形状的物体

读取和显示图像---- 方法一:matplotlib.image显示图像

from matplotlib import image as mpimg#画图、读图片
from matplotlib import pyplot as plt
import numpy as np
%matplotlib inline

img1 = mpimg.imread('cat.jpg')#直接变为numpy.ndarray
plt.imshow(img1)
type(img1)

读取和显示图像---- 方法二:cv2

import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

img2 = cv2.imread('cat.jpg')#opencv保存的是:bgr
plt.imshow(img2)
# type(img2)
#注意图像的色彩由问题.因为cv2加载图像后保存为BGR, 而非RGB的格式. 需要如下方式变换:
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
plt.imshow(img2)

读取和显示图像---- 方法三:常用的图像处理库 - PIL

from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline

img3 = Image.open('cat.jpg')#PIL.JpegImagePlugin.JpegImageFile
plt.imshow(img3)
type(img3)
#注意此时的图像类型是 JpegImageFile - 而非 numpy array. 这种类型的数据适合PIL库的函数/方法. 可以转换为numpy array:
img3 = np.array(img3)#可以转换成np.array

# 大多数时候我们使用numpy array来表达图像. 可以使用如下方法保存numpy array:

# Save the image保存numpy array
np.save('cat.npy', img3)

#Load the image
img3 = np.load('cat.npy')

# 将np.array-numpy数组转换为PIL Image对象
orig_img = Image.fromarray(img3)

缩放图像

from PIL import Image, ImageOps
import matplotlib.pyplot as plt
%matplotlib inline

# 将np.array-numpy数组转换为PIL Image对象
orig_img = Image.fromarray(img3)

# 缩放为 200 x 200 
target_size = (200,200)
new_img = orig_img.resize(target_size)#缩放
n_h, n_w = new_img.size
print('New size:', n_h, 'x', n_w)
  • 图像缩放造成了图像形变. 我们可以按照原来图像宽高比缩放图像, 避免形变.
from PIL import Image, ImageOps
scaled_img = orig_img.copy()

scaled_img.thumbnail(target_size, Image.ANTIALIAS)
scaled_height, scaled_width = scaled_img.size
print('Scaled size:', scaled_height, 'x', scaled_width)

画图

import matplotlib.pyplot as plt
%matplotlib inline
fig = plt.figure(figsize=(12, 12))

# Subplot for original image
a=fig.add_subplot(2,1,1)
imgplot = plt.imshow(orig_img)
a.set_title('Before')
plt.show()

查看图像的数值特征

from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline

img3 = Image.open('cat.darkened.jpeg')
img3 = np.array(img3)
img3.dtype#dtype('uint8'),数组包含8位的整数值. 值的范围0-255. RGB色彩通道每一个像素可能的值.

直方图和CDF都预示图像的值的分布不均衡.

查看–直方图

一个比较自然的图像的值的分布应该是均匀分布的, 可以通过直方图查看.

import matplotlib.pyplot as plt
%matplotlib inline

# Plot a histogram - we need to use ravel to "flatten" the 3 dimensions
plt.hist(img3.ravel())#直方图
plt.show()

查看–累积分布函数 (CDF)图

import matplotlib.pyplot as plt
%matplotlib inline

plt.hist(img3.ravel(), bins=255, cumulative=True)#CDF图
plt.show()

调整调整图像的像素值使得其值变为均匀分布

from PIL import Image, ImageOps
%matplotlib inline

# Equalize the image - but we need to convert the numpy array back to the PIL image format
# ImageOps.equalize():通过调整图像的像素值使得其值变为均匀分布.
img3PIL_eq = ImageOps.equalize(Image.fromarray(img3))

使用滤波器去噪声

添加随机噪声:模拟低亮度时拍摄的照片, 包括大量随机噪声

import skimage#sklearn中的做图像处理的操作
%matplotlib inline

img3_n = skimage.util.random_noise(img3_eq)#添加噪声
plt.imshow(img3_n)

高斯滤波器:使用一个像素临近区域的像素的加权均值代替原来的值.

from scipy.ndimage.filters import gaussian_filter as gauss
%matplotlib inline

img3_gauss = gauss(img3_n, sigma=1)  #采用高斯滤波器去除噪声 ,sigma控制滤波强度,越大越虚
plt.imshow(img3_gauss)

中值滤波:使用一个像素临近区域的像素的中间值代替原来的值.

from scipy.ndimage.filters import median_filter as med
%matplotlib inline

img3_med = med(img3_n, size=3)#采用中值滤波器去除噪声 
plt.imshow(img3_med)

特征提取——边缘检测

Sobel 边缘检测:寻找图像中在纵横方向上面值变化比较大的区域

步骤:

  1. 将彩色图像转换为灰度图像.
  2. 计算横向和纵向的梯度.
  3. 计算梯度的大小.
  4. 规范化梯度值.
from PIL import Image, ImageOps
import numpy as np
from PIL import Image
from scipy import ndimage
%matplotlib inline

sx = ndimage.sobel(img, axis=0, mode='constant')#x方向的sobel边缘检测
sy = ndimage.sobel(img, axis=1, mode='constant')#y方向的sobel边缘检测
sob = np.hypot(sx, sy)#x和y方向的sobel边缘检测

Canny边缘检测

from scipy import ndimage

from skimage.feature import canny
canny_edges = canny(img, sigma=5)#canny边缘检测

Harris Corner Detector 哈里斯边角侦测:检测在所有方向像素值变化都比较大的区域, 这些区域被称为corner, 边角.

import numpy as np
import cv2
from matplotlib import pyplot as plt

filename = 'chessboard.jpg'
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)
plt.imshow(gray),plt.show()
dst = cv2.cornerHarris(gray,2,3,0.04)#cornerHarris边角检测为一个值dst

#result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None)#结果边角增强些,看得清楚

# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]


plt.imshow(img),plt.show()