【OpenCV学习】(九)⽬标识别之车辆检测与计数
【OpenCV学习】(九)⽬标识别之车辆检测及计数
背景
本篇将具体介绍⼀个实际应⽤项⽬——车辆检测及计数,在交通安全中是很重要的⼀项计数;当然,本次完全采⽤OpenCV进⾏实现,和⽬前落地的采⽤深度学习的算法并不相同,但原理是⼀致的;本篇将从基础开始介绍,⼀步步完成车辆检测计数的项⽬;
⼀、图像轮廓
本质:具有相同颜⾊或强度的连续点的曲线;
作⽤:
1、可⽤于图形分析;
2、应⽤于物体的识别与检测;
注意点:
1、为了检测的准确性,需要先对图像进⾏⼆值化或Canny操作;
2、画轮廓的时候回修改输⼊的图像,需要先深拷贝原图;
轮廓查的函数原型:
findContours(img,mode,ApproximationMode…)
mode
RETR_EXTERNAL=0,表⽰只检测外轮廓;
RETR_LIST=1,检测的轮廓不建⽴等级关系;(常⽤)
RETR_CCOMP=2,每层最多两级;
RETR_TREE=3,按树形结构存储轮廓,从右到左,从⼤到⼩;(常⽤)
ApproximationMode
CHAIN_APPROX_BOBE:保存轮廓上所有的点;
CHAIN_APPROX_SIMPLE:只保存轮廓的⾓点;
代码实战:
img = cv2.imread('./contours1.jpeg')
# 转变成单通道
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ⼆值化
ret, binary = cv2.threshold(gray,150,255, cv2.THRESH_BINARY)
# 轮廓查
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours输出结果:
(array([[[0,0]],
[[0,435]],
[[345,435]],
[[345,0]]], dtype=int32),)
可以看出,我们最外层轮廓,出了⼀个矩形轮廓的四个点;
当然,我们不需要通过画形状来绘制轮廓,可以通过⼀个内置函数来绘制轮廓;
绘制轮廓函数原型:
drawContours(img,contours,contoursIdx,color,thickness,…)contours:表⽰保存轮廓的数组;
contoursIdx:表⽰绘制第⼏个轮廓,-1表⽰所有轮廓;
代码案例:
img = cv2.imread('./contours1.jpeg')
img2 = py()
# 转变成单通道
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ⼆值化
ret, binary = cv2.threshold(gray,150,255, cv2.THRESH_BINARY)
# 轮廓查
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours,-1,(0,0,255),1)
cv2.drawContours(img2, contours,-1,(0,0,255),-1)
cv2.imshow('org', img)
cv2.imshow('org2', img2)
cv2.waitKey(0)
如上图所⽰,左图是线宽设置为1,右图为线宽设置为-1,也就是填充的效果;
当然,OpenCV还提供了计算轮廓周长和⾯积的⽅法;
轮廓⾯积函数原型:
contourArea(contour)
轮廓周长函数原型:
arcLength(curve,closed)
curve:表⽰轮廓;
closed:是否是闭合的轮廓;
上述两个函数⽐较简单,在这就不做代码演⽰了;
⼆、多边形逼近与凸包
多边形逼近函数原型:
approxPolyDP(curve,epsilon,closed)
epslion:精度;
凸包的函数原型:
convexHull(points,clockwise,…)
points:轮廓;rectangle函数opencv
clockwise:绘制⽅向,顺时针或逆时针;(不重要)
⾸先我们看⼀下基于轮廓查输出的轮廓形状:
可以看出轮廓点⼗分密集,接下来看⼀下基于多变形逼近和凸包的效果:代码案例:
img = cv2.imread('./hand.png')
img2 = py()
# 转变成单通道
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ⼆值化
ret, binary = cv2.threshold(gray,150,255, cv2.THRESH_BINARY)
# 轮廓查
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# cv2.drawContours(img, contours, -1, (0, 0, 255), 1)
e =20
approx = cv2.approxPolyDP(contours[0], e,True)# 多边形逼近
approx =(approx,)
cv2.drawContours(img, approx,0,(0,0,255),3)
hull = vexHull(contours[0])
hull =(hull,)
cv2.drawContours(img2, hull,0,(0,0,255),3)# 凸包
cv2.imshow('org', img)
cv2.imshow('org2', img2)
cv2.waitKey(0)
这⾥需要注意⼀点,绘制轮廓的函数对于轮廓的传⼊需要为元组,需要将得到的数组放到⼀个元组中!当然,多边形逼近这⾥设置的精度为20,所以⽐较粗糙,设置⼩⼀些可以达到更好的效果;
三、外接矩形
外接矩阵分为最⼤外接矩阵和最⼩外接矩阵,如下图所⽰:
最⼩外接矩阵还有⼀个功能,就是计算旋转⾓度,从上图的绿框应该可以很明显看出;
最⼩外接矩阵函数原型:
minAreaRect(points)
返回值:起始点(x,y)、宽⾼(w,h)、⾓度(angle)
最⼤外接矩形函数原型:
boundingRect(array)
返回值:起始点(x,y)、宽⾼(w,h)
代码案例:
img = cv2.imread('./hello.jpeg')
img2 = py()
# 转变成单通道
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ⼆值化
ret, binary = cv2.threshold(gray,150,255, cv2.THRESH_BINARY)
# 轮廓查
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 获取最⼩外接矩形
r = cv2.minAreaRect(contours[1])
box = cv2.boxPoints(r)# 提取其中的点
box = np.int0(box)# 将浮点型转换为整型
cv2.drawContours(img,(box,),0,(0,0,255),2)
# 获取最⼤外接矩形
x, y, w, h = cv2.boundingRect(contours[1])
cv2.imshow('org', img)
cv2.imshow('org2', img2)
cv2.waitKey(0)
四、车辆统计实战
涉及的知识点:
窗⼝展⽰
图像、视频的加载
基本图形的绘制
基本图像运算与处理
形态学
轮廓查

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。