本篇补充暑假学opencv遗漏的相关知识点

参考链接:https://www.bilibili.com/video/BV1Fo4y1d7JL?from=search&seid=17628666680714675884&spm_id_from=333.337.0.0

一、图像的基本操作

1.1图像上绘制图形

绘制直线

cv.line(img,start,end,color,thickness)

参数:

img:要绘制直线的图像
Start,end: 直线的起点和终点
color: 线条的颜色
Thickness: 线条宽度

绘制圆形

cv.circle(img,centerpoint, r, color, thickness)

参数:

img:要绘制圆形的图像
Centerpoint, r: 圆心和半径
color: 线条的颜色
Thickness: 线条宽度,为-1时生成闭合图案并填充颜色

绘制矩形

cv.rectangle(img,leftupper,rightdown,color,thickness)

参数:

img:要绘制矩形的图像
Leftupper, rightdown: 矩形的左上角和右下角坐标
color: 线条的颜色
Thickness: 线条宽度

向图像中添加文字

cv.putText(img,text,station, font, fontsize,color,thickness,cv.LINE_AA)

参数:

img: 图像
text:要写入的文本数据
station:文本的放置位置
font:字体
Fontsize :字体大小

demo1:

import cv2
import numpy as npdef cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows()img = cv2.imread('D:\\openCV files\\data\\1\\lena.jpg',cv2.IMREAD_GRAYSCALE)v1 = cv2.Canny(img, 80, 150)  #80:minVal  150:maxVal
v2 = cv2.Canny(img, 50, 100)res = np.hstack((v1, v2))
cv_show(res, 'res')img = cv2.imread('D:\\openCV files\\data\\1\\car.png',cv2.IMREAD_GRAYSCALE)v1 = cv2.Canny(img, 120, 250)  #80:minVal  150:maxVal
v2 = cv2.Canny(img, 50, 100)res = np.hstack((v1, v2))
cv_show(res, 'res')

out1:


二、图像处理

2.1图像缩放

缩放是对图像的大小进行调整,即使图像放大或缩小。

cv2.resize(src,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)

参数:

src : 输入图像

dsize: 绝对尺寸,直接指定调整后图像的大小

fx,fy: 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可

interpolation:插值方法


demo2:

import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']# 读取图片
img1 = cv2.imread(r"D:\openCV_files\data\v2\base\dog.jpeg")# 图像缩放
# 绝对尺寸
rows,cols = img1.shape[:2]
res = cv2.resize(img1,(2*cols,2*rows),interpolation=cv2.INTER_CUBIC)# 相对尺寸
res1 = cv2.resize(img1, None, fx=0.5, fy=0.5)# 3 图像显示
# 3.1 使用opencv显示图像(不推荐)
cv2.imshow("orignal",img1)
cv2.imshow("enlarge",res)
cv2.imshow("shrink",res1)
cv2.waitKey(0)# 使用matplotlib显示图像
fig, axes=plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(res[:,:,::-1])
axes[0].set_title("绝对尺度(放大)")
axes[1].imshow(img1[:,:,::-1])
axes[1].set_title("原图")
axes[2].imshow(res1[:,:,::-1])
axes[2].set_title("相对尺度(缩小)")
plt.show()

out2:


2.2 图像平移

图像平移将图像按照指定方向和距离,移动到相应的位置。

cv.warpAffine(img,M,dsize)

参数:


注意:输出图像的大小,它应该是(宽度,高度)的形式。请记住,width=列数,height=行数。

demo3:

import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']# 读取图像
img1 = cv2.imread(r"D:\openCV_files\data\v2\base\image2.jpg")# 图像平移
rows,cols = img1.shape[:2]
M = np.float32([[1,0,100],[0,1,50]])# 平移矩阵
dst = cv2.warpAffine(img1,M,(cols,rows))# 3. 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("平移后结果")
plt.show()

out3:

2.3 图像旋转

图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持这原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴及中心坐标原点都可能会发生变换,因此需要对图像旋转中的坐标进行相应转换。



