计算机视觉是一个快速发展的领域,它涉及到图像和视频的分析与处理。OpenCV是一个开源的计算机视觉库,它提供了成千上万的优化算法和函数,用于各种图像操作。这些操作包括视频和图像分析、实时计算机视觉、目标检测、视频分析等。许多公司、研究人员和开发者都为OpenCV的创建做出了贡献。使用OpenCV非常简单,它配备了许多工具和功能。让使用OpenCV来执行一些有趣的图像操作,并查看结果。
形态学变换是一种基于形状的图像处理方法。这个过程有助于区域形状的表示和描绘。这些变换使用结构元素应用于输入图像,并生成输出图像。形态学操作有多种用途,包括从图像中去除噪声、定位图像中的强度凸起和孔洞以及连接图像中不同的元素。形态学变换主要有两种类型:腐蚀和膨胀。
腐蚀是一种形态学操作,用于减小前景对象的大小。外物体的边界逐渐被腐蚀。腐蚀在图像编辑和变换中有许多应用,它缩小了图像像素。物体边界上的像素也被移除。在Python中实现腐蚀非常简单,可以通过核的帮助来实现。
import cv2
import numpy as np
# 读取图像
image = cv2.imread("image1.jpg")
# 创建用于执行腐蚀操作的核
kernel = np.ones((5, 5), np.uint8)
# 使用cv2.erode()方法
image_erode = cv2.erode(image, kernel)
# 保存文件并查看
filename = 'image_erode1.jpg'
cv2.imwrite(filename, image_erode)
如所见,图像现在已经被腐蚀,锐度和边缘减少,图像变得模糊。腐蚀可以用来隐藏或移除图像的某些部分,或者从图像中隐藏信息。让尝试不同类型的腐蚀。
kernel2 = np.ones((3, 3), np.uint8)
image_erode2 = cv2.erode(image, kernel2, cv2.BORDER_REFLECT)
filename = 'image_erode2.jpg'
cv2.imwrite(filename, image_erode2)
膨胀是腐蚀的相反过程。在膨胀的情况下,不是缩小,而是扩大前景对象。边界附近的事物发展,形成一个扩大的对象。图像中的亮区域在膨胀后倾向于“发光”,这通常会导致图像增强。因此,膨胀用于图像校正和增强。让使用Python代码实现膨胀。
kernel3 = np.ones((5,5), np.uint8)
image_dilation = cv2.dilate(image, kernel, iterations=1)
filename = 'image_dilation.jpg'
cv2.imwrite(filename, image_dilation)
如所见,图像现在更亮,强度更高。
向图像添加边框非常简单,手机相册应用或编辑应用可以非常快速地做到这一点。但是,现在让使用Python为图像创建边框。
image_border1 = cv2.copyMakeBorder(image, 25, 25, 10, 10, cv2.BORDER_CONSTANT, None, value = 0)
filename = 'image_border1.jpg'
cv2.imwrite(filename, image_border1)
在这里,为图像添加了一个简单的黑色边框。现在,让尝试一些镜像边框。
image_border2 = cv2.copyMakeBorder(image, 250, 250, 250, 250, cv2.BORDER_REFLECT)
filename = 'image_border2.jpg'
cv2.imwrite(filename, image_border2)
这很有趣,看起来像是来自奇异博士的镜像维度。让尝试其他东西。
image_border3 = cv2.copyMakeBorder(image, 300, 250, 100, 50, cv2.BORDER_REFLECT)
filename = 'image_border3.jpg'
cv2.imwrite(filename, image_border3)
由于各种原因,图像经常需要进行强度变换。这些操作是在空间域中直接对图像像素进行的。像图像阈值处理和对比度调整这样的操作是使用强度变换完成的。
对数变换是一种强度变换操作,其中图像的像素值被替换为它们的对数值。对数变换用于增亮图像或增强图像,因为它比高像素值更多地扩展了图像中的暗像素。让实现对数变换。
c = 255/(np.log(1 + np.max(image)))
log_transformed = c * np.log(1 + image)
log_transformed = np.array(log_transformed, dtype = np.uint8)
cv2.imwrite('log_transformed.jpg', log_transformed)
图像变得非常明亮。
将对图像应用分段线性变换。这种变换也是在空间域中完成的。这种方法用于修改图像以满足特定目的。它被称为分段线性变换,因为只有部分是线性的。最常用的分段线性变换是对比度拉伸。
通常,如果图像在低光照下拍摄并且周围照明不佳,结果图像的对比度会很低。对比度拉伸增加了图像的强度水平范围,对比度拉伸函数单调增加,以保持像素强度的顺序。现在,让实现对比度拉伸。
def pixelVal(pix, r1, s1, r2, s2):
if (0 <= pix and pix <= r1):
return (s1 / r1)*pix
elif (r1 < pix and pix <= r2):
return ((s2 - s1)/(r2 - r1)) * (pix - r1) + s1
else:
return ((255 - s2)/(255 - r2)) * (pix - r2) + s2
r1 = 70
s1 = 0
r2 = 140
s2 = 255
pixelVal_vec = np.vectorize(pixelVal)
contrast_stretch = pixelVal_vec(image, r1, s1, r2, s2)
cv2.imwrite('contrast_stretch.jpg', contrast_stretch)
在这里,图像得到了改善,可以观察到更多的对比度。
去噪一个信号或图像意味着移除不必要的信号和信息以获得有用的信息。在图像的情况下,去噪是为了移除不需要的噪声,以便更好地分析和处理图像。
denoised_image = cv2.fastNlMeansDenoisingColored(image, None, 15, 8, 8, 15)
cv2.imwrite('denoised_image.jpg', denoised_image)
可以看到很多不需要的东西,比如背景和天空已经被移除。
直方图是任何形式分析中的重要视觉工具。图像的直方图是了解全局描述的有趣方式,直方图也可以用来对图像进行定量分析。图像直方图表示图像中灰度级别的出现次数。
可以使用直方图来理解数字图像的像素强度分布,还可以使用直方图来理解主导颜色。让绘制一个直方图。
from matplotlib import pyplot as plt
histr = cv2.calcHist([image],[0],None,[256],[0,256])
plt.plot(histr)
plt.hist(image.ravel(),256,[0,256])
plt.show()
grey_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
histogram = cv2.calcHist([grey_image], [0], None, [256], [0, 256])
plt.plot(histogram, color='k')
for i, col in enumerate(['b', 'g', 'r']):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color = col)
plt.xlim([0, 256])
plt.show()