计算机视觉基础

计算机视觉概述

什么是计算机视觉

  • 计算机视觉在广义上是和图像相关的技术总称。包括图像的采集获取,图像的压缩编码,图像的存储和传输,图像的合成,三维图像重建,图像增强,图像修复,图像的分类和识别,目标的检测、跟踪、表达和描述,特征提取,图像的显示和输出等等。
  • 随着计算机视觉在各种场景的应用和发展,已有的图像技术也在不断的更新和扩展。

计算机视觉的应用

  • 公安安防:人脸识别,指纹识别,场景监控,环境建模。
  • 生物医学:染色体分析,X光、CT图像分析,显微医学操作。
  • 文字处理:文字识别,文档修复,办公自动化,垃圾邮件分类。
  • 国防军事:资源探测,军事侦察,导弹路径规划。
  • 智能交通:公路交通管理,电子警察执法抓拍系统,自动驾驶车辆。
  • 休闲娱乐:电影特效,视频编辑,人像美颜,体感游戏,VR。

计算机视觉相关学科

  • 计算机视觉是一门研究图像理论、技术和应用的交叉学科。计算机视觉不仅和传统的数学、物理学、生理学、心理学、计算机科学、电子工程等学科相关。并且还涉及到计算机图形学、图像模式识别、图像工程等专业技术,这几个技术名词相互关联,经常混合使用,在许多情况下他们只是专业背景不同的人习惯使用的不同称呼术语。

QQ截图20230706154154.jpg

数字图像处理基础

人眼成像原理

  • 人的眼睛近似为一个球体。物体的光线通过角膜和晶状体的折射,在视网膜上成倒立缩小的实像。
  • 视网膜上分布光线接收的神经细胞,分为锥状体和杆状体。每只眼睛有600万-700万个锥状体,其对颜色灵敏度很高,负责亮光视觉。有7500万- 15000万杆状体,杆状体没有颜色感觉,负责暗视觉。

QQ截图20230706154308.jpg

计算机成像原理

  • 数字图像的采集过程类似人眼,使用大量的光敏传感器构成的阵列获取图像。成像的质量由传感器的单元数,尺寸和传感性能决定。
  • 多数传感器的输出是连续的电压波形,图像数字化就是将一副画面的数据转换为计算机能够处理的数字形式。
  • 图像数字化包括两种处理过程:采样和量化。

QQ截图20230706154312.jpg

图像采样与分辨率

  • 将空间上连续的图像变换成离散点的操作称为采样
  • 采样是按照某种时间间隔或空间间隔,采集模拟信号的过程,即空间离散化。
  • 图像数字化的采样过程是将空间上连续的图像变化为离散的点。
  • 采样的效果由传感器的采样间隔和采样孔径决定,采样间隔和采样孔径的大小是两个很重要的参数。
  • 采样后得到离散图像的尺寸称为图像分辨率。分辨率是数字图像可辨别的最小细节。
  • 分辨率由宽(width)和高(height)两个参数构成。宽表示水平方向的细节数,高表示垂直方向的细节数。
  • 一副640*480分辨率的图像,表示这幅图像是由640*480=307200个点组成。
  • 一副1920*1080分辨率的图像,表示这幅图像是由1920*1080= 2073600个点组成。
  • 采样间隔越小,所得图像像素数越多,空间分辨率高,图像质量好,但数据量大。下图展示了lena图的分辨率从512x512依次降低到8x8的图像效果。

QQ截图20230706155518.jpg

灰度级与灰度图像

  • 灰度级(depth)表征了每个采样点的传感器输出中可分辨的最小变化。
  • 灰度级通常是2的整数次幂。我们用m级或者n位来表示灰度级。图像数据的灰度级越多视觉效果就越好。计算机中最常用的是8位图像。
  • 一副8位的图像,表示每个采样点有2^8=256级。从最暗到最亮,可以分辨256个级别。
  • 一副32级的灰度图像,每个采样点从最暗到最亮,可以分辨32个级别。
  • 量化等级越多,所得图像层次越丰富,灰度分辨率高,图像质量好,但数据量大。下图展示了lena图的灰度级从256级依次降低到4级的图像效果。

QQ截图20230706155848.jpg

  • 单通道的数字图像被称为灰度图。通常,单通道记录了采样点的亮度信息,例如8位的图像,0表示最暗(黑色),255表示最亮(白色)。