在OpenCV中图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果。

cv2.getRotationMatrix2D(center, angle, scale)

参数:

center:旋转中心
angle:旋转角度
scale:缩放比例

返回:

M:旋转矩阵

调用cv.warpAffine完成图像的旋转

demo4:

import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']# 读取图像
img = cv2.imread(r"D:\openCV_files\data\v2\base\image2.jpg")# 图像旋转
rows,cols = img.shape[:2]
# 生成旋转矩阵
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
# 进行旋转变换
dst = cv2.warpAffine(img,M,(cols,rows))# 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("旋转后结果")
plt.show()

out4:

2.4 透射变换

透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。


(除以z原因:除以Z轴转换成二维坐标)

在opencv中,我们要找到四个点,其中任意三个不共线,然后获取变换矩阵T,再进行透射变换。通过函数cv.getPerspectiveTransform找到变换矩阵,将cv.warpPerspective应用于此3x3变换矩阵。

demo5:

import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
# 读取图像
img = cv2.imread(r"D:\openCV_files\data\v2\base\image2.jpg")
# 透射变换
rows,cols = img.shape[:2]
# 创建变换矩阵
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]])T = cv2.getPerspectiveTransform(pts1,pts2)
# 进行变换
dst = cv2.warpPerspective(img,T,(cols,rows))# 3 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("透射后结果")
plt.show()

out5:

2.5 仿射变换

图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合。

那什么是图像的仿射变换,如下图所示,图1中的点1, 2 和 3 与图二中三个点一一映射, 仍然形成三角形, 但形状已经大大改变,通过这样两组三点(感兴趣点)求出仿射变换, 接下来我们就能把仿射变换应用到图像中所有的点中,就完成了图像的仿射变换。

demo6:

import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
# 图像读取
img = cv2.imread(r"D:\openCV_files\data\v2\base\image2.jpg")# 仿射变换
rows,cols = img.shape[:2]
# 创建变换矩阵
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
# 完成仿射变换
dst = cv2.warpAffine(img,M,(cols,rows))# 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img[:,:,::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:,:,::-1])
axes[1].set_title("仿射后结果")
plt.show()

out6:

2.6 霍夫变换

霍夫变换常用来提取图像中的直线和圆等几何形状,如下图所示:








霍夫线检测

在OpenCV中做霍夫线检测是使用的API是:

cv.HoughLines(img, rho, theta, threshold)

参数:

img: 检测的图像,要求是二值化的图像,所以在调用霍夫变换之前首先要进行二值化,或者进行Canny边缘检测

rho、theta: \rhoρ 和\thetaθ的精确度

threshold: 阈值,只有累加器中的值高于该阈值时才被认为是直线。

霍夫线检测的整个流程如下图所示,这是在stackflow上一个关于霍夫线变换的解释:


demo7:

import numpy as np
import random
import cv2 as cv
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
# 1.加载图片,转为二值图
img = cv.imread(r'D:\openCV_files\data\v2\processing\rili.jpg')print(img.shape)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150)# 2.霍夫直线变换
lines = cv.HoughLines(edges, 0.8, np.pi / 180, 150)
# 3.将检测的线绘制在图像上(注意是极坐标噢)
for line in lines:rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 1000 * (-b))y1 = int(y0 + 1000 * (a))x2 = int(x0 - 1000 * (-b))y2 = int(y0 - 1000 * (a))cv.line(img, (x1, y1), (x2, y2), (0, 255, 0))
# 4. 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('霍夫变换线检测')
plt.xticks([]), plt.yticks([])
plt.show()

out7:

(379, 507, 3)


对于其中1000的解释,参考链接

(简单而言,就是保证画出来的线贯穿图形,可以换作300试运行)

霍夫圆检测

原理

圆的表示式是:

其中a和b表示圆心坐标,r表示圆半径,因此标准的霍夫圆检测就是在这三个参数组成的三维空间累加器上进行圆形检测,此时效率就会很低,所以OpenCV中使用霍夫梯度法进行圆形的检测。

