目标识别
目标识别
图像轮廓
图像轮廓:具有相同颜色或强度的连续点的曲线
作用:
可用于图形分析
物体的识别和检测
注意点:
为了检测的准确性,需要先对图像进行二值化或Canny操作
画轮廓时会修改输入的图像
findContours(img,mode,ApproximationMode)
mode:模式
RETR_EXTERNAL=0表示只检测外轮廓
RETR_LIST=1检测的轮廓不建立等级关系
RETR_CCOMP=2每层最多两级
RETR_TREE=3按树形存储轮廓
ApproximationMode
CHAIN_APPROX_NONE:保存所有轮廓上的点
CHAIN_APPROX_SIMPLE只保存角点
import cv2
import numpy as np
img = cv2.imread('C:\\Users\dazhi\Desktop\lunkuo.png')
###转变成单通道
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)
print(contours)
cv2.imshow('img',img)
# cv2.imshow('bin',binary)
cv2.waitKey(0)
绘制轮廓
drawContours(img,contours,contourIdx,color,thickness..)
contourIdx -1表示绘制所有轮廓
color 颜色(0,0,255)
thickness,线宽,-1是全部填充
import cv2
import numpy as np
img = cv2.imread('C:\\Users\dazhi\Desktop\lunkuo.png')
###转变成单通道
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)
# print(contours)
###绘制轮廓
cv2.drawContours(img,contours,-1,(0,0,255),1)
cv2.imshow('img',img)
# cv2.imshow('bin',binary)
cv2.waitKey(0)
轮廓的面积和周长
###轮廓的面积
contourArea(contour)
contour:轮廓
###轮廓的周长
arcLength(curve,closed)
curve:轮廓
closed:闭合还是非闭合
import cv2
import numpy as np
img = cv2.imread('C:\\Users\dazhi\Desktop\lunkuo.png')
###转变成单通道
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)
# print(contours)
###绘制轮廓
cv2.drawContours(img,contours,-1,(0,0,255),1)
###计算面积
area = cv2.contourArea(contours[0])
print("area=%d"%(area))
###计算周长
len = cv2.arcLength(contours[0],True)
print("len=%d"%(len))
cv2.imshow('img',img)
# cv2.imshow('bin',binary)
cv2.waitKey(0)
多边形逼近与凸包
###多边形逼近
approxPolyDP(curve,epsilon,closed)
curve:曲线,轮廓
epsilon:精度
closed:是否闭合
###凸包
convexHull(points,clockwise)
points:点,轮廓
clockwise:顺时针绘制
import cv2
import numpy as np
def darwShape(src,points):
i = 0
###画线
while i <len(points):
if(i == len(points) -1):
x,y = points[i][0]
x1,y1 = points[0][0]
cv2.line(src,(x,y),(x1,y1),(0,0,255),3)
else:
x,y = points[i][0]
x1,y1 = points[i+1][0]
cv2.line(src,(x,y),(x1,y1),(0,0,255),3)
i=i+1
img = cv2.imread('C:\\Users\dazhi\Desktop\-tubao.png')
###转变成单通道
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)
# print(contours)
###绘制轮廓
cv2.drawContours(img,contours,0,(0,255,0),1)
###多边形逼近
e = 20 ###e值变小线会变得平滑
approx = cv2.approxPolyDP(contours[0],e,True)
darwShape(img,approx)
###凸包
hull = cv2.convexHull(contours[0])
darwShape(img,hull)
cv2.imshow('img',img)
cv2.waitKey(0)
外接矩阵
最小外接矩形
minAreaRect(points)
points:坐标点。轮廓
最大外接矩形
boundingRect(array)
array:轮廓
import cv2
import numpy as np
def darwShape(src,points):
i = 0
###画线
while i <len(points):
if(i == len(points) -1):
x,y = points[i][0]
x1,y1 = points[0][0]
cv2.line(src,(x,y),(x1,y1),(0,0,255),3)
else:
x,y = points[i][0]
x1,y1 = points[i+1][0]
cv2.line(src,(x,y),(x1,y1),(0,0,255),3)
i=i+1
img = cv2.imread('C:\\Users\dazhi\Desktop\Hello.png')
###转变成单通道
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)
# print(contours)
###最小外接矩形
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])
###(x+w,y+h)在起始点的基础上加上
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
车辆识别
涉及到的内容
窗口的展示
图像/视频的加载
基本图形的绘制
车辆识别
基本图像运算与处理
形态学
轮廓查找
###视频加载
import cv2
import numpy as np
cap = cv2.VideoCapture('C://Users/dazhi/Desktop/video.mp4')
###通过while循环将视频一幅一幅的读取出来(读取每一帧)
while True:
ret,frame = cap.read()
if(ret == True):
cv2.imshow('video',frame)
key = cv2.waitKey(1)
###27=左上角esc
if(key == 27):
break
cap.release()
cv2.destroyAllWindows()
###去除背景
createBackgroundSubtractorMOG()
history=200 缓冲5帧
import cv2
import numpy as np
cap = cv2.VideoCapture('C://Users/dazhi/Desktop/video.mp4')
bgsubmog = cv2.createBackgroundSubtractorMOG2()
# test = cv2.createBackgroundSubtractorMOG2()
# bgsubmog = cv2.bgsegm.createBackgroundSubtractorGMG()
###通过while循环将视频一幅一幅的读取出来(读取每一帧)
while True:
ret,frame = cap.read()
if(ret == True):
###灰度化
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
###去噪(高斯)
blur = cv2.GaussianBlur(frame,(3,3),5)
###去背景
mask = bgsubmog.apply(blur)
###做对比 没有经过去噪的
# t1 = test.apply(frame)
# cv2.imshow('t1',t1)
cv2.imshow('video',mask)
key = cv2.waitKey(1)
###27=左上角esc
if(key == 27):
break
cap.release()
cv2.destroyAllWindows()
###形态处理
import cv2
import numpy as np
cap = cv2.VideoCapture('C://Users/dazhi/Desktop/video.mp4')
bgsubmog = cv2.createBackgroundSubtractorMOG2()
# test = cv2.createBackgroundSubtractorMOG2()
# bgsubmog = cv2.bgsegm.createBackgroundSubtractorGMG()
###通过while循环将视频一幅一幅的读取出来(读取每一帧)
###形态学kernel
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,frame = cap.read()
if(ret == True):
###灰度化
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
###去噪(高斯)
blur = cv2.GaussianBlur(frame,(3,3),5)
###去背景
mask = bgsubmog.apply(blur)
###做对比 没有经过去噪的
# t1 = test.apply(frame)
# cv2.imshow('t1',t1)
##腐蚀(去掉一些小的斑块)
erode = cv2.erode(mask,kernel)
# cv2.imshow('erode',erode)
###膨胀(还原放大)
dilate = cv2.dilate(erode,kernel,iterations=3)
# cv2.imshow('erode',dilate)
###闭操作 去掉物体内部的小块
close = cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close = cv2.morphologyEx(close,cv2.MORPH_CLOSE,kernel)
# cv2.imshow('erode',close)
cnts,h = cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for (i,c) in enumerate(cnts):
(x,y,w,h) = cv2.boundingRect(c)
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow('video',frame)
key = cv2.waitKey(1)
###27=左上角esc
if(key == 27):
break
cap.release()
cv2.destroyAllWindows()
###车辆统计
import cv2
import numpy as np
###检测线的高度 (可以在灰度那里打印出(720, 1280, 3))
line_high = 600
###存放有效车辆的数组
cars = []
###统计车的数量
carno = 0
###计算中心点
def center(x,y,w,h):
x1 = int(w/2)
y1 = int(h/2)
cx = x+x1
cy = y+y1
return cx,cy
cap = cv2.VideoCapture('C://Users/dazhi/Desktop/video.mp4')
bgsubmog = cv2.createBackgroundSubtractorMOG2()
# test = cv2.createBackgroundSubtractorMOG2()
# bgsubmog = cv2.bgsegm.createBackgroundSubtractorGMG()
###通过while循环将视频一幅一幅的读取出来(读取每一帧)
###形态学kernel
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,frame = cap.read()
if(ret == True):
###灰度化
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
###查看视频的数据
# print(frame.shape)
# exit()
###去噪(高斯)
blur = cv2.GaussianBlur(frame,(3,3),5)
###去背景
mask = bgsubmog.apply(blur)
###做对比 没有经过去噪的
# t1 = test.apply(frame)
# cv2.imshow('t1',t1)
##腐蚀(去掉一些小的斑块)
erode = cv2.erode(mask,kernel)
# cv2.imshow('erode',erode)
###膨胀(还原放大)
dilate = cv2.dilate(erode,kernel,iterations=3)
# cv2.imshow('erode',dilate)
###闭操作 去掉物体内部的小块
close = cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close = cv2.morphologyEx(close,cv2.MORPH_CLOSE,kernel)
# cv2.imshow('erode',close)
cnts,h = cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
###画一条线
cv2.line(frame,(10,line_high),(1200,line_high),(255,255,0),3)
for (i,c) in enumerate(cnts):
(x,y,w,h) = cv2.boundingRect(c)
###过滤(对车辆的宽高进行判断,已验证是否是有效的车辆)
isValid = (w >= 90) and (h >= 90)
if(not isValid):
continue
###到这里是有效的车
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2) ##绘制车
cpoint = center(x,y,w,h)
cars.append(cpoint)
for(x,y) in cars:
##要有一条线
##有范围 6
##从数组中减去
if ((y > line_high -6) and (y < line_high + 6)):
carno += 1
cars.remove((x,y))
print(carno)
cv2.imshow('video',frame)
key = cv2.waitKey(1)
###27=左上角esc
if(key == 27):
break
cap.release()
cv2.destroyAllWindows()
###显示车辆统计信息
import cv2
import numpy as np
###检测线的高度 (可以在灰度那里打印出(720, 1280, 3))
line_high = 550
###存放有效车辆的数组
cars = []
###统计车的数量
carno = 0
###计算中心点
def center(x,y,w,h):
x1 = int(w/2)
y1 = int(h/2)
cx = x+x1
cy = y+y1
return cx,cy
cap = cv2.VideoCapture('C://Users/dazhi/Desktop/video.mp4')
bgsubmog = cv2.createBackgroundSubtractorMOG2()
# bgsubmog = cv2.bgsegm.createBackgroundSubtractorGMG()
###通过while循环将视频一幅一幅的读取出来(读取每一帧)
###形态学kernel
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,frame = cap.read()
if(ret == True):
###灰度化
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
###去噪(高斯)
blur = cv2.GaussianBlur(frame,(3,3),5)
###去背景
mask = bgsubmog.apply(blur)
##腐蚀(去掉一些小的斑块)
erode = cv2.erode(mask,kernel)
# cv2.imshow('erode',erode)
###膨胀(还原放大)
dilate = cv2.dilate(erode,kernel,iterations=3)
# cv2.imshow('erode',dilate)
###闭操作 去掉物体内部的小块
close = cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
close = cv2.morphologyEx(close,cv2.MORPH_CLOSE,kernel)
# cv2.imshow('erode',close)
cnts,h = cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
###画一条线
cv2.line(frame,(10,line_high),(1200,line_high),(255,255,0),3)
for (i,c) in enumerate(cnts):
(x,y,w,h) = cv2.boundingRect(c)
###过滤(对车辆的宽高进行判断,已验证是否是有效的车辆)
isValid = (w >= 90) and (h >= 90)
if(not isValid):
continue
###到这里是有效的车
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2) ##绘制车
cpoint = center(x,y,w,h)
cars.append(cpoint)
for(x,y) in cars:
##要有一条线
##有范围 6
##从数组中减去
if ((y > line_high - 7) and (y < line_high + 7)):
carno += 1
cars.remove((x,y))
print(carno)
###将信息打印出来
cv2.putText(frame,"Cars count:"+str(carno),(500,60),cv2.FONT_HERSHEY_SIMPLEX,2,(255,0,0),5)
cv2.imshow('video',frame)
key = cv2.waitKey(1)
###27=左上角esc
if(key == 27):
break
cap.release()
cv2.destroyAllWindows()