QQ截图20230706155907.jpg

彩色图像与色彩空间

为了表征彩色图像,我们需要使用多通道数字图像。最普遍的方式是使用RGB颜色空间。RGB颜色空间中每个像素点有三个维度,分别记录在红(Red)、绿(Green)、蓝(Blue)三原色的分量上的亮度。

QQ截图20230706160036.jpg

  • 另一种常用的颜色空间是HSV,该颜色空间可以用一个圆锥来表示。
  • HSV表示色相(hue)、饱和度(saturation)和亮度(value)。
  • H表示颜色的相位角(hue) ,取值范围是0---360;S表示颜色的饱和度(saturation) ,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率;
  • V表示色彩的明亮程度(value) ,范围从0到1

QQ截图20230706160343.jpg

  • YUV:亮度信号Y和两个色差信号R-Y、B-Y,最后发送端将亮度和色差三个信号分别进行编码。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量,那么这样表示的图就是黑白灰度图。YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法。YUV色彩空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。与RGB视频信号传输相比,YUV只需占用极少的频宽。
  • CMYK :CMYK颜色空间应用于印刷工业,印刷业通过青(C)、品(M)、黄(Y)、黑(BK)四色油墨的不同网点面积率的叠印来表现丰富多彩的颜色和阶调。
  • Lab:Lab的色彩空间要比RGB模式和CMYK模式的色彩空间大,自然界中任何一点色都可以在Lab空间中表达出来。

颜色空间变换

  • 在计算机视觉中,尤其是颜色识别相关的算法设计中,各种颜色空间混合使用是常见的方法。RGB,HSV,YUV等常见颜色空间可以通过计算公式实现相互转化,这个过程叫做颜色空间变化。颜色变换的计算公式比较复杂,通常图像处理库会提供颜色空间变化的API给用户调用。

常用图像处理技术

  • 色彩处理
  1. 灰度化:将彩色图像转换为灰度图像
  2. 二值化/反二值化:将灰度图像转换为只有两种颜色的图像
  3. 色彩提取:提取指定的颜色
  4. 直方图均衡化:调节图像统计直方图分布
  5. 亮度、饱和度、色调调整
  • 形态相关操作
  1. 仿射变换:旋转、平移
  2. 缩放、裁剪
  3. 图像相加、相减
  4. 透视变换
  5. 图像腐蚀、膨胀、形态学梯度
  • 色彩梯度
  1. 模糊
  2. 锐化
  3. 边沿检测
  • 轮廓处理
  1. 轮廓查找、绘制
  2. 绘制矩形、圆型、椭圆包围
  3. 多边形拟合

图像色彩操作

OpenCV安装

  • 执行以下命令安装opencv-python库(核心库)和opencv-contrib-python库(贡献库)。注意:命令拷贝后要合成一行执行,中间不要换行。
# 安装opencv核心库
pip3 install  --user opencv-python==4.3.0.38 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/  --trusted-host https://pypi.tuna.tsinghua.edu.cn

# 安装opencv贡献库
pip3 install  --user opencv-contrib-python==4.3.0.38 --index-url https://pypi.tuna.tsinghua.edu.cn/simple/  --trusted-host https://pypi.tuna.tsinghua.edu.cn

图像色彩调整

亮度调整

  • 对HSV空间的V分量进行处理可以实现对图像亮度的增强。
  • 直接将彩色图像灰度化,也可以得到代表图像亮度的灰度图进行图像处理,计算量比HSV颜色空间变化低。但在HSV空间中进行处理可以得到增强后的彩色图像。

QQ截图20230706160950.jpg

饱和度调整

  • 对HSV空间的S分量进行处理可以实现对图像饱和度的增强。
  • 饱和度的调整通常是在S原始值上乘以一个修正系数。
  • 修正系数大于1,会增加饱和度,使图像的色彩更鲜明;
  • 修正系数小于1,会减小饱和度,使图像看起来比较平淡。

QQ截图20230706161008.jpg

色调调整

  • 对HSV空间的H分量进行处理可以实现对图像色调的增强。
  • 色相H的值对应的是一个角度,并且在色相环上循环。所以色相的修正可能会造成颜色的失真。
  • 色相的调整通常在H原始值上加上一个小的偏移量,使其在色相环上有小角度的调整。调整后,图像的色调会变为冷色或者暖色。

