python opencv 检测移动物体并截图保存实例


Posted in Python onMarch 10, 2020

最近在老家找工作,无奈老家工作真心太少,也没什么面试机会,不过之前面试一家公司,提了一个有意思的需求,检测河面没有有什么船只之类的物体,我当时第一反应是用opencv做识别,不过回家想想,河面相对的东西比较少,画面比较单一,只需要检测有没有移动的物体不就简单很多嘛,如果做街道垃圾检测的话可能就很复杂了,毕竟街道上行人,车辆,动物,很多干扰物,于是就花了一个小时写了一个小的demo,只需在程序同级目录创建一个img目录就可以了

# -*-coding:utf-8 -*- 
__author__ = "ZJL"
 
import cv2
import time
 
 
# 保存截图
save_path = './img/'
 
# 定义摄像头对象,其参数0表示第一个摄像头
camera = cv2.VideoCapture(0)
 
# 判断视频是否打开
if (camera.isOpened()):
 print('Open')
else:
 print('摄像头未打开')
 
# 测试用,查看视频size
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
  int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('size:'+repr(size))
 
# 帧率
fps = 5
# 总是取前一帧做为背景(不用考虑环境影响)
pre_frame = None
 
while(1):
 start = time.time()
 # 读取视频流
 ret, frame = camera.read()
 # 转灰度图
 gray_lwpCV = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
 if not ret:
  break
 end = time.time()
 
 cv2.imshow("capture", frame)
 
 # 运动检测部分
 seconds = end - start
 if seconds < 1.0 / fps:
  time.sleep(1.0 / fps - seconds)
 gray_lwpCV = cv2.resize(gray_lwpCV, (500, 500))
 # 用高斯滤波进行模糊处理
 gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)
 
 # 如果没有背景图像就将当前帧当作背景图片
 if pre_frame is None:
  pre_frame = gray_lwpCV
 else:
  # absdiff把两幅图的差的绝对值输出到另一幅图上面来
  img_delta = cv2.absdiff(pre_frame, gray_lwpCV)
  #threshold阈值函数(原图像应该是灰度图,对像素值进行分类的阈值,当像素值高于(有时是小于)阈值时应该被赋予的新的像素值,阈值方法)
  thresh = cv2.threshold(img_delta, 25, 255, cv2.THRESH_BINARY)[1]
  # 膨胀图像
  thresh = cv2.dilate(thresh, None, iterations=2)
  # findContours检测物体轮廓(寻找轮廓的图像,轮廓的检索模式,轮廓的近似办法)
  image, contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  for c in contours:
   # 设置敏感度
   # contourArea计算轮廓面积
   if cv2.contourArea(c) < 1000:
    continue
   else:
    print("出现目标物,请求核实")
    # 保存图像
    cv2.imwrite(save_path + str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))) + '.jpg', frame)
    break
  pre_frame = gray_lwpCV
 
  if cv2.waitKey(1) & 0xFF == ord('q'):
   break
 
 
# release()释放摄像头
camera.release()
#destroyAllWindows()关闭所有图像窗口
cv2.destroyAllWindows()

想出现一个矩形框跟随移动物于是进行了改造,结果发现效果不是很理想,不能很好的框住移动目标,要么只框一部分,要么出现在移动目标附近,尴尬

# -*-coding:utf-8 -*- 
__author__ = "ZJL"
 
import cv2
import time
 
 
# 保存截图
save_path = './img/'
 
# 定义摄像头对象,其参数0表示第一个摄像头
camera = cv2.VideoCapture(0)
 
# 判断视频是否打开
if (camera.isOpened()):
 print('Open')
else:
 print('摄像头未打开')
 
# 测试用,查看视频size
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),
  int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('size:'+repr(size))
 
# 帧率
fps = 5
# 总是取前一帧做为背景(不用考虑环境影响)
pre_frame = None
 