霍夫梯度法将霍夫圆检测范围两个阶段,第一阶段检测圆心,第二阶段利用圆心推导出圆半径。

圆心检测的原理:圆心是圆周法线的交汇处,设置一个阈值,在某点的相交的直线的条数大于这个阈值就认为该交汇点为圆心。

圆半径确定原理:圆心到圆周上的距离(半径)是相同的,确定一个阈值,只要相同距离的数量大于该阈值,就认为该距离是该圆心的半径。

原则上霍夫变换可以检测任何形状,但复杂的形状需要的参数就多,霍夫空间的维数就多,因此在程序实现上所需的内存空间以及运行效率上都不利于把标准霍夫变换应用于实际复杂图形的检测中。霍夫梯度法是霍夫变换的改进,它的目的是减小霍夫空间的维度,提高效率。

API

在OpenCV中检测图像中的圆环使用的是API是:、

circles = cv.HoughCircles(image, method, dp, minDist, param1=100, param2=100, minRadius=0,maxRadius=0 )

参数

image:输入图像,应输入灰度图像

method:使用霍夫变换圆检测的算法,它的参数是CV_HOUGH_GRADIENT

dp:霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小一致,dp=2时霍夫空间是输入图像空间的一半,以此类推

minDist为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心

param1:边缘检测时使用Canny算子的高阈值,低阈值是高阈值的一半。

param2:检测圆心和确定半径时所共有的阈值

minRadius和maxRadius为所检测到的圆半径的最小值和最大值

返回:

circles:输出圆向量,包括三个浮点型的元素——圆心横坐标,圆心纵坐标和圆半径

实现

demo8:

import cv2 as cv
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']# 1 读取图像,并转换为灰度图
planets = cv.imread(r"D:\openCV_files\data\v2\processing\star.jpg")
gray_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY)
# 2 进行中值模糊,去噪点
img = cv.medianBlur(gray_img, 7)
# 3 霍夫圆检测
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 200, param1=100, param2=30, minRadius=0, maxRadius=100)
# 4 将检测结果绘制在图像上
for i in circles[0, :]:  # 遍历矩阵每一行的数据# 绘制圆形cv.circle(planets, (int(i[0]), int(i[1])), int(i[2]), (0, 255, 0), 2) # 加int将浮点型转换成整数# 绘制圆心cv.circle(planets, (int(i[0]), int(i[1])), 2, (0, 0, 255), 3)
# 5 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(planets[:,:,::-1]),plt.title('霍夫变换圆检测')
plt.xticks([]), plt.yticks([])
plt.show()

out8:

三、图像特征提取与描述

3.1 Shi-Tomasi角点检测

原理

Shi-Tomasi算法是对Harris角点检测算法的改进,一般会比Harris算法得到更好的角点。Harris 算法的角点响应函数是将矩阵 M 的行列式值与 M 的迹相减,利用差值判断是否为角点。后来Shi 和Tomasi 提出改进的方法是,若矩阵M的两个特征值中较小的一个大于阈值,则认为他是角点,即:



实现

在OpenCV中实现Shi-Tomasi角点检测使用API:

corners = cv2.goodFeaturesToTrack ( image, maxcorners, qualityLevel, minDistance )

参数:

Image: 输入灰度图像
maxCorners : 获取角点数的数目。
qualityLevel:该参数指出最低可接受的角点质量水平,在0-1之间。
minDistance:角点之间最小的欧式距离,避免得到相邻特征点。
返回:

Corners: 搜索到的角点,在这里所有低于质量水平的角点被排除掉,然后把合格的角点按质量排序,然后将质量较好的角点附近(小于最小欧式距离)的角点删掉,最后找到maxCorners个角点返回。

四、视频操作

4.1 视频读取

在OpenCV中我们要获取一个视频,需要创建一个VideoCapture对象,指定你要读取的视频文件:

1.创建读取视频的对象