QQ截图20230706161034.jpg

图像通道操作代码实现

'''
对图像的某个通道进行操作
'''

import cv2

img = cv2.imread('../data/opencv2.png')
cv2.imshow('img',img)

b = img[:,:,0]
cv2.imshow('b',b)
img[:,:,0] = 0
cv2.imshow('b0',img)
img[:,:,1] = 0
cv2.imshow('b0g0',img)

cv2.waitKey()
cv2.destroyAllWindows()

QQ截图20230706163246.jpg

图像灰度化

什么是图像灰度化

  • 在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。将RGB图像转换为灰度图像的过程称为图像灰度化处理。

QQ截图20230706161138.jpg

如何进行图像灰度化

  • 分量法。将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。
  • 最大值法。将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
  • 将彩色图像中的三分量亮度求平均得到一个灰度值。
  • 根据重要性及其它指标,将三个分量以不同的权值进行加权平均。例如,由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。如:
  • f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j)

图像灰度化代码实现

import cv2

# 读取图片
img = cv2.imread('../data/Linus.png',1)

# 展示图片
cv2.imshow('img',img)
# 使用cvtColor进行颜色空间变化,COLOR_BGR2GRAY表示BGR to GRAY
# 彩色图像灰度化
imggray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 展示图片
cv2.imshow('imggray',imggray)

# 等待按下任意键
cv2.waitKey()
# 关闭所有窗口
cv2.destroyAllWindows()

QQ截图20230706161434.jpg

二值化与反二值化

二值化

  • 二值化阈值处理是将原始图像处理为仅有两个值的二值图像,对于灰度值大于阈值t的像素点,将其灰度值设定为最大值。对于灰度值小于或等于阈值的像素点,将其灰度值设定为0

QQ截图20230706162937.jpg

反二值化

  • 反二值化阈值处理的结果也是仅有两个值的二值图像,对于灰度值大于阈值的像素点,将其值设定为0;对于灰度值小于或等于阈值的像素点,将其值设定为255。

QQ截图20230706163001.jpg

二值化代码实现

import cv2

img = cv2.imread('../data/lena.jpg',0)
cv2.imshow('img',img)

#二值化
t,binary = cv2.threshold(img,
                         100, #阈值
                         255, #大于阈值转成的最大值
                         cv2.THRESH_BINARY)#二值化

cv2.imshow('binary',binary)

#反二值化
t,binary_inv = cv2.threshold(img,
                         100, #阈值
                         255, #大于阈值转成的最大值
                         cv2.THRESH_BINARY_INV)#反二值化

cv2.imshow('binary_inv',binary_inv)

cv2.waitKey()
cv2.destroyAllWindows()

QQ截图20230706164000.jpg

直方图均衡化处理

图像直方图

  • 灰度直方图反映的是一幅图像中各灰度级像素出现的频率。以灰度级为横坐标,纵坐标为灰度级的频率,绘制频率同灰度级的关系图就是灰度直方图。它是图像的一个重要特征,反映了图像灰度分布的情况。
  • 使用直方图进行图像变换是一种基于概率论的处理方法,通过改变图像的直方图,修改图像中各像素的灰度值,达到增强图像视觉效果的目的。
  • 相对于灰度变化只针对单独的像素点操作,直方图变化综合考虑了全图的灰度值分布。
  • 下面是两幅灰度图像的直方图,直方图的形状能反映图像的视觉效果。

QQ截图20230706164103.jpg

  • 对于彩色图像,可以对不同的通道分别统计直方图

QQ截图20230706164121.jpg

直方图均衡化

  • 直方图均衡化将原始图像的直方图,即灰度概率分布图,进行调整,使之变化为均衡分布的样式,达到灰度级均衡的效果,可以有效增强图像的整体对比度。
  • 直方图均衡化能够自动的计算变化函数,通过该方法自适应得产生有均衡直方图的输出图像。能够对图像过暗、过亮和细节不清晰的图像得到有效的增强。
  • 在常用的图像处理库中,直方图操作都有API直接调用实现。

QQ截图20230706164200.jpg

直方图均衡化代码实现

  • 灰度图像直方图均衡化
import cv2
import matplotlib.pyplot as plt