while(1):
 start = time.time()
 # 读取视频流
 ret, frame = camera.read()
 # 转灰度图
 gray_lwpCV = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
 if not ret:
  break
 end = time.time()
 
 # 显示图像
 # cv2.imshow("capture", frame)
 
 # 运动检测部分
 seconds = end - start
 if seconds < 1.0 / fps:
  time.sleep(1.0 / fps - seconds)
 gray_lwpCV = cv2.resize(gray_lwpCV, (500, 500))
 # 用高斯滤波进行模糊处理
 gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)
 
 # 如果没有背景图像就将当前帧当作背景图片
 if pre_frame is None:
  pre_frame = gray_lwpCV
 else:
  # absdiff把两幅图的差的绝对值输出到另一幅图上面来
  img_delta = cv2.absdiff(pre_frame, gray_lwpCV)
  #threshold阈值函数(原图像应该是灰度图,对像素值进行分类的阈值,当像素值高于(有时是小于)阈值时应该被赋予的新的像素值,阈值方法)
  thresh = cv2.threshold(img_delta, 25, 255, cv2.THRESH_BINARY)[1]
  # 膨胀图像
  thresh = cv2.dilate(thresh, None, iterations=2)
  # findContours检测物体轮廓(寻找轮廓的图像,轮廓的检索模式,轮廓的近似办法)
  image, contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  for c in contours:
   # 设置敏感度
   # contourArea计算轮廓面积
   if cv2.contourArea(c) < 1000:
    continue
   else:
    # 画出矩形框架,返回值x,y是矩阵左上点的坐标,w,h是矩阵的宽和高
    (x, y, w, h) = cv2.boundingRect(c)
    # rectangle(原图,(x,y)是矩阵的左上点坐标,(x+w,y+h)是矩阵的右下点坐标,(0,255,0)是画线对应的rgb颜色,2是所画的线的宽度)
    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
    # putText 图片中加入文字
    cv2.putText(frame, "now time: {}".format(str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))) ), (10, 20),
       cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
    print("出现目标物,请求核实")
    # 保存图像
    cv2.imwrite(save_path + str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))) + '.jpg', frame)
    break
  pre_frame = gray_lwpCV
 
  # 显示图像
  cv2.imshow("capture", frame)
  # cv2.imshow("Thresh", thresh)
  # 进行阀值化来显示图片中像素强度值有显著变化的区域的画面
  cv2.imshow("Frame Delta", img_delta)
 
 if cv2.waitKey(1) & 0xFF == ord('q'):
  break
 
 
# release()释放摄像头
camera.release()
#destroyAllWindows()关闭所有图像窗口
cv2.destroyAllWindows()

补充知识:基于python使用opencv监测视频指定区域是否有物体移动

缘由:车停车位,早上看到右后轮有很明显的干了的水渍,前一天下雨,车身其他位置没有如此显眼的水渍,不可能是前天雨水的水渍,仔细一看,从油箱盖一直往下,很明显,有某个X德的人故意尿在车上的,找物业拿到视频监控文件,自己看太费时间,于是。。。

思路:读取视频的关键帧,对比指定区域的数据,如果变化较大(排除环境光线变化),则有物体移动,截取当前帧保存备用。

行动:对于python处理视频不了解,找来找去,找到opencv,符合需求。

python opencv 检测移动物体并截图保存实例

原来是个熊孩子小学生,上楼就到家了,这爹妈教也没管教说不能随地大小便么。

代码如下:

#!/usr/bin/env python
# coding: utf-8
# @author: sSWans
# @file: main.py
# @time: 2018/1/11 15:54
 
import os
import random
from _datetime import datetime
 
import cv2
 
path = 'F:\\111'
 
 
# 遍历目录下的视频文件
def get_files(fpath):
 files_list = []
 for i in os.listdir(fpath):
  files_list.append(os.path.join(fpath, i))
 return files_list
 
 
# 视频处理
def process(file, fname):
 # camera = cv2.VideoCapture(0) # 参数0表示第一个摄像头
 camera = cv2.VideoCapture(file)
 # 参数设置,监测矩形区域
 rectangleX = 880 # 矩形最左点x坐标
 rectangleXCols = 0 # 矩形x轴上的长度
 rectangleY = 650 # 矩形最上点y坐标
 rectangleYCols = 100 # 矩形y轴上的长度
 KeyFrame = 17 # 取关键帧的间隔数,根据视频的帧率设置,我的视频是16FPS
 counter = 1 # 取帧计数器
 pre_frame = None # 总是取视频流前一帧做为背景相对下一帧进行比较
 
 # 判断视频是否打开
 if not camera.isOpened():
  print('视频文件打开失败!')
 
 width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))
 height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
 print('视频尺寸(高,宽):', height, width)
 
 if rectangleXCols == 0:
  rectangleXCols = width - rectangleX
 if rectangleYCols == 0:
  rectangleYCols = height - rectangleY
 start_time = datetime.now()
 print('{} 开始处理文件: {}'.format(start_time.strftime('%H:%M:%S'), fname))
 while True:
  grabbed, frame_lwpCV = camera.read() # 读取视频流
  if grabbed:
   if counter % KeyFrame == 0:
    # if not grabbed:
    #  print('{} 完成处理文件: {} 。。。 '.format(datetime.now().strftime('%H:%M:%S'),fname))
    #  break
    gray_lwpCV = cv2.cvtColor(frame_lwpCV, cv2.COLOR_BGR2GRAY) # 转灰度图
    gray_lwpCV = gray_lwpCV[rectangleY:rectangleY + rectangleYCols, rectangleX:rectangleX + rectangleXCols]
    lwpCV_box = cv2.rectangle(frame_lwpCV, (rectangleX, rectangleY),
           (rectangleX + rectangleXCols, rectangleY + rectangleYCols), (0, 255, 0),
           2) # 用绿色矩形框显示监测区域
    # cv2.imshow('lwpCVWindow', frame_lwpCV) # 显示视频播放窗口,开启消耗时间大概是3倍
    gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)
    if pre_frame is None:
     pre_frame = gray_lwpCV
    else:
     img_delta = cv2.absdiff(pre_frame, gray_lwpCV)
     thresh = cv2.threshold(img_delta, 25, 255, cv2.THRESH_BINARY)[1]
     thresh = cv2.dilate(thresh, None, iterations=2)
     image, contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                 cv2.CHAIN_APPROX_SIMPLE)
     for x in contours:
      if cv2.contourArea(x) < 1000: # 设置敏感度
       continue
      else:
       cv2.imwrite(
        'image/' + fname + '_' + datetime.now().strftime('%H%M%S') + '_' + str(
         random.randrange(0, 9999)) + '.jpg',
        frame_lwpCV)
       # print("监测到移动物体。。。 ", datetime.now().strftime('%H:%M:%S'))
       break
     pre_frame = gray_lwpCV
   counter += 1
   key = cv2.waitKey(1) & 0xFF
   if key == ord('q'):
    break
  else:
   end_time = datetime.now()
   print('{} 完成处理文件: {} 耗时:{}'.format(end_time.strftime('%H:%M:%S'), fname, end_time - start_time))
   break
 camera.release()
 # cv2.destroyAllWindows() # 与上面的imshow对应
 
 
