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中装饰器的用法
Jun 28 Python
Python中Selenium模拟JQuery滑动解锁实例
Jul 26 Python
python实现神经网络感知器算法
Dec 20 Python
python+pillow绘制矩阵盖尔圆简单实例
Jan 16 Python
浅谈Python中的zip()与*zip()函数详解
Feb 24 Python
python3爬虫之设计签名小程序
Jun 19 Python
对python创建及引用动态变量名的示例讲解
Nov 10 Python
Python使用post及get方式提交数据的实例
Jan 24 Python
对python中arange()和linspace()的区别说明
May 03 Python
python调用私有属性的方法总结
Jul 24 Python
python 解决selenium 中的 .clear()方法失效问题
Sep 01 Python
OpenCV-Python直方图均衡化实现图像去雾
Jun 07 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
Mysql的GROUP_CONCAT()函数使用方法
2008/03/28 PHP
php str_pad 函数使用详解
2009/01/13 PHP
解决phpmyadmin中缺少mysqli扩展问题的方法
2013/05/06 PHP
PHP文件锁函数flock()详细介绍
2014/11/18 PHP
PHP版本常用的排序算法汇总
2015/12/20 PHP
thinkphp3.2.3 分页代码分享
2016/07/28 PHP
PHP微信发送推送消息乱码的解决方法
2019/02/28 PHP
基于javascript数组实现图片轮播
2016/05/02 Javascript
JS判断字符串变量是否含有某个字串的实现方法
2016/06/03 Javascript
JS时间控制实现动态效果的实例讲解
2017/07/31 Javascript
vue.js 微信支付前端代码分享
2018/02/10 Javascript
angularjs实现的购物金额计算工具示例
2018/05/08 Javascript
JavaScript中toLocaleString()和toString()的区别实例分析
2018/08/14 Javascript
JavaScript数组特性与实践应用深入详解
2018/12/30 Javascript
微信小程序wepy框架学习和使用心得详解
2019/05/24 Javascript
seajs和requirejs模块化简单案例分析
2019/08/26 Javascript
js实现动态时钟
2020/03/12 Javascript
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
2020/04/07 Javascript
vue中实现弹出层动画效果的示例代码
2020/09/25 Javascript
[02:28]DOTA2 2015国际邀请赛中国区预选赛首日现场百态
2015/05/26 DOTA
[36:43]NB vs Optic 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
深入探究Python中变量的拷贝和作用域问题
2015/05/05 Python
Python上下文管理器和with块详解
2017/09/09 Python
Python 二叉树的层序建立与三种遍历实现详解
2019/07/29 Python
python输入错误后删除的方法
2019/10/12 Python
tensorflow如何继续训练之前保存的模型实例
2020/01/21 Python
python画环形图的方法
2020/03/25 Python
美国正宗设计师眼镜在线零售商:EYEZZ
2019/03/23 全球购物
运动鞋、街头服装、手表和手袋的实时市场:StockX
2020/11/25 全球购物
见习期自我鉴定
2013/11/07 职场文书
绿色城市实施方案
2014/03/19 职场文书
勿忘国耻9.18演讲稿(经典篇)
2014/09/14 职场文书
2014幼儿园保育员工作总结
2014/11/10 职场文书
Python爬取某拍短视频
2021/06/11 Python
在js中修改html body的样式
2021/11/11 Javascript
Nginx报404错误的详细解决方法
2022/07/23 Servers