cap = cv.VideoCapture(filepath)

参数:

filepath: 视频文件路径

2.视频的属性信息

2.1. 获取视频的某些属性,

retval = cap.get(propId)

参数:

propId: 从0到18的数字,每个数字表示视频的属性

常用属性有:


2.2 修改视频的属性信息

cap.set(propId,value)

参数:

proid: 属性的索引,与上面的表格相对应
value: 修改后的属性值

3.判断图像是否读取成功

isornot = cap.isOpened()

若读取成功则返回true,否则返回False

4.获取视频的一帧图像

ret, frame = cap.read()

参数:

ret: 若获取成功返回True,获取失败,返回False
Frame: 获取到的某一帧的图像

5.调用cv.imshow()显示图像,在显示图像时使用cv.waitkey()设置适当的持续时间,如果太低视频会播放的非常快,如果太高就会播放的非常慢,通常情况下我们设置25ms就可以了。

6.最后,调用cap.realease()将视频释放掉

在OpenCV中我们保存视频使用的是VedioWriter对象,在其中指定输出文件的名称,如下所示:

7.创建视频写入的对象

out = cv2.VideoWriter(filename,fourcc, fps, frameSize)

参数:

filename:视频保存的位置
fourcc:指定视频编解码器的4字节代码
fps:帧率
frameSize:帧大小

设置视频的编解码器,如下所示,

retval = cv2.VideoWriter_fourcc( c1, c2, c3, c4 )

参数:

c1,c2,c3,c4: 是视频编解码器的4字节代码,在fourcc.org中找到可用代码列表,与平台紧密相关,常用的有:

在Windows中:DIVX(.avi)
在OS中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。

利用cap.read()获取视频中的每一帧图像,并使用out.write()将某一帧图像写入视频中。
使用cap.release()和out.release()释放资源。

demo9:

