Python编程基础教程:图像处理与计算机视觉
1.背景介绍1.1 计算机视觉计算机视觉(Computer Vision)是指对某些特定领域的图像、视频或其它模态信息进行分析、理解和处理,使之成为智能化的信息源提供给计算机处理、分析、理解的领域。通过计算机视觉技术,能够实现高效自动化目标识别、监控、测绘、辅助决策等功能。
1.背景介绍
1.1 计算机视觉
计算机视觉(Computer Vision)是指对某些特定领域的图像、视频或其它模态信息进行分析、理解和处理,使之成为智能化的信息源提供给计算机处理、分析、理解的领域。通过计算机视觉技术,能够实现高效自动化目标识别、监控、测绘、辅助决策等功能。
1.2 图像处理
图像处理(Image Processing)是指利用计算机对图像、视频、文本等多媒体数据进行数字化、存储、检索、分析、检索、传输等一系列操作的过程。包括图像增强、颜色增强、噪声去除、平衡化、锐化、缩放、旋转、切割、分割、修复、重建等一系列图像处理算法。
1.3 OpenCV简介
OpenCV (Open Source Computer Vision Library),是基于BSD许可证发行的一个开源计算机视觉库,由英国计算机视觉研究小组(The British Machine Vision Association – BMVC)开发和维护。它提供了用于图像处理及计算机视觉方面的很多模块,如图形变换、特征提取、对象检测和跟踪、轮廓检测、图像编码与解码等。其由以下四个主要部分构成:
1.基础库:包含基本的矩阵运算函数、数据结构等 2.图形处理:包含各种图像处理算法,如滤波、锐化、裁剪、旋转、仿射变换、直方图等 3.机器学习:包含机器学习相关的算法,如KNN、SVM、随机森林等 4.计算机视觉API:为程序员提供了丰富的接口和高级工具,支持图像的读取、写入、显示、图像处理等任务。
2.核心概念与联系
2.1 颜色空间
计算机中的颜色分为RGB三原色、CMY黑白及其他颜色,对于彩色图像而言,不同光源和照明条件下会产生不同的颜色,因此需要将不同颜色表示的方式进行转换,使得图像在各个设备上呈现一致的颜色。颜色空间即是用来表示颜色的一种抽象模式。常用的颜色空间有:RGB、HSV、YCrCb等。
2.2 图像格式
图像文件格式又称为影像文件格式,它描述了在文件中组织图像数据的方式。常用图像文件格式包括BMP、JPEG、PNG、TIFF、GIF等。
2.3 坐标系
在计算机视觉领域,常用的图像坐标系分为两种:
- 笛卡尔坐标系:是最简单的一种坐标系,笛卡尔坐标系是平面直角坐标系,原点在坐标轴的左上角。
- 椭圆坐标系:椭圆坐标系也是二维坐标系,不同于笛卡尔坐标系,其位于原点的横轴、纵轴分别与坐标轴相交,并且也满足两条轴的长度比例不变。
2.4 边缘检测
边缘检测是指从图像中检测出其边缘、轮廓或缺陷的过程。常用的边缘检测方法有:
- Canny算法:是目前最流行的边缘检测算法,该算法包含两个阶段:第一阶段是计算梯度幅值和方向,第二阶段是进行阈值分割,最后输出边缘结果。
- Sobel算子:由两个卷积核组成,一个负方向卷积核(Dx)、一个正方向卷积核(Dy),通过对图像卷积实现梯度幅值和方向计算。
- Laplacian算子:即拉普拉斯算子,也属于卷积核形式,对图像进行二阶微分求导再取绝对值,以计算图像的边缘强度和方向。
2.5 分水岭算法
分水岭算法(Watershed Algorithm)是一种区域生长模式分割方法,它可以自动地对图像中的物体边界与背景区域进行分割,基于“连通分量”的概念,先把图像中的所有连通的背景区域连接起来,然后再开辟新的区域生长。
2.6 HOG特征描述符
HOG(Histogram of Oriented Gradients)特征描述符是一种描述图像局部特征的方法。其基本想法是将图像分成多个小块(cell),并在每个小块中生成一组梯度方向直方图(gradient histogram)。HOG算法描述了图像中每一组梯度方向直方图的统计特征,从而对图像的局部特征进行描述。
2.7 CNN卷积神经网络
CNN(Convolutional Neural Network)是一种深度学习模型,用于图像分类、目标检测、语义分割等。CNN的特点是具有共享参数的多个卷积层,这样就可以共同学习到输入的图像的一些共同的特征,有效地降低了训练难度,提高了模型性能。
3.核心算法原理和具体操作步骤以及数学模型公式详细讲解
3.1 图像亮度、对比度与饱和度调整
亮度(Brightness)、对比度(Contrast)、饱和度(Saturation)三个方面对图像的修改是最常见的,可以让图片更鲜艳、清晰或者不那么浓重。如下所示:
import cv2
import numpy as np
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 灰度化
equ = cv2.equalizeHist(gray) # 对比度均衡化
bright = cv2.addWeighted(gray,1.2,np.zeros(gray.shape,gray.dtype),0,-90) # 图像增加亮度
contr = cv2.multiply(gray,1.5,scale=0) # 图像增加对比度
satu = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)
for i in range(satu.shape[0]):
for j in range(satu.shape[1]):
b,g,r = satu[i][j]
r += 50; g += 50; b += 50
if r > 255:
r = 255
if g > 255:
g = 255
if b > 255:
b = 255
satu[i][j] = [b,g,r]
cv2.imshow('origin', img)
cv2.imshow('gray', gray)
cv2.imshow('equ', equ)
cv2.imshow('bright', bright)
cv2.imshow('contrast', contr)
cv2.imshow('saturation', satu)
cv2.waitKey()
cv2.destroyAllWindows()
3.2 图像灰度化与二值化
图像灰度化(Grayscale Conversion)即把彩色图像转换为灰度图像,其中采用常用的抖动(Additive Grayscale)或权重平均(Weight Average Grayscale)方法。在二值化过程中,通常采用阈值分割(Thresholding)的方法,将灰度值大于某个阈值的像素置为1(前景),小于某个阈值的像素置为0(背景)。如下所示:
import cv2
import numpy as np
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 灰度化
ret,binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY) # 全局阈值分割
otsu = cv2.threshold(gray,0,255,cv2.THRESH_OTSU)[1] # Otsu阈值分割
cv2.imshow('origin', img)
cv2.imshow('gray', gray)
cv2.imshow('binary', binary)
cv2.imshow('otsu', otsu)
cv2.waitKey()
cv2.destroyAllWindows()
3.3 形态学操作
形态学操作(Morphological Operations)是基于图像的结构,包括膨胀(Dilation)、腐蚀(Erosion)、开(Opening)、闭(Closing)等。它们能够消除或填充图像中噪声、细节、小颗粒、边界等。操作方法包括矩形核(矩形)、球形核(圆形)、十字形核(菱形)等。如下所示:
import cv2
import numpy as np
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 灰度化
kernel = np.ones((5,5),np.uint8) # 定义核
dilate = cv2.dilate(gray,kernel,iterations = 1) # 膨胀
erode = cv2.erode(gray,kernel,iterations = 1) # 腐蚀
opening = cv2.morphologyEx(gray,cv2.MORPH_OPEN,kernel) # 开操作
closing = cv2.morphologyEx(gray,cv2.MORPH_CLOSE,kernel) # 闭操作
cv2.imshow('origin', img)
cv2.imshow('gray', gray)
cv2.imshow('dilation', dilate)
cv2.imshow('erosion', erode)
cv2.imshow('opening', opening)
cv2.imshow('closing', closing)
cv2.waitKey()
cv2.destroyAllWindows()
3.4 图像金字塔
图像金字塔(Pyramid Image)是通过不同尺寸的图像组合而成的,不同层次上的图像具有不同的分辨率,即高分辨率的图像具有较低分辨率层的一些重要信息。可以提高图像细节的捕捉能力和纹理的鲜度。OpenCV中通过函数buildPyramid()
构建图像金字塔。如下所示:
import cv2
import numpy as np
pyramid = [img.copy()] # 初始化金字塔列表
layer = img.copy() # 初始化当前层图像
while True:
layer = cv2.pyrDown(layer) # 下采样
pyramid.append(layer)
if cv2.countNonZero(layer)==0:
break
layer = img.copy()
while len(pyramid)>0:
cv2.imshow(str(cv2.GetSize(pyramid[-1])), pyramid[-1])
pyramid = pyramid[:-1]
cv2.waitKey()
cv2.destroyAllWindows()
3.5 SIFT关键点检测与描述符
SIFT(Scale-Invariant Feature Transform)是一种基于尺度不变性的特征描述符,适用于各种尺寸和形状的目标检测和特征提取。SIFT算法首先建立一个尺度空间,根据尺度和几何结构对图像进行金字塔分层。然后在每个尺度层的图像中检测关键点,并根据邻近像素确定它们之间的关联性。为了使特征更加稳定,将关键点分为尺度空间的八邻域,每个邻域内的像素都参与描述。因此,一张图片对应于一组描述子。OpenCV中通过函数xfeatures2d.SIFT_create()
创建SIFT对象,调用对象的detectAndCompute()
方法检测并计算关键点及描述符。如下所示:
import cv2
import numpy as np
sift = cv2.xfeatures2d.SIFT_create() # 创建SIFT对象
keypoints,descriptors = sift.detectAndCompute(img,None) # 检测关键点及描述符
img = cv2.drawKeypoints(img,keypoints,None) # 在图像中绘制关键点
cv2.imshow('origin', img)
cv2.waitKey()
cv2.destroyAllWindows()
3.6 FAST算法检测关键点
FAST(Features from Accelerated Segment Test)算法是一种快速检测关键点的方法,速度快且精度高。FAST算法在估计角点位置时没有假设或前提,直接运用灰度差的统计特性,计算灰度差和它的斜率梯度方向直方图。在阈值确定范围内,选择响应最大的几个点作为候选点,进一步处理选出的候选点,判断是否为角点。opencv中通过函数FastFeatureDetector_create()
创建FAST对象,调用对象的detect()
方法检测关键点。如下所示:
import cv2
import numpy as np
fast = cv2.FastFeatureDetector_create() # 创建FAST对象
keypoints = fast.detect(img,None) # 检测关键点
img = cv2.drawKeypoints(img,keypoints,None) # 在图像中绘制关键点
cv2.imshow('origin', img)
cv2.waitKey()
cv2.destroyAllWindows()
3.7 特征匹配
特征匹配(Feature Matching)是根据已知图像的特征点(keypoint)和待测图像的特征点进行匹配,找到对应的点对,找出共轭关系。一般来说,特征匹配有三种方式:暴力匹配、最近邻匹配、KD树匹配。OpenCV中通过函数BFMatcher_create()
创建一个BruteForce Matcher对象,调用对象的knnMatch()
方法进行暴力匹配。如下所示:
import cv2
import numpy as np
bf = cv2.BFMatcher_create() # 创建暴力匹配器
kp1, des1 = sift.detectAndCompute(img1, None) # 计算特征点及描述符
kp2, des2 = sift.detectAndCompute(img2, None)
matches = bf.knnMatch(des1,des2, k=2) # 进行暴力匹配
good = []
for m,n in matches:
if m.distance < 0.7*n.distance: # 根据距离阈值筛选好匹配点对
good.append([m])
src_pts = np.float32([ kp1[m[0].queryIdx].pt for m in good ]).reshape(-1,1,2) # 获取匹配点坐标
dst_pts = np.float32([ kp2[m[0].trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0) # 使用RANSAC求解投影矩阵
matchImg = cv2.warpPerspective(img1, M,(img2.shape[1], img2.shape[0])) # 投影图像
cv2.imshow("Match Result", matchImg)
cv2.waitKey()
cv2.destroyAllWindows()
3.8 Hough变换检测直线
Hough变换(Hough Transformation)是一种基于极坐标的曲线检测方法,包括直线检测、圆环检测、圆孤立点检测等。Hough变换算法主要是依据直线方程,将图像分成不同的直线段,对于每一条直线段,确定一条直线足够多的交点,即可认为该直线与图像中的一个曲线。OpenCV中通过函数houghLines()
实现Hough变换,并绘制出来。如下所示:
import cv2
import numpy as np
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 灰度化
edges = cv2.Canny(gray,50,150,apertureSize = 3) # 边缘检测
lines = cv2.HoughLines(edges,1,np.pi/180,100) # hough变换检测直线
for rho,theta in lines[:,0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)
cv2.imshow("Result", img)
cv2.waitKey()
cv2.destroyAllWindows()
更多推荐
所有评论(0)