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查找第k小元素代码分享
Dec 18 Python
zbar解码二维码和条形码示例
Feb 07 Python
使用Python的web.py框架实现类似Django的ORM查询的教程
May 02 Python
python实现的守护进程(Daemon)用法实例
Jun 02 Python
Flask框架的学习指南之制作简单blog系统
Nov 20 Python
Python实现按特定格式对文件进行读写的方法示例
Nov 30 Python
浅谈Python黑帽子取代netcat
Feb 10 Python
如何使用VSCode愉快的写Python于调试配置步骤
Apr 06 Python
django中静态文件配置static的方法
May 20 Python
我就是这样学习Python中的列表
Jun 02 Python
python 基于TCP协议的套接字编程详解
Jun 29 Python
浅析python实现动态规划背包问题
Dec 31 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 对输入信息的进行安全过滤的函数代码
2012/06/29 PHP
用 Composer构建自己的 PHP 框架之基础准备
2014/10/30 PHP
php程序总是提示验证码输入有误解决方案
2015/01/07 PHP
php实现在多维数组中查找特定value的方法
2015/07/29 PHP
php中Ioc(控制反转)和Di(依赖注入)
2017/05/07 PHP
div当滚动到页面顶部的时候固定在顶部实例代码
2013/05/27 Javascript
JavaScript中“过于”犀利地for/in循环使用示例
2013/10/22 Javascript
AngularJS基础知识
2014/12/21 Javascript
JavaScript动态加载样式表的方法
2015/03/21 Javascript
js实现touch移动触屏滑动事件
2015/04/17 Javascript
jQuery插件制作之参数用法实例分析
2015/06/01 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
mint-ui的search组件在键盘显示搜索按钮的实现方法
2017/10/27 Javascript
nvm、nrm、npm 安装和使用详解(小结)
2019/01/17 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
2019/09/11 Javascript
vue el-table实现行内编辑功能
2019/12/11 Javascript
JS代码触发事件代码实例
2020/01/02 Javascript
Node.js设置定时任务之node-schedule模块的使用详解
2020/04/28 Javascript
Python编写屏幕截图程序方法
2015/02/18 Python
python中字符串变二维数组的实例讲解
2018/04/03 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
2020/02/29 Python
在python中实现求输出1-3+5-7+9-......101的和
2020/04/02 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
2020/04/29 Python
以特惠价提供在线奢侈品购物:FRMODA.com
2018/01/25 全球购物
健康教育评估方案
2014/05/25 职场文书
关于运动会广播稿300字
2014/10/05 职场文书
观看建国大业观后感
2015/06/01 职场文书
《日月潭》教学反思
2016/02/20 职场文书
pandas中关于apply+lambda的应用
2022/02/28 Python
一条慢SQL语句引发的改造之路
2022/03/16 MySQL
VUE之图片Base64编码使用ElementUI组件上传
2022/04/09 Vue.js
python实现学生信息管理系统(面向对象)
2022/06/05 Python
MySQL约束(创建表时的各种条件说明)
2022/06/21 MySQL