python3.6.3+opencv3.3.0学习笔记九--动态物体检测

思路

  1. 设置视频来源
  2. 设置各种参数,包括储存,窗口,过程参数等
  3. 捕获第一帧图像
  4. 进入循环
  5. 将第一帧图像赋给过程frame
  6. 对图像进行灰度处理
  7. 对图像执行高斯模糊,使其尽可能减小灰度的变化梯度
  8. 将两幅灰度图像相减,从而将背景删除
  9. 给出阈值,将相减后的图像转化为黑白图
  10. 将多余的零星变化白点置为黑色
  11. 检测白色色块的大小和边缘
  12. 按照阈值检测白色色块的边缘
  13. 绘出动态变化物体的边缘矩形
  14. 显示
  15. 储存到本地
  16. 按下esc退出循环
  17. 清零

注意点

  1. 在储存时彩色图像和灰度黑白图像的制式不同,需要分别指出各自的制式,否则无法保存到本地。高斯模糊的阈值、相减时的阈值、色块大小的阈值、灰度变化的阈值需要不断调节,最终结果受到光影、运动、物体明暗程度、场景环境的诸多影像,和视频源也有极大的关系
  2. 循环较长,各种逻辑关系必须非常清楚
  3. 网上例程很多,但基本上不可能拿来即用,本例程基本上算是最新的
  4. 后附各种图像和动画,以供参考
  5. 本例程采用手机的摄像头作为无线IP视频源,可能会有些卡滞,640x480的质量差强人意,转化为2M大小的GIF更是打了折扣,但程序毫无疑问是畅通的。
  6. 将手机作为无线视频源也是一个技术点,在后续的学习笔记中再行记录吧。


import cv2  
import numpy as np  

#设置窗口大小
cv2.namedWindow("Video",0)
cv2.resizeWindow("Video", 640, 480)
cv2.namedWindow("Video_gray",0)
cv2.resizeWindow("Video_gray", 640, 480)
cv2.namedWindow("Video_wb",0)
cv2.resizeWindow("Video_wb", 640, 480)

#打开USB摄像头,本例程采用手机作为无线IP摄像头,可能会有些卡
video="http://aikes:[email protected]:8080//video"#在不同的路由连接下会有不同的IP地址
camera = cv2.VideoCapture(video)
frame_now=camera.read()
#这是直接采用笔记本自带摄像头的定义
'''camera = cv2.VideoCapture(0)
frame_now=camera.read()'''

frame_old=None

#这是处理本地的视频
#camera= cv2.VideoCapture("c://girl.avi")  

#fps,size码率及尺寸  
#fps = camera.get(cv2.CV_CAP_PROP_FPS)
#size = (int(camera.get(cv2.CV_CAP_PROP_FRAME_WIDTH)), int(camera.get(cv2.CV_CAP_PROP_FRAME_HEIGHT))) 
 
fps=10
size=640,480

#指定写视频的格式
out_now = cv2.VideoWriter('c://object_detect_now.avi', cv2.VideoWriter_fourcc(*'DIVX'), fps, size)  #彩色视频
out_gray = cv2.VideoWriter('c://object_detect_gray.avi', cv2.VideoWriter_fourcc(*'DIVX'), fps, size,0)	#灰度视频
out_wb = cv2.VideoWriter('c://object_detect_wb.avi', cv2.VideoWriter_fourcc(*'DIVX'), fps, size,0)	#黑白视频

while (1):  
    ret,frame_now = camera.read()	#返回frame,维持循环的重要步骤
    #print (frame_now)
    
    if not ret:  
        break
        
    frame_gray=cv2.cvtColor(frame_now,cv2.COLOR_BGR2GRAY)  #转化为灰度图像
    frame_gray=cv2.GaussianBlur(frame_gray,(15,15),0)  #高斯模糊
    
    if frame_old is None:  
        frame_old=frame_gray	#赋给过渡帧
        continue  
    
    #获得与背景的差值,背景很重要,最好是除了移动的主体之外,什么都不懂,且背景中没有移动的主体
    frame_delta = cv2.absdiff(frame_old,frame_gray)  #相减
    
    #获得黑白的图片
    thresh = cv2.threshold(frame_delta, 25, 255, cv2.THRESH_BINARY)[1]  
    thresh = cv2.dilate(thresh, None, iterations=2)
    
    #获得移动物体的轮廓
    cnts, hierarchy, rr = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  
    #print cnts
    
    #画出轮廓
    #cv2.drawContours(frame_now, hierarchy, -1, (0, 255, 0), 3)
 
    for c in hierarchy:
    
        # if the contour is too small, ignore it
        # 轮廓面积
        #area = cv2.contourArea(c)
        #print area
        # 周长,或者说,弧长;第二个参数的True表示该轮廓是否封闭
        #perimeter = cv2.arcLength(c,True)
        #sprint  perimeter
        
        if cv2.contourArea(c) <= 5000:	#阈值
            continue
    
        # compute the bounding box for the contour, draw it on the frame,
        # and update the text
        
        # 计算轮廓的边界框,在当前帧中画出该框
        x,y,w,h = cv2.boundingRect(c)        
            
        #x,y,w,h=cv2.boundingRect(thresh)  
        frame_now=cv2.rectangle(frame_now,(x,y),(x+w,y+h),(0,0,255),3)  

        # 计算的最小轮廓
        #rect = cv2.minAreaRect(c)
        #print rect
    
    print('save video....\n')
    out_now.write(frame_now)	#储存图像
    out_gray.write(thresh)
    out_wb.write(frame_delta)
        
    cv2.imshow("Video", frame_now)  #显示图像
    cv2.imshow("Video_gray", thresh)  
    cv2.imshow("Video_wb", frame_delta)  
         
    if cv2.waitKey(1) == ord("q") or cv2.waitKey(1) == 27:	#按下‘q’或者esc退出
        print('exit!\n')
        break  

#清零
out_now.release()
out_gray.release()
out_wb.release()
camera.release()
cv2.destroyAllWindows()  

python3.6.3+opencv3.3.0学习笔记九--动态物体检测_第1张图片


python3.6.3+opencv3.3.0学习笔记九--动态物体检测_第2张图片


python3.6.3+opencv3.3.0学习笔记九--动态物体检测_第3张图片


python3.6.3+opencv3.3.0学习笔记九--动态物体检测_第4张图片




python3.6.3+opencv3.3.0学习笔记九--动态物体检测_第5张图片


python3.6.3+opencv3.3.0学习笔记九--动态物体检测_第6张图片



你可能感兴趣的:(python,opencv,机器视觉算法与应用)