for file in get_files(path):
 fname = file.split('\\')[-1].replace('.mp4', '')
 process(file, fname)

以上这篇python opencv 检测移动物体并截图保存实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之dict()的操作方法
Sep 24 Python
Python实现删除文件中含“指定内容”的行示例
Jun 09 Python
Python实现k-means算法
Feb 23 Python
python实现简单登陆流程的方法
Apr 22 Python
Python3中的json模块使用详解
May 05 Python
PyCharm如何导入python项目的方法
Feb 06 Python
logging level级别介绍
Feb 21 Python
Python实现转换图片背景颜色代码
Apr 30 Python
Django 解决由save方法引发的错误
May 21 Python
python处理写入数据代码讲解
Oct 22 Python
python中numpy.empty()函数实例讲解
Feb 05 Python
基于PyTorch中view的用法说明
Mar 03 Python
Python标准库json模块和pickle模块使用详解
Mar 10 #Python
Python xlrd excel文件操作代码实例
Mar 10 #Python
python图片剪裁代码(图片按四个点坐标剪裁)
Mar 10 #Python
python 截取XML中bndbox的坐标中的图像,另存为jpg的实例
Mar 10 #Python
Python代码一键转Jar包及Java调用Python新姿势
Mar 10 #Python
Python读取VOC中的xml目标框实例
Mar 10 #Python
Python 读取xml数据,cv2裁剪图片实例
Mar 10 #Python
You might like
phpMyAdmin2.11.6安装配置方法
2008/08/24 PHP
8个PHP数组面试题
2015/06/23 PHP
深入浅析PHP无限极分类的案例教程
2016/05/09 PHP
PHP缩略图生成和图片水印制作
2017/01/07 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
Yii框架常见缓存应用实例小结
2019/09/09 PHP
Javascript 陷阱 window全局对象
2008/11/26 Javascript
extjs之去除s.gif的影响
2010/12/25 Javascript
体验js中splice()的强大(插入、删除或替换数组的元素)
2013/01/16 Javascript
jquery得到iframe src属性值的方法
2014/09/25 Javascript
node.js中的emitter.on方法使用说明
2014/12/10 Javascript
javascript实现鼠标拖动改变层大小的方法
2015/04/30 Javascript
HTML5+jQuery插件Quicksand实现超酷的星际争霸2兵种分类展示效果(附demo源码下载)
2016/05/25 Javascript
简单实现js页面切换功能
2021/01/10 Javascript
总结在前端排序中遇到的问题
2016/07/19 Javascript
Bootstrap CSS布局之表单
2016/12/17 Javascript
微信小程序实现轮播图效果
2017/09/07 Javascript
angularJs中ng-model-options设置数据同步的方法
2018/09/30 Javascript
mpvue开发音频类小程序踩坑和建议详解
2019/03/12 Javascript
jquery+css3实现的经典弹出层效果示例
2020/05/16 jQuery
JS实现电脑虚拟键盘打字测试
2020/06/24 Javascript
python清除指定目录内所有文件中script的方法
2015/06/30 Python
python dataframe NaN处理方式
2019/12/26 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
Python 实现将某一列设置为str类型
2020/07/14 Python
CSS3实现渐变背景兼容问题
2020/05/06 HTML / CSS
纪伊国屋新加坡网上书店:Kinokuniya新加坡
2017/12/29 全球购物
C/C++程序员常见面试题一
2012/12/08 面试题
文体活动总结范文
2014/05/05 职场文书
2014年设计师工作总结
2014/11/25 职场文书
党员民主生活会材料
2014/12/15 职场文书
前台文员岗位职责
2015/02/04 职场文书
档案管理员岗位职责
2015/02/12 职场文书
工程质量保证书
2015/05/09 职场文书
2016年五一劳动节专题校园广播稿
2015/12/17 职场文书
golang http使用踩过的坑与填坑指南
2021/04/27 Golang