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基础教程之udp端口扫描
Feb 10 Python
使用python解析xml成对应的html示例分享
Apr 02 Python
Python使用MONGODB入门实例
May 11 Python
python Django模板的使用方法
Jan 14 Python
详解python之多进程和进程池(Processing库)
Jun 09 Python
python生成tensorflow输入输出的图像格式的方法
Feb 12 Python
人脸识别经典算法一 特征脸方法(Eigenface)
Mar 13 Python
Python安装图文教程 Pycharm安装教程
Mar 27 Python
python装饰器深入学习
Apr 06 Python
Python实现的本地文件搜索功能示例【测试可用】
May 30 Python
python实现简单图片物体标注工具
Mar 18 Python
Python 添加文件注释和函数注释操作
Aug 09 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
php的access操作类
2008/04/09 PHP
PHP集成FCK的函数代码
2008/09/27 PHP
php提交过来的数据生成为txt文件
2016/04/28 PHP
创建无限极分类树型结构的简单方法
2017/06/20 PHP
php压缩文件夹最新版
2018/07/18 PHP
phpmyadmin在宝塔面板里进不去的解决方案
2020/07/06 PHP
本地图片预览(支持IE6/IE7/IE8/Firefox3)经验总结
2013/03/25 Javascript
jquery更换文章内容与改变字体大小代码
2013/09/30 Javascript
js中判断用户输入的值是否为空的简单实例
2013/12/23 Javascript
js添加select下默认的option的value和text的方法
2014/10/19 Javascript
轻松掌握JavaScript装饰者模式
2016/08/27 Javascript
jQuery之动画效果大全
2016/11/09 Javascript
[原创]SyntaxHighlighter自动识别并加载脚本语言
2017/02/07 Javascript
Angular实现跨域(搜索框的下拉列表)
2017/02/16 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
js get和post请求实现代码解析
2020/02/06 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
jQuery 实现扁平式小清新导航
2020/07/07 jQuery
微信小程序连续签到7天积分获得功能的示例代码
2020/08/20 Javascript
Vue获取微博授权URL代码实例
2020/11/04 Javascript
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python生成随机验证码的两种方法
2015/12/22 Python
python 开发的三种运行模式详细介绍
2017/01/18 Python
Python 3.7新功能之dataclass装饰器详解
2018/04/21 Python
python文件选择对话框的操作方法
2019/06/27 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
2019/12/11 Python
python numpy 矩阵堆叠实例
2020/01/17 Python
python实现五子棋游戏(pygame版)
2020/01/19 Python
Python numpy大矩阵运算内存不足如何解决
2020/11/19 Python
python中的unittest框架实例详解
2021/02/05 Python
Django视图类型总结
2021/02/17 Python
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
敬老模范事迹
2014/05/21 职场文书
新闻工作者先进事迹
2014/05/26 职场文书
思想作风整顿个人剖析材料
2014/10/06 职场文书
运动会加油稿50字
2015/07/21 职场文书