img = cv2.imread('../data/sunrise.jpg',0)
cv2.imshow('img',img)

#直方图均衡化
img_equ = cv2.equalizeHist(img)
cv2.imshow('img_equ',img_equ)

plt.figure('Hist')
plt.subplot(1,2,1)
plt.hist(img.ravel(),bins=256,range=[0,256])
plt.subplot(1,2,2)
plt.hist(img_equ.ravel(),bins=256,range=[0,256])
plt.show()

cv2.waitKey()
cv2.destroyAllWindows()

QQ截图20230706164702.jpg

QQ截图20230706164925.jpg

  • 彩色图像直方图均衡化
import cv2

img = cv2.imread('../data/sunrise.jpg')
cv2.imshow('img',img)

#imread读到的彩色图像色彩空间为BGR
#BGR--->HSV
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

hsv[...,2] = cv2.equalizeHist(hsv[...,2])

#HSV--->BGR
res = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
cv2.imshow('hsv',res)

cv2.waitKey()
cv2.destroyAllWindows()

QQ截图20230706172110.jpg

色彩提取

  • 从图片中提取特定颜色
import cv2
import numpy as np

im = cv2.imread("../data/opencv2.png")
hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
cv2.imshow('opencv', im)

# =============指定蓝色值的范围=============
# 蓝色H通道值为120,通常取120上下10的范围
# S通道和V通道通常取50~255间,饱和度太低、色调太暗计算出来的颜色不准确
minBlue = np.array([110, 50, 50])
maxBlue = np.array([130, 255, 255])
# 确定蓝色区域
mask = cv2.inRange(hsv, minBlue, maxBlue)  # 选取出掩模
# cv2.imshow("mask", mask)
# 通过掩码控制的按位与运算,锁定蓝色区域
blue = cv2.bitwise_and(im, im, mask=mask)  # 执行掩模运算
cv2.imshow('blue', blue)

# =============指定绿色值的范围=============
minGreen = np.array([50, 50, 50])
maxGreen = np.array([70, 255, 255])
# 确定绿色区域
mask = cv2.inRange(hsv, minGreen, maxGreen)
# cv2.imshow("mask", mask)
# 通过掩码控制的按位与运算,锁定绿色区域
green = cv2.bitwise_and(im, im, mask=mask)  # 执行掩模运算
cv2.imshow('green', green)

# =============指定红色值的范围=============
minRed = np.array([0, 50, 50])
maxRed = np.array([30, 255, 255])
# 确定红色区域
mask = cv2.inRange(hsv, minRed, maxRed)
# cv2.imshow("mask", mask)
# 通过掩码控制的按位与运算,锁定红色区域
red = cv2.bitwise_and(im, im, mask=mask)  # 执行掩模运算
cv2.imshow('red', red)

cv2.waitKey()
cv2.destroyAllWindows()

13_提取颜色.png

图像形态操作

仿射变换

什么是仿射变换

  • 仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像在完成仿射变换后,平行线仍然是平行线。

QQ截图20230706172234.jpg

平移

QQ截图20230706172247.jpg

镜像

QQ截图20230706172311.jpg

旋转

QQ截图20230706172325.jpg

透视变换

  • 透视变换是将图片投影到一个新的视平面,也称作投影映射.它是二维(x,y)到三维(X,Y,Z),再到另一个二维(x’,y’)空间的映射.
  • 相对于仿射变换,它提供了更大的灵活性,将一个四边形区域映射到另一个四边形区域(不一定是平行四边形).透视变换可用于图像形状校正。

QQ截图20230706172352.jpg

图像翻转代码实现

# 图像翻转示例
import numpy as np
import cv2

im = cv2.imread("../data/Linus.png")
cv2.imshow("src", im)

# 0-垂直镜像
im_flip0 = cv2.flip(im, 0)
cv2.imshow("im_flip0", im_flip0)

# 1-水平镜像
im_flip1 = cv2.flip(im, 1)
cv2.imshow("im_flip1", im_flip1)

cv2.waitKey()
cv2.destroyAllWindows()

03_图像翻转.png

图像仿射变换代码实现

# 图像仿射变换
import numpy as np
import cv2

