为了对图像进行预处理,需要将其载入程序,利用OpenCV的imread方法:
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 把图像导入成灰度图
image = cv2.imread('plane.jpg', cv2.IMREAD_GRAYSCALE)
# 显示图像
plt.imshow(image, cmap='gray'),plt.axis('off')
plt.show()
在我们调用imread方法时候,程序会将图像数据转换成NumPy数组,矩阵中的元素与原图像中的像素点一一对应:
# 显示数据类型
print(type(image))
# 显示图像数据
print(image)
<class 'numpy.ndarray'>
[[116 115 115 ... 81 79 79]
[118 117 117 ... 81 80 80]
[119 118 118 ... 81 81 80]
...
[227 227 227 ... 163 162 161]
[227 227 227 ... 161 161 161]
[226 226 226 ... 159 160 162]]
图像分辨率和矩阵的维度完全相同:
# 查看矩阵维度
print(image.shape)
(512, 1024)
矩阵中每个元素实际代表什么呢?对于灰度图像:矩阵元素的值代表对应像素的灰度值,灰度值在0(黑色)~255(白色)之间变化;而对于彩色图像,每个元素包含三个值,分别对应蓝色、绿色、红色(BGR):
# 把图像导入成彩色图
image_bgr = cv2.imread('plane.jpg', cv2.IMREAD_COLOR)
# 显示像素值
print(image_bgr[0,0])
# B G R
[187 124 73]
【小提示】:OpenCV默认使用BGR格式,但是许多图像应用程序(Matplotlib)使用RGB格式,红色和蓝色分量对调位置了。如果要想在Matplotlib中正确显示OpenCV彩色图像,需要先进行转换。
# 转换成RGB格式
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
plt.imshow(image_rgb), plt.axis('off')
plt.show()
利用OpenCV的imwrite:
# 保存图像
cv2.imwrite('images/plane_new.jpg', image)
【小提示】:imwrite将直接覆盖现有文件,而不会输出一条错误信息或请求你确认。
利用OpenCV的resize:调整图像的大小(图像的像素)
#调整图像像素大小:50*50像素
image_50_50 = cv2.resize(image, (50,50))
plt.imshow(image_50_50, cmap='gray'),plt.axis('off')
plt.show()
【说明】:调整图像大小的原因有两点:(1)原始图像的形状和大小各异,但是被用作特征的图像必须有相同的大小(像素数),然而图像大小上的标准化也会带来一些信息的损失。(2)机器学习算法可能需要成千上万张图像,甚至更多。如果这些图像非常大,就会占用大量内存,通过这种方式可以大大减少内存使用量。在机器学习中常见的图像规格有:3232、6464、256*256等...
通过裁剪图像的边缘来更改尺寸,图象被编码为二维NumPy数组,因此通过对数组切片可以方便地裁剪图像:
# 选择所有行和前300列
image_cropped = image[:, :300]
plt.imshow(image_cropped, cmap='gray'),plt.axis('off')
plt.show()
平滑处理图像:将每个像素的值变换为其相邻像素值的平均值。相邻像素和所执行的操作在数学上被表示为一个核。这个核的大小决定了平滑的程度,核越大,产生的图像就越平滑。下面我们使用5*5的核对每个像素周围的值取平均值:
#平滑处理
image_blurry = cv2.blur(image, (5,5))
plt.imshow(image_blurry, cmap='gray'),plt.axis('off')
plt.show()
image_blurry = cv2.blur(image, (100,100))
在图像处理中,核被广泛应用于图像锐化到边缘检测的所有领域:
# 创建核
kernel = np.ones((5,5))/25.0
print(kernel)
# 锐化图像
image_sharp = cv2.filter2D(image, -1, kernel)
[[0.04 0.04 0.04 0.04 0.04]
[0.04 0.04 0.04 0.04 0.04]
[0.04 0.04 0.04 0.04 0.04]
[0.04 0.04 0.04 0.04 0.04]
[0.04 0.04 0.04 0.04 0.04]]
核的中心要素是要处理的像素,其余的元素是该像素的相邻像素,由于所有像素具有相同的值(被归一化),因此每个元素对要处理的像素点有相同的权重。可以利用filter2D在图像上手动应用核,产生与之前一样的效果。
创建一个能突出显示目标像素的核,然后使用filter2D将其应用于图像:
# 创建核
kernel = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
# 锐化图像
image_sharp = cv2.filter2D(image, -1, kernel)
【说明】:图像锐化时,我们使用能突显出像素自身的核,锐化可以使图像的边缘更加突出。
直方图均衡是一种图像处理方法,它可以使图像中的物体和形状更加突出,。对于灰度图像,可以直接在图像上应用OpenCV的equalizeHist:
# 提高对比度
image_enhanced = cv2.equalizeHist(image)
# 加载图像
image_bgr = cv2.imread('plane.jpg')
# 转换成YUV格式
image_yuv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2YUV)
# 对图像应用直方图均衡
image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])
# 转换成RGB格式
image_rgb = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2BGR)
【说明】:经过直方图均衡后的图像往往看起来不“真实”,但是图像只是底层数据的可视化表现。
import cv2
import numpy as np
from matplotlib import pyplot as plt
image_bgr = cv2.imread('plane.jpg')
# 将BGR格式转换成HSV格式
image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
# 定义HSV格式中蓝色分量区间
lower_blue = np.array([50, 15, 50])
upper_blue = np.array([130, 255, 255])
# 创建掩模
mask = cv2.inRange(image_hsv, lower_blue, upper_blue)
# 应用掩模
image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)
# 从BGR格式转换成RGB格式
image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)
plt.imshow(image_rgb), plt.axis('off')
plt.show()
【说明】:在OpenCV中,分离颜色很简单:首先,将图像转换成HSV格式(色调、饱和度、亮度);其次,定义要分离的一系列值,这部分工作可能是最困难和最耗时的。然后,创建一个掩模(只保留掩模的白色区域):
plt.imshow(mask, cmap='gray'), plt.axis('off')
图像二值化是指对图像进行阈值处理,将强度大于某个阈值的像素设为白色并将小于该值像素设置为黑色的过程。还有一种更先进的技术“自适应阈值处理”,一个像素的阈值是由其相邻像素的强度决定的。当图像中不同区域光照条件有差异时,这种方法处理会很有帮助。
import cv2
import numpy as np
from matplotlib import pyplot as plt
image_grey = cv2.imread('plane.jpg', cv2.IMREAD_GRAYSCALE)
# 应用自适应阈值处理:
max_output_value = 255
neighborhood_size = 99
subtract_from_mean = 15
image_binarized = cv2.adaptiveThreshold(image_grey,
max_output_value,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
neighborhood_size,
subtract_from_mean)
plt.imshow(image_binarized, cmap='gray'), plt.axis('off')
plt.show()
【说明】:对图像进行阈值处理的一个主要优点:图像去噪--------只保留最重要的元素(如:可以对文本的图片进行阈值处理,已提取照片上的文字)
import cv2
import numpy as np
from matplotlib import pyplot as plt
image_grey = cv2.imread('plane.jpg', cv2.IMREAD_GRAYSCALE)
# 计算像素强调中位数
median_intensity = np.median(image_grey)
# 设置阈值
lower_threshold = int(max(0, (1.0 - 0.33) * median_intensity))
upper_threshold = int(min(255, (1.0 + 0.33) * median_intensity))
# 应用Canny边缘检测器
image_canny = cv2.Canny(image_grey, lower_threshold, upper_threshold)
plt.imshow(image_canny, cmap='gray'), plt.axis('off')
plt.show()
评论