import cv2 as cv# 1. 读取视频
cap = cv.VideoCapture('D:\\openCV_files\\data\\1\\test.mp4')# 2. 获取图像的属性(宽和高,),并将其转换为整数
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))# 3. 创建保存视频的对象,设置编码格式,帧率,图像的宽高等
out = cv.VideoWriter('D:\\openCV_files\\data\\1\\outpy.avi',cv.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
while(True):# 4.获取视频中的每一帧图像ret, frame = cap.read()if ret == True:# 5.将每一帧图像写入到输出文件中out.write(frame)else:break# 6.释放资源
cap.release()
out.release()
cv.destroyAllWindows()

4.2 视频追踪

1.meanshift

1.1原理
meanshift算法的原理很简单。假设你有一堆点集,还有一个小的窗口,这个窗口可能是圆形的,现在你可能要移动这个窗口到点集密度最大的区域当中。

如下图:


最开始的窗口是蓝色圆环的区域,命名为C1。蓝色圆环的圆心用一个蓝色的矩形标注,命名为C1_o。

而窗口中所有点的点集构成的质心在蓝色圆形点C1_r处,显然圆环的形心和质心并不重合。所以,移动蓝色的窗口,使得形心与之前得到的质心重合。在新移动后的圆环的区域当中再次寻找圆环当中所包围点集的质心,然后再次移动,通常情况下,形心和质心是不重合的。不断执行上面的移动过程,直到形心和质心大致重合结束。 这样,最后圆形的窗口会落到像素分布最大的地方,也就是图中的绿色圈,命名为C2。

meanshift算法除了应用在视频追踪当中,在聚类,平滑等等各种涉及到数据以及非监督学习的场合当中均有重要应用,是一个应用广泛的算法。

图像是一个矩阵信息,如何在一个视频当中使用meanshift算法来追踪一个运动的物体呢? 大致流程如下:

1.首先在图像上选定一个目标区域

2.计算选定区域的直方图分布,一般是HSV色彩空间的直方图。

3.对下一帧图像b同样计算直方图分布。

4.计算图像b当中与选定区域直方图分布最为相似的区域,使用meanshift算法将选定区域沿着最为相似的部分进行移动,直到找到最相似的区域,便完成了在图像b中的目标追踪。

5.重复3到4的过程,就完成整个视频目标追踪。

通常情况下我们使用直方图反向投影得到的图像和第一帧目标对象的起始位置,当目标对象的移动会反映到直方图反向投影图中,meanshift 算法就把我们的窗口移动到反向投影图像中灰度密度最大的区域了

直方图反向投影的流程是:

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:

1.从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
2.生成临时图像的直方图;
3.用临时图像的直方图和模板图像的直方图对比,对比结果记为c;
4.直方图对比结果c,就是结果图像(0,0)处的像素值;
5.切割输入图像从(0,1)至(10,11)的临时图像,对比直方图,并记录到结果图像;
6.重复1~5步直到输入图像的右下角,就形成了直方图的反向投影

1.2 实现

在OpenCV中实现Meanshift的API是:

cv.meanShift(probImage, window, criteria)

参数:

probImage: ROI区域,即目标的直方图的反向投影

window: 初始搜索窗口,就是定义ROI的rect

criteria: 确定窗口搜索停止的准则,主要有迭代次数达到设置的最大值,窗口中心的漂移值大于某个设定的限值等。

实现Meanshift的主要流程是:

1.读取视频文件:cv.videoCapture()
2.感兴趣区域设置:获取第一帧图像,并设置目标区域,即感兴趣区域
3.计算直方图:计算感兴趣区域的HSV直方图,并进行归一化
4.目标追踪:设置窗口搜索停止条件,直方图反向投影,进行目标追踪,并在目标位置绘制矩形框。

demo10:

import cv2 as cv
import matplotlib.pyplot as plt #matplotlib是RGB# 1.获取图像
cap = cv.VideoCapture(r'D:\openCV_files\data\v2\processing\DOG.wmv')# 2.获取第一帧图像,并指定目标位置
ret,frame = cap.read()# 先找初始位置
cv.rectangle(frame, (0, 197), ( 0+128, 197+141), (0, 255, 0), 3)
cv.imshow('The original position',frame)
cv.waitKey(0)
cv.destroyAllWindows()# 2.1 目标位置(行,高,列,宽)
r,h,c,w = 197,141,0,208  # 一开始狗狗所在的大致位置
track_window = (c,r,w,h)
# 2.2 指定目标的感兴趣区域
roi = frame[r:r+h, c:c+w]# 3. 计算直方图
# 3.1 转换色彩空间(HSV)
hsv_roi =  cv.cvtColor(roi, cv.COLOR_BGR2HSV)
# 3.2 去除低亮度的值
# mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
# 3.3 计算直方图
roi_hist = cv.calcHist([hsv_roi],[0],None,[180],[0,180])# 3.4 归一化
cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)# 4. 目标追踪
# 4.1 设置窗口搜索终止条件:最大迭代次数,窗口中心漂移最小值
term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)while (True):# 4.2 获取每一帧图像ret ,frame = cap.read()if ret == True:# 4.3 计算直方图的反向投影hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)  # roi_hist# 4.4 进行meanshift追踪ret, track_window = cv.meanShift(dst, track_window, term_crit)# 4.5 将追踪的位置绘制在视频上,并进行显示x,y,w,h = track_windowimg2 = cv.rectangle(frame, (x,y), (x+w,y+h), 255,2)cv.imshow('frame',img2)if cv.waitKey(60) & 0xFF == ord('q'):breakelse:break
# 5. 资源释放
cap.release()
cv.destroyAllWindows()

out10:

2 Camshift

大家认真看下上面的结果,有一个问题,就是检测的窗口的大小是固定的,而狗狗由近及远是一个逐渐变小的过程,固定的窗口是不合适的。所以我们需要根据目标的大小和角度来对窗口的大小和角度进行修正。CamShift可以帮我们解决这个问题。