def translate(img, x, y):
    """
    坐标平移变换
    :param img: 原始图像数据
    :param x:平移的x坐标
    :param y:平移的y坐标
    :return:返回平移后的图像
    """
    h, w = img.shape[:2]  # 获取图像高、宽

    # 定义平移矩阵
    M = np.float32([[1, 0, x],
                    [0, 1, y]])
    # 使用openCV仿射操作实现平移变换
    shifted = cv2.warpAffine(img, M, (w, h))  # 第三个参数为输出图像尺寸

    return shifted  # 返回平移后的图像


def rotate(img, angle, center=None, scale=1.0):
    """
    图像旋转变换
    :param img: 原始图像数据
    :param angle: 旋转角度
    :param center: 旋转中心,如果为None则以原图中心为旋转中心
    :param scale: 缩放比例,默认为1
    :return: 返回旋转后的图像
    """
    h, w = img.shape[:2]  # 获取图像高、宽

    # 旋转中心默认为图像中心
    if center is None:
        center = (w / 2, h / 2)

    # 计算旋转矩阵
    M = cv2.getRotationMatrix2D(center, angle, scale)

    # 使用openCV仿射变换实现函数旋转
    rotated = cv2.warpAffine(img, M, (w, h))

    return rotated  # 返回旋转后的矩阵

if __name__ == "__main__":
    # 读取并显示原始图像
    im = cv2.imread("../data/Linus.png")
    cv2.imshow("SrcImg", im)

    # 图像向下移动50像素
    shifted = translate(im, 0, 50)
    cv2.imshow("Shifted1", shifted)

    # 图像向左移动40, 下移动40像素
    shifted = translate(im, -40, 40)
    cv2.imshow("Shifted2", shifted)

    # 逆时针旋转45度
    rotated = rotate(im, 45)
    cv2.imshow("rotated1", rotated)

    # 顺时针旋转180度
    rotated = rotate(im, -90)
    cv2.imshow("rorated2", rotated)

    cv2.waitKey()
    cv2.destroyAllWindows()

06_图像位置变换.png

透视变换代码实现

# 透视变换
import cv2
import numpy as np

img = cv2.imread('../data/pers.png')
rows, cols = img.shape[:2]
print(rows, cols)

pts1 = np.float32([[58, 2], [167, 9], [8, 196], [126, 196]])# 输入图像四个顶点坐标
pts2 = np.float32([[16, 2], [167, 8], [8, 196], [169, 196]])# 输出图像四个顶点坐标

# 生成透视变换矩阵
M = cv2.getPerspectiveTransform(pts1, # 输入图像四个顶点坐标
                                pts2) # 输出图像四个顶点坐标
print(M.shape)
# 执行透视变换,返回变换后的图像
dst = cv2.warpPerspective(img, # 原始图像
                          M, # 3*3的变换矩阵
                          (cols, rows)) # 输出图像大小


# 生成透视变换矩阵
M = cv2.getPerspectiveTransform(pts2, # 输入图像四个顶点坐标
                                pts1) # 输出图像四个顶点坐标
# 执行透视变换,返回变换后的图像
dst2 = cv2.warpPerspective(dst, # 原始图像
                          M, # 3*3的变换矩阵
                          (cols, rows)) # 输出图像大小
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.imshow("dst2", dst2)

cv2.waitKey()
cv2.destroyAllWindows()

透视变换.png

算数运算

图像加法

  • 图像加法可以用于多幅图像平均去除噪声

QQ截图20230707134804.jpg

  • 图像加法实现水印的叠加

QQ截图20230707134819.jpg

图像减法

  • 图像减法是找出两幅图像的差异,可以在连续图像中可以实现消除背景和运动检测

QQ截图20230707134840.jpg

图像相加代码实现

# 图像相加示例
import cv2

a = cv2.imread("../data/lena.jpg", 0)
b = cv2.imread("../data/lily_square.png", 0)

dst1 = cv2.add(a, b)  # 图像直接相加,会导致图像过亮、过白

# 加权求和:addWeighted
# 图像进行加权和计算时,要求src1和src2必须大小、类型相同
dst2 = cv2.addWeighted(a, 0.6, b, 0.4, 0)  # 最后一个参数为亮度调节量

cv2.imshow("a", a)
cv2.imshow("b", b)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)

cv2.waitKey()
cv2.destroyAllWindows()

04_图像相加.png

图像相减代码实现

# 图像相减运算示例
import cv2

