PyTorch深度学习(30)OpenCV图像处理
一、安装OpenCV
3.4.2以上需要专利
pip install opencv-python==3.4.1.15
pip install opencv-contrib-python==3.4.1.15 增加额外拓展包
import cv2
cv2.__version__
环境配置
Anaconda:Anaconda | The World's Most Popular Data Science Platform
Python_whl:https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv
二、图像处理
1、截取部分图像数据
ROI:region of interest
颜色通道提取
b,g,r=cv2.split(img)
img.shape 形状大小 H,W,C
2、图像格式
cv2.IMREAD_COLOR:彩色图像
cv2.IMREAD_GRAYSCALE:灰色图像
cv2.imread('路径+图像名称') type=numpy array h,w,c
opencv读取格式:BGR
cv2.imshow('窗口名称', img)
cv2.waitKey(0) 0表示任意键终止,等待时间为毫秒级
cv2.destroyAllWindows()
cv2.VideoCapture(.mp4文件路径+名称)
ROI range of interest感兴趣区域
img[0:50, 0:200]
颜色通道提取
b,g,r = cv2.split(img)
cv2.merge((b, g, r))
3、边界填充
cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
BORDER_REPLICATE:复制法,复制最边缘像素
BORDER_RELECT:反射法,对感兴趣的图像中的像素在两边进行复制
BORDER_REFLECT_101:反射法,以最边缘像素为轴,对称
BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
BORDER_CONSTANT:常量法,常量值填充
图像叠加
cv2.add(img_1,img_2) [[255,255,.]...]]
重置图像大小
cv2.resize(img, (500, 300))
cv2.resize(img, (0,0), fx=3, fy=1) 指定长宽倍数
cv2.addWeighted(img_1, 0.4, img_2, 0.6, 0) 制定权重融合
4、图像阈值
ret,dst = cv2.threshold(src, thresh, maxval, type)
src:输入图像,只能输入单通道图像(灰度图)
dst:输出图
thresh:阈值
maxval:当像素值超出了阈值(或小于阈值,根据type来决定),所赋予的值
type:二值化操作的类型,类型如下
cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
cv2.THRESH_BINARY_INV 上一个的反转
cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
cv2.THRESH_TOZERO 大于阈值部分不变,否则为0
cv2.THRESH_TOZERO_INV 上一个的反转
5、图像平滑
均值滤波 简单的平均卷积操作
cv2.blur(img, (3,3)) 卷积核大小
方框滤波
cv2.boxFilter(img, -1, (3,3), normalize=True)
高斯滤波
cv2.GaussianBlur(img, (5,5), -1)
中值滤波
cv2.medianBlur(img, 5)
6、形态学
腐蚀操作——边界越来越小,损害
cv2.erode(img, np.ones((5,5),np.uint8),iterations=1)
膨胀操作——损害还原
cv2.dilate(img, np.ones((5,5),np.uint8), iterations=1)
开运算:先腐蚀,后膨胀
kernel = np.ones((5,5)
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
闭运算:先膨胀,后腐蚀
cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
梯度运算=膨胀-腐蚀 得到轮廓
cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
礼帽=原始输入-开运算结果
(如原始为带刺,减去不带刺,得到带刺的图像)
cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
黑帽=闭运算-原始输入
(如膨胀带刺图-原始带刺图,得到原图像的边缘)
cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
7、图像梯度
Sobel算子(Gx Gy 水平 竖直之间的像素差异)
cv2.Sobel(src,ddepth,dx,dy,ksize)
ddepth:图像的深度
dx和dy分别水平和竖值方向
ksize是Sobel算子的大小
cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
cv2.convertScaleAbs(sobelx)
cv2.convertScaleAbs(sobely)
cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
Scharr算子
cv2.Scharr(img,cv2.CV_64F,1,0)
cv2.Scharr(img,cv2.CV_64F,0,1)
Laplacian算子
cv2.Laplacian(img,cv2.CV_64F)
Canny边缘检测
1)使用高斯滤波器,以平滑图像,滤除噪声
2)计算图像中每个像素点的梯度强度和方向
3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应
4)应用双阈值(Double-Threshold)检测来确定真实和潜在的边缘
5)通过抑制孤立的弱边缘最终完成边缘检测
cv2.Canny(img,80,150)
8、图像金字塔
(1)高斯金字塔
向下采样方法(缩小)
cv2.pyrDown(img)
将Gi与高斯内核卷积
将所有偶数行和列去除
向上采样方法(放大)
cv2.pyrUp(img)
将图像在每个方向扩大为原来的两倍,新增的行和列以0填充
使用先前同样的内核(乘以4)与放大后的图像卷积,获得近似值
(2)拉普拉斯金字塔
Li=Gi-PyrUp(PyrDown(Gi))
1、低通滤波 2、缩小尺寸 3、放大尺寸 4、图像相减
down = cv2.pyrDown(img)
down_up = cv2.pyrUp(down)
l_1 = img - down_up
9、图像轮廓
cv2.findContours(img,mode,method)
mode:轮廓检测模式
RETR_EXTERNAL:只检测最外面的轮廓
RETR_LIST:检测所有的轮廓,并将其保存到一条链表当中
RETR_CCOMP:检索所有的轮廓,并将他们组织为两层,顶层是个部分的外部边界,第二层是空洞的边界
RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次
method:轮廓逼近方法
CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,函数只保留他们的终点部分
ret,thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
binary,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
轮廓特征
面积
cv2.contourArea(contours[0])
周长,True表示闭合
cv2.arcLength(contours[0])
轮廓近似
epsilon = 0.1 * cv2.arcLength(contours[0],True)
cv2.approxPolyDP(contours[0],epsilon,True)
哪个轮廓,周长的百分比
边界矩形
x,y,w,h = cv2.boundingRect(contours[0])
外接圆
(x,y),radius = cv2.minEnclosingCircle(contours[0])
模板匹配
res = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED)
TM_SQDIFF:计算平方不同,计算出来的值越小越相关
TM_CCORR:计算相关性,计算出来的值越大越相关
TM_CCOEFF:计算相关系数,计算出来的值越大越相关
TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0越相关
TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1越相关
TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1越相关
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)
10、直方图
cv2.calcHist(images,channels,mask,histSize,ranges)
images:源图像格式为uint8或float32
channels:如果是彩色图像,则输入参数为[0~2] BGR
mask:掩模图像
histSize:bin的数目
ranges:像素值范围为0~256
cv2.calcHist([img],[0],None,[256],[0,256])
直方图均衡化
cv2.equalizeHist(img)
自适应直方图均衡化(分块均衡化)
cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
傅里叶变换:以时间为参照就是时域分析,但在频域中是静止的
高频:变化剧烈的灰度分量,如边界
低频:变化缓慢的灰度分量,如一片大海
滤波
低通滤波器:只保留低频会使得图像模糊
高通滤波器:只保留高频会使得图像细节增强
cv2.dft() cv2.idft() 输入图像先转换成np.float32
cv2.dtf()返回结果是双通道的(实部,虚部)
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
将值映射回0~255
magnitude_spectrum=20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
Magnitude_Specturm图,中心为低频,边缘为高频
11、文档文字识别
OCR Optical Character Recognition
光学字符识别
pip install pytesseract
如果环境变量未找到,在Anaconda的Lib中,找到pytesseract.py tesseract_cmd,将斜杠进行更改
tesseract.image_to_string(图片)
12、图像特征
harris角点检测
角点响应R值
R=detM-a(traceM)^2 detM=x1x2 traceM=x1+x2
cv2.cornerHarris()
img:数据类型为float32的图像
blockSize:角点检测中指定区域的大小
ksize:Sobel求导中使用的窗口大小
k:取值参数为[0.04, 0.06]
cv2.cornerHarris(cv2.cvtColor(cv2.imread(图像名),cv2.COLOR_BGR2GRAY),2,3,0.04)
Scale Invariant Feature Transform(SIFT)
获取关键点,关键点向量化
平移不变性特征转换
图像尺度空间--高斯模糊实现
多分辨率金字塔 DOG Difference of Gaussian 高斯差分金字塔
关键点的精确定位
候选点是DOG空间的局部极值点,这些点是离散的,需要对尺度空间DOG函数进行曲线拟合,计算极值点,实现关键点精确定位
(可以利用泰勒级数进行展开)
消除边界响应
Hessian矩阵,另a=xmain为最大特征值,b=ymin为最小特征值
特征点的主方向--一个特征点产生了多个坐标、尺度、方向
生成特征描述--使用直方图统计邻域内像素的梯度和方向
opencv 3.4.3以上版本无法使用SIFT函数,需要3.4.3版本以下,pip install opencv-python==3.4.1.15 pip install opencv-contrib-python==3.4.1.15
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(灰度图, None)
13、特征匹配(可用于拼图)
(1)Brute-Force蛮力匹配
kp1,des1 = sift.detectAndCompute(img1,None)
kp2,des2 = sift.detectAndCompute(img2,None)
crossCheck表示两个特征点要户像匹配,如A中的第i个特征点与B中的第j个特征点最近,且B中第j个特征点与A中第i个特征点最近
NORM_L2:归一化数组的(欧几里德距离),如果其他特征计算方法需要考虑不同的匹配计算方式
bf = cv2.BFMatcher(crossCheck=True)
(2)1对1匹配
matches = bf.match(des1,des2)
matches = sorted(matches,key=lambda x:x.distance)
两张图像关键点匹配连线
cv2.drawMatches(img1,kp1,img2,kp2,matches[:10],None,flags=2)
(3)k对最佳匹配
bf.knnMatch(des1,des2,k=2)
如果需要更快速完成操作,可以尝试使用cv2.FlannBasedMatcher
14、图像拼接
随机抽样一致算法(Random sample consensus RANSAC)
容忍范围不断迭代
单应性矩阵
视觉变换矩阵RANSAC+单应性矩阵
cv2.findHomography(np.float32(kpsA[i] for(_,i) in matches]), np.float32(kpsB[i] for(_,i) in matches]), cv2.RANSAC, reprojThresh)
15、背景建模
(1)帧差法
场景中目标在运动,对连续两帧图像进行差分运算,不同帧对应的像素点相减,判断灰度差绝对值,当绝对值超过一定阈值时,即为运动目标,从而实现目标的检测功能。
帧差法会引入噪音和空洞问题
(2)混合高斯模型
背景的实际分布应当是多个高斯分布混合在一起,每个高斯模型也可以带有权重
混合高斯模型学习方法
1、首先初始化每个高斯模型矩阵参数
2、取视频中T帧数据图像用来训练高斯混合模型,第一个像素之后来当第一个高斯分布
3、后面的像素值与前面已有的高斯均值进行比较,如果像素点值与其模型均值差3倍方差,则属于该分布,对其进行参数更新
4、如果后一个像素不满足当前高斯分布,用它来创建一个新的高斯分布
例如测试:对新来的像素点值与混合高斯模型中的每一个均值进行比较,如果其差值在2倍方差之间,则认为是背景,否则是前景。前景赋值为255,背景赋值为0。形成一幅前景二值图。
形态学操作
cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
创建混合高斯模型用于背景建模
cv2.createBackgroundSubtractorMOG2()
cv2.morphologyEx(fg.apply(cv2.VideoCapture(视频名)),cv2.MORPH_OPEN,kernel)
16、光流估计
光流:空间运动物体在观测成像平面上的像素运动的瞬时速度,根据各个像素点的速度矢量特征,可以对图像进行动态分析,例如目标跟踪
亮度恒定:同一点随着时间的变化,其亮度不会发生改变
小运动:随着时间的变化不会引起位置的距离变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数
空间一致:一个场景上附近的点投影到图像上也是邻近点,且邻近点速度一直。因为光流基本方程约束只有一个,而要求x,y的方向的速度,需要连立多个方程求解。
Lucas-kanade算法
角点检测所需参数
feature_params = dict(maxCorners=100,qualityLevel=0.3,minDistance=7)
lk_params = dict(winSize=(15,15),maxLevel=2)
角点最大数量(效率),品质因子(特征值越大的越好,筛选),距离
p0 = cv2.goodFeaturesToTrack(gray_image, mask=None, **feature_params)
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.calcOpticalFlowPyrLK(gray_image, frame_gray, p0, None, **lk_params)
参数 prevImage前一帧图像 nextImage 当前帧图像
prevPts 待跟踪的特征点向量 winSize 搜索窗口的大小 maxLevel 最大的金字塔层数
返回 nextPts 输出跟踪特征点向量
status 特征点是否找到,找到状态为1,未找到状态为0
OpenCV读取Caffe模型
cv2.dnn.readNetFromCaffe(txt, model)
cv2.dnn.blobFromImage(cv2.resize(image, (224,224), (224,224), (104,117,123)))
OpenCV追踪算法
csrt:cv2.TrackerCSRT_create
kcf:cv2.TrackerKCF_create
boosting:cv2.TrackerBoosting_create
mil:cv2.TrackerMIL_create
tld:cv2.TrackerTLD_create
medianflow:cv2.TrackerMedianFlow_create
mosse:cv2.TrackerMOSSE_create
多目标追踪
trackers = cv2.MultiTracker_create()