CamShift算法全称是“Continuously Adaptive Mean-Shift”(连续自适应MeanShift算法),是对MeanShift算法的改进算法,可随着跟踪目标的大小变化实时调整搜索窗口的大小,具有较好的跟踪效果。

Camshift算法首先应用meanshift,一旦meanshift收敛,它就会更新窗口的大小,还计算最佳拟合椭圆的方向,从而根据目标的位置和大小更新搜索窗口。如下图所示.

demo11:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt #matplotlib是RGB# 1.获取图像
cap = cv.VideoCapture(r'C:\Users\DENGFY\Desktop\king dog.mp4')# 2.获取第一帧图像,并指定目标位置
ret,frame = cap.read()
print(frame.shape)
# 先找初始位置
r,h,c,w = 45,80,130,80  # 一开始狗狗所在的大致位置
cv.rectangle(frame, (c, r), ( c+w, r+h), (0, 255, 0), 3)
cv.imshow('The original position',frame)
cv.waitKey(0)
cv.destroyAllWindows()# 2.1 目标位置(行,高,列,宽)track_window = (c,r,w,h)
# 2.2 指定目标的感兴趣区域
roi = frame[r:r+h, c:c+w]# 3. 计算直方图
# 3.1 转换色彩空间(HSV)
hsv_roi =  cv.cvtColor(roi, cv.COLOR_BGR2HSV)
# 3.2 去除低亮度的值
# mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
# 3.3 计算直方图
roi_hist = cv.calcHist([hsv_roi],[0],None,[180],[0,180])# 3.4 归一化
cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)# 4. 目标追踪
# 4.1 设置窗口搜索终止条件:最大迭代次数,窗口中心漂移最小值
term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)while (True):# 4.2 获取每一帧图像ret ,frame = cap.read()if ret == True:# 4.3 计算直方图的反向投影hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)  # roi_hist# 进行camshift追踪ret, track_window = cv.CamShift(dst, track_window, term_crit)# 绘制追踪结果pts = cv.boxPoints(ret)pts = np.int0(pts) # 用于在OpenCV问题中将边界框浮点值转换为intimg2 = cv.polylines(frame, [pts], True, 255, 2)cv.imshow('frame',img2)if cv.waitKey(60) & 0xFF == ord('q'):breakelse:break
# 5. 资源释放
cap.release()
cv.destroyAllWindows()

out11:




Meanshift和camshift算法都各有优势,自然也有劣势:

Meanshift算法:简单,迭代次数少,但无法解决目标的遮挡问题并且不能适应运动目标的的形状和大小变化。

camshift算法:可适应运动目标的大小形状的改变,具有较好的跟踪效果,但当背景色和目标颜色接近时,容易使目标的区域变大,最终有可能导致目标跟踪丢失。如上例所示。