a = cv2.imread("../data/3.png", 0)
b = cv2.imread("../data/4.png", 0)

dst = cv2.subtract(a, b)  # 两幅图像相减,是求出图像的差异

cv2.imshow("a", a)
cv2.imshow("b", b)
cv2.imshow("dst1", dst)

cv2.waitKey()
cv2.destroyAllWindows()

05_图像相减.png

图像缩放

缩放

  • 图像缩放(image scaling)是指对数字图像的大小进行调整的过程。将分辨率为(w,h)的图像,缩放为(w', h')的图像,水平方向系数为Sx= w' / w, 垂直方向缩放系数为Sy= h' / h。缩放变换矩阵为

QQ截图20230707135024.jpg

QQ截图20230707135041.jpg

图像缩小

  • 图像缩小可以通过删除矩阵中的元素来实现,例如:下面的例子进行隔行、隔列删除后,高度、宽度均减小为原来的一半

QQ截图20230707135107.jpg

图像放大

  • 图像放大需要进行像素插入,常用的插值法有最邻近插值法和双线性插值法
  • 最邻近插值法:直接使用新的像素点(x', y')最近的整数坐标灰度值作为该点的值,该方法计算量小,但精确度不高,并且可能破坏图像中的线性关系
  • 双线性插值法:使用新的像素点(x',y')最邻近的四个像素值进行插值计算,假设为(i,j),(i+1,j)(i,j+1),(i+1,j+1),则u=x'-i,v=y'-j.

QQ截图20230707135144.jpg

  • 下图是最邻近插值法和双线性插值法的效果对比

QQ截图20230707135201.jpg

图像缩放代码实现

# 图像缩放示例
import numpy as np
import cv2

im = cv2.imread("../data/Linus.png")
cv2.imshow("src", im)

h, w = im.shape[:2]  # 获取图像尺寸


dst_size = (int(w/2), int(h/2))  # 缩放目标尺寸,宽高均为原来1/2
resized = cv2.resize(im, dst_size)  # 执行缩放
cv2.imshow("reduce", resized)

dst_size = (200, 300)  # 缩放目标尺寸,宽200,高300
method = cv2.INTER_NEAREST  # 最邻近插值
resized = cv2.resize(im, dst_size, interpolation=method)  # 执行缩放
cv2.imshow("NEAREST", resized)

dst_size = (200, 300)  # 缩放目标尺寸,宽200,高300
method = cv2.INTER_LINEAR  # 双线性插值
resized = cv2.resize(im, dst_size, interpolation=method)  # 执行缩放
cv2.imshow("LINEAR", resized)

cv2.waitKey()
cv2.destroyAllWindows()

07_图像缩放.png

图像裁剪代码实现

import numpy as np
import cv2


# 图像随机裁剪
def random_crop(im, w, h):
    start_x = np.random.randint(0, im.shape[1])  # 裁剪起始x像素
    start_y = np.random.randint(0, im.shape[0])  # 裁剪起始y像素

    new_img = im[start_y:start_y + h, start_x: start_x + w]  # 执行裁剪

    return new_img


# 图像中心裁剪
def center_crop(im, w, h):
    start_x = int(im.shape[1] / 2) - int(w / 2)  # 裁剪起始x像素
    start_y = int(im.shape[0] / 2) - int(h / 2)  # 裁剪起始y像素

    new_img = im[start_y:start_y + h, start_x: start_x + w]  # 执行裁剪

    return new_img


im = cv2.imread("../data/banana_1.png", 1)

new_img = random_crop(im, 200, 200)  # 随机裁剪
new_img2 = center_crop(im, 200, 200)  # 中心裁剪

cv2.imshow("orig", im)
cv2.imshow("random_crop", new_img)
cv2.imshow("center_crop", new_img2)

cv2.waitKey()
cv2.destroyAllWindows()

图像裁剪.png

腐蚀与膨胀

图像腐蚀

  • 腐蚀是最基本的形态学操作之一,它能够将图像的边界点消除,使图像沿着边界向内收缩,也可以将小于指定结构体元素的部分去除。腐蚀用来“收缩”或者“细化”二值图像中的前景,借此实现去除噪声、元素分割等功能

QQ截图20230707135227.jpg

