【机器视觉】OpenCV 图像基本变换
文章目录
- 介绍
- 机器视觉的核心组成部分
- 机器视觉的关键技术和趋势
- 4. 图像的基本变换
- 4.1 图像的放大与缩小
- 4.2 图像的翻转
- 4.3 图像的旋转
- 4.4 仿射变换之图像平移
- 4.5 仿射变换之获取变换矩阵
- 4.6 透视变换
介绍
机器视觉(Machine Vision)是一门跨学科的领域,它结合了计算机科学、图像处理、模式识别、人工智能等多个领域的知识和技术。其主要目标是让计算机系统能够“看”并理解它们所捕捉到的视觉信息,从而实现自动化决策和操作。机器视觉广泛应用于工业制造、医疗诊断、自动驾驶、安防监控、机器人导航等众多行业。
机器视觉的核心组成部分
- 图像获取:这是机器视觉系统的起点,通常涉及使用摄像头或其他传感器来捕获图像或视频流。根据应用场景的不同,可以采用可见光相机、红外相机、3D扫描仪等多种类型的成像设备。
- 预处理:为了提高后续分析步骤的效果,原始图像可能需要经过一系列预处理操作,例如滤波去噪、灰度化、边缘检测等。这些步骤有助于去除不必要的干扰因素,并增强有用的信息特征。
- 特征提取:从预处理后的图像中提取有意义的特征,如形状、纹理、颜色等。这一步骤对于分类、识别等任务至关重要。现代深度学习模型可以直接从原始像素值中学习高级语义特征,而传统方法则依赖手工设计的特征描述符。
- 模式识别/分类:基于提取出的特征,应用统计学、机器学习或深度学习算法对对象进行分类、匹配或聚类。常见的技术包括支持向量机(SVM)、随机森林、卷积神经网络(CNN)等。
- 决策与控制:最后一步是根据前面几步的结果做出相应的响应或动作。在工业环境中,这可能意味着触发警报、调整生产参数或者执行特定的任务;而在自动驾驶汽车中,则涉及到路径规划和车辆控制。
机器视觉的关键技术和趋势
- 深度学习:近年来,随着计算能力的提升和大数据集的可用性增加,深度学习尤其是卷积神经网络(CNNs)已经成为机器视觉领域最热门的技术之一。它们在图像分类、目标检测、语义分割等方面表现出色。
- 实时处理:为了满足某些应用的需求,如自动驾驶或智能监控,机器视觉系统必须能够在极短的时间内完成复杂的视觉任务。为此,研究人员正在探索更高效的算法架构以及专用硬件加速器(如GPU、TPU)的应用。
- 多模态融合:将来自不同来源的数据(如图像、声音、文本等)结合起来,以获得更加全面的理解。例如,在医疗影像分析中,结合CT扫描和MRI图像可以提供更准确的诊断结果。
- 自监督和弱监督学习:由于标注大量数据的成本高昂且耗时,研究者们开始关注如何利用未标注或部分标注的数据来进行有效的训练。这种方法可以通过挖掘数据内在结构来减少对人工标签的依赖。
- 解释性和透明度:随着机器视觉系统越来越多地被应用于关键决策领域,确保模型预测的可解释性和透明度变得越来越重要。这不仅关系到系统的可靠性,也涉及到用户信任和社会接受度的问题。
现在说的机器视觉(Machine Vision)一般指计算机视觉(Computer Vision), 简单来说就是研究如何使机器看懂东西.
就是是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等机器视觉,并进一步做图形处理,使电脑处理成为更适合人眼观察或传送给仪器检测的图像。
OpenCV官网
4. 图像的基本变换
4.1 图像的放大与缩小
-
resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
- src: 要缩放的图片
- dsize: 缩放之后的图片大小, 元组和列表表示均可.
- dst: 可选参数, 缩放之后的输出图片
- fx, fy: x轴和y轴的缩放比, 即宽度和高度的缩放比.
- interpolation: 插值算法, 主要有以下几种:
- INTER_NEAREST, 邻近插值, 速度快, 效果差.
- INTER_LINEAR, 双线性插值, 使用原图中的4个点进行插值. 默认.
- INTER_CUBIC, 三次插值, 原图中的16个点.
- INTER_AREA, 区域插值, 效果最好, 计算时间最长.
import cv2 import numpy as np #导入图片 dog = cv2.imread('./dog.jpeg') # x,y放大一倍 new_dog = cv2.resize(dog,dsize=(800, 800), interpolation=cv2.INTER_NEAREST) cv2.imshow('dog', new_dog) cv2.waitKey(0) cv2.destroyAllWindows()
4.2 图像的翻转
- flip(src, flipCode)
- flipCode =0 表示上下翻转
- flipCode >0 表示左右翻转
- flipCode <0 上下 + 左右
# 翻转
import cv2
import numpy as np
#导入图片
dog = cv2.imread('./dog.jpeg')
new_dog = cv2.flip(dog, flipCode=-1)
cv2.imshow('dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.3 图像的旋转
- rotate(img, rotateCode)
- ROTATE_90_CLOCKWISE 90度顺时针
- ROTATE_180 180度
- ROTATE_90_COUNTERCLOCKWISE 90度逆时针
# 旋转
import cv2
import numpy as np
#导入图片
dog = cv2.imread('./dog.jpeg')
new_dog = cv2.rotate(dog, rotateCode=cv2.cv2.ROTATE_90_COUNTERCLOCKWISE)
cv2.imshow('dog', new_dog)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.4 仿射变换之图像平移
-
仿射变换是图像旋转, 缩放, 平移的总称.具体的做法是通过一个矩阵和和原图片坐标进行计算, 得到新的坐标, 完成变换. 所以关键就是这个矩阵.
-
warpAffine(src, M, dsize, flags, mode, value)
-
M:变换矩阵
-
dsize: 输出图片大小
-
flag: 与resize中的插值算法一致
-
mode: 边界外推法标志
-
value: 填充边界值
-
平移矩阵
- 矩阵中的每个像素由(x,y)组成,(x, y)表示这个像素的坐标. 假设沿x轴平移 t x t_x tx, 沿y轴平移 t y t_y ty, 那么最后得到的坐标为 ( x ^ , y ^ ) = ( x + t x , y + t y ) (\hat x, \hat y) = (x + t_x, y + t_y) (x^,y^)=(x+tx,y+ty)
# 仿射变换之平移 import cv2 import numpy as np #导入图片 dog = cv2.imread('./dog.jpeg') h, w, ch = dog.shape M = np.float32([[1, 0, 100], [0, 1, 0]]) # 注意opencv中是先宽度, 再高度 new = cv2.warpAffine(dog, M, (w, h)) cv2.imshow('new', new) cv2.waitKey(0) cv2.destroyAllWindows()
4.5 仿射变换之获取变换矩阵
仿射变换的难点就是计算变换矩阵, OpenCV提供了计算变换矩阵的API
- getRotationMatrix2D(center, angle, scale)
- center 中心点 , 以图片的哪个点作为旋转时的中心点.
- angle 角度: 旋转的角度, 按照逆时针旋转.
- scale 缩放比例: 想把图片进行什么样的缩放.
# 仿射变换之平移
import cv2
import numpy as np
#导入图片
dog = cv2.imread('./dog.jpeg')
h, w, ch = dog.shape
# M = np.float32([[1, 0, 100], [0, 1, 0]])
# 注意旋转的角度为逆时针.
# M = cv2.getRotationMatrix2D((100, 100), 15, 1.0)
# 以图像中心点旋转
M = cv2.getRotationMatrix2D((w/2, h/2), 15, 1.0)
# 注意opencv中是先宽度, 再高度
new = cv2.warpAffine(dog, M, (w, h))
cv2.imshow('new', new)
cv2.waitKey(0)
cv2.destroyAllWindows()
-
getAffineTransform(src[], dst[]) 通过三点可以确定变换后的位置, 相当于解方程, 3个点对应三个方程, 能解出偏移的参数和旋转的角度.
-
src原目标的三个点
-
dst对应变换后的三个点
-
# 通过三个点来确定M
# 仿射变换之平移
import cv2
import numpy as np
#导入图片
dog = cv2.imread('./dog.jpeg')
h, w, ch = dog.shape
# 一般是横向和纵向的点, 所以一定会有2个点横坐标相同, 2个点纵坐标相同
src = np.float32([[200, 100], [300, 100], [200, 300]])
dst = np.float32([[100, 150], [360, 200], [280, 120]])
M = cv2.getAffineTransform(src, dst)
# 注意opencv中是先宽度, 再高度
new = cv2.warpAffine(dog, M, (w, h))
cv2.imshow('new', new)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.6 透视变换
透视变换就是将一种坐标系变换成另一种坐标系. 简单来说可以把一张"斜"的图变"正".
-
warpPerspective(img, M, dsize,…)
-
对于透视变换来说, M是一个3 * 3 的矩阵.
-
getPerspectiveTransform(src, dst) 获取透视变换的变换矩阵, 需要4个点, 即图片的4个角.
# 透视变换 import cv2 import numpy as np #导入图片 img = cv2.imread('./123.png') print(img.shape) src = np.float32([[100, 1100], [2100, 1100], [0, 4000], [2500, 3900]]) dst = np.float32([[0, 0], [2300, 0], [0, 3000], [2300, 3000]]) M = cv2.getPerspectiveTransform(src, dst) new = cv2.warpPerspective(img, M, (2300, 3000)) cv2.namedWindow('img', cv2.WINDOW_NORMAL) cv2.resizeWindow('img', 640, 480) cv2.namedWindow('new', cv2.WINDOW_NORMAL) cv2.resizeWindow('new', 640, 480) cv2.imshow('img', img) cv2.imshow('new', new) cv2.waitKey(0) cv2.destroyAllWindows()