基于python的openCV自学笔记(四)——遗漏知识点补充相关推荐

  1. 基于Python的OpenCV+TensorFlow+Keras人脸识别实现

    前言:本节要讲的人脸识别主要是借鉴了 一位研究生前辈的文章 我只是在他的基础上进行了改动,让代码能在现在的TensorFlow2.X 等的环境下运行 先看一下效果图 完整工程及源代码请点击链接下载:人 ...

  2. 4. Python脚本学习实战笔记四 新闻聚合

    4. Python脚本学习实战笔记四 新闻聚合 本篇名言:"人言纷杂,保持自我:工作勤奋,娱乐适度:对待朋友,不玩心术:处理事务,不躁不怒:生活讲究,量入为出:知足常乐,一生幸福!" ...

  3. 基于Python通过OpenCV实现的口罩识别系统理论篇

    基于Python通过OpenCV实现的口罩识别系统理论设计篇 一.项目实现环境 基于Python 3.8.1版本 opencv-python 4.2.0.34版本 需要自己下载OpenCV的库文件,添 ...

  4. cv2 python 获取斑马线_基于python的opencv图像处理实现对斑马线的检测示例

    基本思路 斑马线检测通过opencv图像处理来进行灰度值转换.高斯滤波去噪.阈值处理.腐蚀和膨胀后对图像进行轮廓检测,通过判断车辆和行人的位置,以及他们之间的距离信息,当车速到超过一定阈值时并且与行人 ...

  5. OpenCV学习笔记四-image的一些整体操作

    title: OpenCV学习笔记四-image的一些整体操作 categories: 编程 date: 2019-08-08 12:50:47 tags: OpenCV image的一些操作 sP4 ...

  6. ubuntu16.04安装python.h_ubuntu16.04 下基于 Python 的 OpenCV 的安装

    ubuntu16.04 下基于 Python 的 OpenCV 的安装 这几天一直在学习基于 Python 的 OpenCV , 开发环境是在 Ubuntu16.04 下, 学习的心得就是基于 Pyt ...

  7. 基于python和Opencv将多张图片结合为一张图片的办法

    基于python和Opencv将多张图片结合为一张图片的办法 需要用到的python包 代码本体 这两天写结课论文,需要做一个好看一点的图,要把多张图片结合为同一张图片,本来想用ps,但是懒,干脆用代 ...

  8. matlab 平均梯度,OpenCV 自学笔记33. 计算图像的均值、标准差和平均梯度

    OpenCV 自学笔记33. 计算图像的均值.标准差和平均梯度 均值.标准差和平均梯度是验证图像质量的常用指标.其中: 均值反映了图像的亮度,均值越大说明图像亮度越大,反之越小: 标准差反映了图像像素 ...

  9. 基于Python与OpenCV的纸质票自动统计功能的实现(一)界面编程

    基于Python与OpenCV的纸质票自动统计功能的实现(一)--界面编程 作为一个资深的自动化工程师,界面编程对我来说太熟悉不过了,但是当时用的都是工业界面编程软件,比如WINCC.组态王等等,在这 ...

最新文章

  1. Spotify如何对Apache Storm进行规模扩展
  2. ZendStudio快捷键
  3. Android URL
  4. OSS网页上传和断点续传(终结篇)
  5. 02_pyplot.plot函数、回顾第一个例子、格式字符串、plot函数、线型风格字符、标记(marker)字符、颜色字符
  6. python的6种基本数据类型--集合
  7. [CodeForces1070C]Cloud Computing(2018-2019 ICPC, NEERC, Southern Subregional Contest )
  8. nit计算机应用基础是考试大纲,NIT考试大纲--计算机应用基础.doc
  9. 产品经理和项目经理有哪些区别?
  10. MySQL 数据库性能优化之SQL优化
  11. 双显示器 启动黑屏 黑苹果_黑苹果开机加载黑屏
  12. android界面自动跳转,android实现欢迎界面的自动跳转
  13. Halcon 毛刺检测
  14. 2020年中级数据库系统工程师考试笔记7—关系数据库1
  15. python在两行中分别输入一个字符串s和整数n,定义一个函数将字符串s循环向右移动n位
  16. 【JavaScript打印100,1000,10000 ......内的素数】自动打印素数
  17. 接地气,到底什么才是大数据开发工程师?
  18. Ureport2分栏功能
  19. 北鲲教程|基于 ABAQUS 的 CFRP 加固钢筋混凝土柱承载能力分析
  20. Retrofit+RxJava上传文件和头像

热门文章

  1. 软件工程 软件过程模型概述
  2. 如何学习前端?看这篇就够了
  3. udhcpc不配置默认网关问题解决
  4. 服务器本地系统 网络受限,windows10网络受限怎么解决_win10本地系统网络受限解决方法...
  5. android 4.4版miui v5,基于Android 4.4的MIUI V5公测开始,适配17款非小米机型
  6. 云计算设计模式(六)——命令和查询职责分离(CQRS)模式
  7. 单例模式——一个类只有一个实例
  8. 现货黄金白银上阻力位和压力位的确定和应用
  9. 需求结构化与分析约束影响
  10. 螺旋测微器b类不确定度_华理大物实验答案(误差与有效数字,基本测量) -...