图像膨胀

  • 图像膨胀(dilate)是指根据原图像的形状,向外进行扩充。如果图像内两个对象的距离较近,那么在膨胀的过程中,两个对象可能会连通在一起。膨胀操作对填补图像分割后图像内所存在的空白相当有帮助。

QQ截图20230707135243.jpg

图像开运算

  • 开运算进行的操作是先将图像腐蚀,再对腐蚀的结果进行膨胀。开运算可以用于去噪、计数等

QQ截图20230707135311.jpg

  • 开运算可用于取出主题图像之间细小的连接

QQ截图20230707135327.jpg

图像闭运算

  • 闭运算是先膨胀、后腐蚀的运算,它有助于关闭前景物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景图像进行连接。

QQ截图20230707135348.jpg

QQ截图20230707135357.jpg

形态学梯度

  • 形态学梯度运算是用图像的膨胀图像减腐蚀图像的操作,该操作可以获取原始图像中前景图像的边缘。

QQ截图20230707135418.jpg

礼帽运算

  • 礼帽运算是用原始图像减去其开运算图像的操作。礼帽运算能够获取图像的噪声信息,或者得到比原始图像的边缘更亮的边缘信息

QQ截图20230707135440.jpg

黑帽运算

  • 黑帽运算是用闭运算图像减去原始图像的操作。黑帽运算能够获取图像内部的小孔,或前景色中的小黑点,或者得到比原始图像的边缘更暗的边缘部分。

QQ截图20230707135500.jpg

图像腐蚀代码实现

# 图像腐蚀
import cv2
import numpy as np

# 读取原始图像
im = cv2.imread("../data/5.png")
cv2.imshow("im", im)

# 腐蚀
kernel = np.ones((3, 3), np.uint8) # 用于腐蚀计算的核
erosion = cv2.erode(im, # 原始图像
                    kernel,  # 腐蚀核
                    iterations=3) # 迭代次数
cv2.imshow("erosion", erosion)

cv2.waitKey()
cv2.destroyAllWindows()

图像腐蚀.png

图像膨胀代码实现

# 图像膨胀
import cv2
import numpy as np

# 读取原始图像
im = cv2.imread("../data/6.png")
cv2.imshow("im", im)

# 膨胀
kernel = np.ones((3, 3), np.uint8)  # 用于膨胀计算的核
dilation = cv2.dilate(im,  # 原始图像
                      kernel,  # 膨胀核
                      iterations=5)  # 迭代次数
cv2.imshow("dilation", dilation)

cv2.waitKey()
cv2.destroyAllWindows()

图像膨胀.png

图像开运算代码实现

# 开运算示例
import cv2
import numpy as np

# 读取原始图像
im1 = cv2.imread("../data/7.png")
im2 = cv2.imread("../data/8.png")

# 执行开运算
k = np.ones((10, 10), np.uint8)
r1 = cv2.morphologyEx(im1, cv2.MORPH_OPEN, k)
r2 = cv2.morphologyEx(im2, cv2.MORPH_OPEN, k)

cv2.imshow("im1", im1)
cv2.imshow("result1", r1)

cv2.imshow("im2", im2)
cv2.imshow("result2", r2)

cv2.waitKey()
cv2.destroyAllWindows()

开运算.png

图像闭运算代码实现

# 闭运算示例
import cv2
import numpy as np

# 读取图像
im1 = cv2.imread("../data/9.png")
im2 = cv2.imread("../data/10.png")

# 闭运算
k = np.ones((8, 8), np.uint8)
r1 = cv2.morphologyEx(im1, cv2.MORPH_CLOSE, k, iterations=2)
r2 = cv2.morphologyEx(im2, cv2.MORPH_CLOSE, k, iterations=2)

cv2.imshow("im1", im1)
cv2.imshow("result1", r1)
cv2.imshow("im2", im2)
cv2.imshow("result2", r2)

cv2.waitKey()
cv2.destroyAllWindows()

闭运算.png

形态学梯度代码实现

# 形态学梯度示例
import cv2
import numpy as np

o = cv2.imread("../data/6.png")

k = np.ones((3, 3), np.uint8)
r = cv2.morphologyEx(o, cv2.MORPH_GRADIENT, k)

cv2.imshow("original", o)
cv2.imshow("result", r)

cv2.waitKey()
cv2.destroyAllWindows()

形态学梯度.png