写在前边:

OpenCV3.0+要想使用MHI,就要现安装扩展模块opencv_contrib。安装方法见:ubuntu 14.04 64位 安装Opencv3.1.0 (包含opencv_contrib模块)

OpenCV2.4.11中samples/python2/motempl.py 就是使用mhi的一个例子,但是在OpenCV3.1.0下使用的话需要稍加修改:

1.把OpenCV2.4.11/samples/python2/motempl.py 复制到OpenCV3.1.0/samples/python 目录下。

  OpenCV3.1.0的samples里边已经没有motempl.py了。 注:motempl.py需要使用common.py 和 video.py两个文件,直接使用3.1.0/samples里边的这两个文件就行。

2.把motempl.py 的 47、48、49、75这四行的代码,改为:

47 cv2.motempl.updateMotionHistory(motion_mask, motion_history, timestamp, MHI_DURATION)
48 mg_mask, mg_orient = cv2.motempl.calcMotionGradient(motion_history, MAX_TIME_DELTA, MIN_TIME_DELTA, apertureSize=5)
49 seg_mask, seg_bounds = cv2.motempl.segmentMotion(motion_history, timestamp, MAX_TIME_DELTA) 75 angle = cv2.motempl.calcGlobalOrientation(orient_roi, mask_roi, mhi_roi, timestamp, MHI_DURATION)

  其实就是在前边加了个“motempl.”,因为3.0+版本里,把这些函数放在了motempl API里边。

这里贴出来common.py video.py motempl.py三个文件的代码。

common.py

 #!/usr/bin/env python

 '''
This module contains some common routines used by other samples.
''' # Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3 if PY3:
from functools import reduce import numpy as np
import cv2 # built-in modules
import os
import itertools as it
from contextlib import contextmanager image_extensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.pbm', '.pgm', '.ppm'] class Bunch(object):
def __init__(self, **kw):
self.__dict__.update(kw)
def __str__(self):
return str(self.__dict__) def splitfn(fn):
path, fn = os.path.split(fn)
name, ext = os.path.splitext(fn)
return path, name, ext def anorm2(a):
return (a*a).sum(-1)
def anorm(a):
return np.sqrt( anorm2(a) ) def homotrans(H, x, y):
xs = H[0, 0]*x + H[0, 1]*y + H[0, 2]
ys = H[1, 0]*x + H[1, 1]*y + H[1, 2]
s = H[2, 0]*x + H[2, 1]*y + H[2, 2]
return xs/s, ys/s def to_rect(a):
a = np.ravel(a)
if len(a) == 2:
a = (0, 0, a[0], a[1])
return np.array(a, np.float64).reshape(2, 2) def rect2rect_mtx(src, dst):
src, dst = to_rect(src), to_rect(dst)
cx, cy = (dst[1] - dst[0]) / (src[1] - src[0])
tx, ty = dst[0] - src[0] * (cx, cy)
M = np.float64([[ cx, 0, tx],
[ 0, cy, ty],
[ 0, 0, 1]])
return M def lookat(eye, target, up = (0, 0, 1)):
fwd = np.asarray(target, np.float64) - eye
fwd /= anorm(fwd)
right = np.cross(fwd, up)
right /= anorm(right)
down = np.cross(fwd, right)
R = np.float64([right, down, fwd])
tvec = -np.dot(R, eye)
return R, tvec def mtx2rvec(R):
w, u, vt = cv2.SVDecomp(R - np.eye(3))
p = vt[0] + u[:,0]*w[0] # same as np.dot(R, vt[0])
c = np.dot(vt[0], p)
s = np.dot(vt[1], p)
axis = np.cross(vt[0], vt[1])
return axis * np.arctan2(s, c) def draw_str(dst, target, s):
x, y = target
cv2.putText(dst, s, (x+1, y+1), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), thickness = 2, lineType=cv2.LINE_AA)
cv2.putText(dst, s, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineType=cv2.LINE_AA) class Sketcher:
def __init__(self, windowname, dests, colors_func):
self.prev_pt = None
self.windowname = windowname
self.dests = dests
self.colors_func = colors_func
self.dirty = False
self.show()
cv2.setMouseCallback(self.windowname, self.on_mouse) def show(self):
cv2.imshow(self.windowname, self.dests[0]) def on_mouse(self, event, x, y, flags, param):
pt = (x, y)
if event == cv2.EVENT_LBUTTONDOWN:
self.prev_pt = pt
elif event == cv2.EVENT_LBUTTONUP:
self.prev_pt = None if self.prev_pt and flags & cv2.EVENT_FLAG_LBUTTON:
for dst, color in zip(self.dests, self.colors_func()):
cv2.line(dst, self.prev_pt, pt, color, 5)
self.dirty = True
self.prev_pt = pt
self.show() # palette data from matplotlib/_cm.py
_jet_data = {'red': ((0., 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89,1, 1),
(1, 0.5, 0.5)),
'green': ((0., 0, 0), (0.125,0, 0), (0.375,1, 1), (0.64,1, 1),
(0.91,0,0), (1, 0, 0)),
'blue': ((0., 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (0.65,0, 0),
(1, 0, 0))} cmap_data = { 'jet' : _jet_data } def make_cmap(name, n=256):
data = cmap_data[name]
xs = np.linspace(0.0, 1.0, n)
channels = []
eps = 1e-6
for ch_name in ['blue', 'green', 'red']:
ch_data = data[ch_name]
xp, yp = [], []
for x, y1, y2 in ch_data:
xp += [x, x+eps]
yp += [y1, y2]
ch = np.interp(xs, xp, yp)
channels.append(ch)
return np.uint8(np.array(channels).T*255) def nothing(*arg, **kw):
pass def clock():
return cv2.getTickCount() / cv2.getTickFrequency() @contextmanager
def Timer(msg):
print(msg, '...',)
start = clock()
try:
yield
finally:
print("%.2f ms" % ((clock()-start)*1000)) class StatValue:
def __init__(self, smooth_coef = 0.5):
self.value = None
self.smooth_coef = smooth_coef
def update(self, v):
if self.value is None:
self.value = v
else:
c = self.smooth_coef
self.value = c * self.value + (1.0-c) * v class RectSelector:
def __init__(self, win, callback):
self.win = win
self.callback = callback
cv2.setMouseCallback(win, self.onmouse)
self.drag_start = None
self.drag_rect = None
def onmouse(self, event, x, y, flags, param):
x, y = np.int16([x, y]) # BUG
if event == cv2.EVENT_LBUTTONDOWN:
self.drag_start = (x, y)
if self.drag_start:
if flags & cv2.EVENT_FLAG_LBUTTON:
xo, yo = self.drag_start
x0, y0 = np.minimum([xo, yo], [x, y])
x1, y1 = np.maximum([xo, yo], [x, y])
self.drag_rect = None
if x1-x0 > 0 and y1-y0 > 0:
self.drag_rect = (x0, y0, x1, y1)
else:
rect = self.drag_rect
self.drag_start = None
self.drag_rect = None
if rect:
self.callback(rect)
def draw(self, vis):
if not self.drag_rect:
return False
x0, y0, x1, y1 = self.drag_rect
cv2.rectangle(vis, (x0, y0), (x1, y1), (0, 255, 0), 2)
return True
@property
def dragging(self):
return self.drag_rect is not None def grouper(n, iterable, fillvalue=None):
'''grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx'''
args = [iter(iterable)] * n
if PY3:
output = it.zip_longest(fillvalue=fillvalue, *args)
else:
output = it.izip_longest(fillvalue=fillvalue, *args)
return output def mosaic(w, imgs):
'''Make a grid from images. w -- number of grid columns
imgs -- images (must have same size and format)
'''
imgs = iter(imgs)
if PY3:
img0 = next(imgs)
else:
img0 = imgs.next()
pad = np.zeros_like(img0)
imgs = it.chain([img0], imgs)
rows = grouper(w, imgs, pad)
return np.vstack(map(np.hstack, rows)) def getsize(img):
h, w = img.shape[:2]
return w, h def mdot(*args):
return reduce(np.dot, args) def draw_keypoints(vis, keypoints, color = (0, 255, 255)):
for kp in keypoints:
x, y = kp.pt
cv2.circle(vis, (int(x), int(y)), 2, color)

video.py

 #!/usr/bin/env python

 '''
Video capture sample. Sample shows how VideoCapture class can be used to acquire video
frames from a camera of a movie file. Also the sample provides
an example of procedural video generation by an object, mimicking
the VideoCapture interface (see Chess class). 'create_capture' is a convinience function for capture creation,
falling back to procedural video in case of error. Usage:
video.py [--shotdir <shot path>] [source0] [source1] ...' sourceN is an
- integer number for camera capture
- name of video file
- synth:<params> for procedural video Synth examples:
synth:bg=../data/lena.jpg:noise=0.1
synth:class=chess:bg=../data/lena.jpg:noise=0.1:size=640x480 Keys:
ESC - exit
SPACE - save current frame to <shot path> directory ''' # Python 2/3 compatibility
from __future__ import print_function import numpy as np
from numpy import pi, sin, cos import cv2 # built-in modules
from time import clock # local modules
import common class VideoSynthBase(object):
def __init__(self, size=None, noise=0.0, bg = None, **params):
self.bg = None
self.frame_size = (640, 480)
if bg is not None:
self.bg = cv2.imread(bg, 1)
h, w = self.bg.shape[:2]
self.frame_size = (w, h) if size is not None:
w, h = map(int, size.split('x'))
self.frame_size = (w, h)
self.bg = cv2.resize(self.bg, self.frame_size) self.noise = float(noise) def render(self, dst):
pass def read(self, dst=None):
w, h = self.frame_size if self.bg is None:
buf = np.zeros((h, w, 3), np.uint8)
else:
buf = self.bg.copy() self.render(buf) if self.noise > 0.0:
noise = np.zeros((h, w, 3), np.int8)
cv2.randn(noise, np.zeros(3), np.ones(3)*255*self.noise)
buf = cv2.add(buf, noise, dtype=cv2.CV_8UC3)
return True, buf def isOpened(self):
return True class Chess(VideoSynthBase):
def __init__(self, **kw):
super(Chess, self).__init__(**kw) w, h = self.frame_size self.grid_size = sx, sy = 10, 7
white_quads = []
black_quads = []
for i, j in np.ndindex(sy, sx):
q = [[j, i, 0], [j+1, i, 0], [j+1, i+1, 0], [j, i+1, 0]]
[white_quads, black_quads][(i + j) % 2].append(q)
self.white_quads = np.float32(white_quads)
self.black_quads = np.float32(black_quads) fx = 0.9
self.K = np.float64([[fx*w, 0, 0.5*(w-1)],
[0, fx*w, 0.5*(h-1)],
[0.0,0.0, 1.0]]) self.dist_coef = np.float64([-0.2, 0.1, 0, 0])
self.t = 0 def draw_quads(self, img, quads, color = (0, 255, 0)):
img_quads = cv2.projectPoints(quads.reshape(-1, 3), self.rvec, self.tvec, self.K, self.dist_coef) [0]
img_quads.shape = quads.shape[:2] + (2,)
for q in img_quads:
cv2.fillConvexPoly(img, np.int32(q*4), color, cv2.LINE_AA, shift=2) def render(self, dst):
t = self.t
self.t += 1.0/30.0 sx, sy = self.grid_size
center = np.array([0.5*sx, 0.5*sy, 0.0])
phi = pi/3 + sin(t*3)*pi/8
c, s = cos(phi), sin(phi)
ofs = np.array([sin(1.2*t), cos(1.8*t), 0]) * sx * 0.2
eye_pos = center + np.array([cos(t)*c, sin(t)*c, s]) * 15.0 + ofs
target_pos = center + ofs R, self.tvec = common.lookat(eye_pos, target_pos)
self.rvec = common.mtx2rvec(R) self.draw_quads(dst, self.white_quads, (245, 245, 245))
self.draw_quads(dst, self.black_quads, (10, 10, 10)) classes = dict(chess=Chess) presets = dict(
empty = 'synth:',
lena = 'synth:bg=../data/lena.jpg:noise=0.1',
chess = 'synth:class=chess:bg=../data/lena.jpg:noise=0.1:size=640x480'
) def create_capture(source = 0, fallback = presets['chess']):
'''source: <int> or '<int>|<filename>|synth [:<param_name>=<value> [:...]]'
'''
source = str(source).strip()
chunks = source.split(':')
# handle drive letter ('c:', ...)
if len(chunks) > 1 and len(chunks[0]) == 1 and chunks[0].isalpha():
chunks[1] = chunks[0] + ':' + chunks[1]
del chunks[0] source = chunks[0]
try: source = int(source)
except ValueError: pass
params = dict( s.split('=') for s in chunks[1:] ) cap = None
if source == 'synth':
Class = classes.get(params.get('class', None), VideoSynthBase)
try: cap = Class(**params)
except: pass
else:
cap = cv2.VideoCapture(source)
if 'size' in params:
w, h = map(int, params['size'].split('x'))
cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
if cap is None or not cap.isOpened():
print('Warning: unable to open video source: ', source)
if fallback is not None:
return create_capture(fallback, None)
return cap if __name__ == '__main__':
import sys
import getopt print(__doc__) args, sources = getopt.getopt(sys.argv[1:], '', 'shotdir=')
args = dict(args)
shotdir = args.get('--shotdir', '.')
if len(sources) == 0:
sources = [ 0 ] caps = list(map(create_capture, sources))
shot_idx = 0
while True:
imgs = []
for i, cap in enumerate(caps):
ret, img = cap.read()
imgs.append(img)
cv2.imshow('capture %d' % i, img)
ch = 0xFF & cv2.waitKey(1)
if ch == 27:
break
if ch == ord(' '):
for i, img in enumerate(imgs):
fn = '%s/shot_%d_%03d.bmp' % (shotdir, i, shot_idx)
cv2.imwrite(fn, img)
print(fn, 'saved')
shot_idx += 1
cv2.destroyAllWindows()

motempl.py

 #!/usr/bin/env python

 import numpy as np
import cv2
import video
from common import nothing, clock, draw_str MHI_DURATION = 0.5
DEFAULT_THRESHOLD = 32
MAX_TIME_DELTA = 0.25
MIN_TIME_DELTA = 0.05 def draw_motion_comp(vis, (x, y, w, h), angle, color):
cv2.rectangle(vis, (x, y), (x + w, y + h), (0, 255, 0))
r = min(w / 2, h / 2)
cx, cy = x + w / 2, y + h / 2
angle = angle * np.pi / 180
cv2.circle(vis, (cx, cy), r, color, 3)
cv2.line(vis, (cx, cy), (int(cx + np.cos(angle) * r), int(cy + np.sin(angle) * r)), color, 3) if __name__ == '__main__':
import sys try:
video_src = sys.argv[1]
except:
video_src = 0 cv2.namedWindow('motempl')
visuals = ['input', 'frame_diff', 'motion_hist', 'grad_orient']
cv2.createTrackbar('visual', 'motempl', 2, len(visuals) - 1, nothing)
cv2.createTrackbar('threshold', 'motempl', DEFAULT_THRESHOLD, 255, nothing) cam = video.create_capture(video_src, fallback='synth:class=chess:bg=../cpp/lena.jpg:noise=0.01')
ret, frame = cam.read()
h, w = frame.shape[:2]
prev_frame = frame.copy()
motion_history = np.zeros((h, w), np.float32)
hsv = np.zeros((h, w, 3), np.uint8)
hsv[:, :, 1] = 255
while True:
ret, frame = cam.read()
frame_diff = cv2.absdiff(frame, prev_frame)
gray_diff = cv2.cvtColor(frame_diff, cv2.COLOR_BGR2GRAY)
thrs = cv2.getTrackbarPos('threshold', 'motempl')
ret, motion_mask = cv2.threshold(gray_diff, thrs, 1, cv2.THRESH_BINARY)
timestamp = clock()
cv2.motempl.updateMotionHistory(motion_mask, motion_history, timestamp, MHI_DURATION)
mg_mask, mg_orient = cv2.motempl.calcMotionGradient(motion_history, MAX_TIME_DELTA, MIN_TIME_DELTA, apertureSize=5)
seg_mask, seg_bounds = cv2.motempl.segmentMotion(motion_history, timestamp, MAX_TIME_DELTA) visual_name = visuals[cv2.getTrackbarPos('visual', 'motempl')]
if visual_name == 'input':
vis = frame.copy()
elif visual_name == 'frame_diff':
vis = frame_diff.copy()
elif visual_name == 'motion_hist':
vis = np.uint8(np.clip((motion_history - (timestamp - MHI_DURATION)) / MHI_DURATION, 0, 1) * 255)
vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)
elif visual_name == 'grad_orient':
hsv[:, :, 0] = mg_orient / 2
hsv[:, :, 2] = mg_mask * 255
vis = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) for i, rect in enumerate([(0, 0, w, h)] + list(seg_bounds)):
x, y, rw, rh = rect
area = rw * rh
if area < 64 ** 2:
continue
silh_roi = motion_mask[y:y + rh, x:x + rw]
orient_roi = mg_orient[y:y + rh, x:x + rw]
mask_roi = mg_mask[y:y + rh, x:x + rw]
mhi_roi = motion_history[y:y + rh, x:x + rw]
if cv2.norm(silh_roi, cv2.NORM_L1) < area * 0.05:
continue
angle = cv2.motempl.calcGlobalOrientation(orient_roi, mask_roi, mhi_roi, timestamp, MHI_DURATION)
color = ((255, 0, 0), (0, 0, 255))[i == 0]
draw_motion_comp(vis, rect, angle, color) draw_str(vis, (20, 20), visual_name)
cv2.imshow('motempl', vis) prev_frame = frame.copy()
if 0xFF & cv2.waitKey(5) == 27:
break
cv2.destroyAllWindows()

3.运行结果:

 python motempl.py camera2.mov //第三个参赛不加的话是直接开启摄像头

OpenCV3.1.0中调用MHI(Motion History Images, 运动历史图像)的更多相关文章

  1. 在OpenCV3.1.0中使用SIFT,SURF算法

    写在前边: 1.我使用的是python2.7 + OpenCV3.1.0 2.OpenCV3.0.0+的文档有很大问题,很多文档写的还是OpenCV2.0+, OpenCV3.0+根本用不了,其中有一 ...

  2. 在thinkphp5.0中调用ajax时, 返回的JSON 格式数据在html前台不能用时

    在thinkphp5.0中调用ajax时,如果控制器返回的数据为json格式,视图层接收到返回值即为json格式的数据,此时应该把 JSON 文本转换为 JavaScript 对象,方便调用.具体代码 ...

  3. 在 Flash ActionScript 2.0 中调用 Javascript 方法

    本篇文章由:http://xinpure.com/call-the-javascript-method-in-flash-actionscript-2-0/ 在 Flash ActionScript ...

  4. 运动历史图(MHI)——Motion History Image

    MHI最初是由Bobick 和 Davis提出的,在此之前,Bobick 和 Davis 首先提出了二值的运动能量图(Motion Energy Image,MEI),通过描述物体如何移动和运动在空间 ...

  5. MHI ,运动历史图像的的获取[下载自CSDN]

    #include "cv.h" #include "highgui.h" #include "stdlib.h" #include &quo ...

  6. AFNetworking 3.0中调用[AFHTTPSessionManager manager]方法导致内存泄漏的解决办法

    在使用AFNetworking3.0框架,使用Instruments检查Leaks时,检测到1000多个内存泄漏的地方,定位到 [AFHTTPSessionManager manager] 语句中,几 ...

  7. ubuntu14.04 + GTX980ti + cuda 8.0 ---Opencv3.1.0(基础+opecv_contrib)配置

    如果喜欢视频的话:YouTube 上有视频教程 https://www.youtube.com/watch?v=1YIAp3Lh5hI 后来我在mac上安装最新版的OpenCV 找到了一片非常详细的教 ...

  8. opencv3.0中contrib模块的添加+实现SIFT/SURF算法

    平台:win10 x64 +VS 2015专业版 +opencv-3.x.+CMake+Anaconda3(python3.7.0) Issue说明:Opencv3.0版本已经发布了有一段时间,在这段 ...

  9. 【OpenCV】opencv3.0中的SVM训练 mnist 手写字体识别

    前言: SVM(支持向量机)一种训练分类器的学习方法 mnist 是一个手写字体图像数据库,训练样本有60000个,测试样本有10000个 LibSVM 一个常用的SVM框架 OpenCV3.0 中的 ...

随机推荐

  1. 搭建ssm框架,可实现登录和数据展示以及增删改查

    需求: 后台使用ssm(spring-springMVC-mybatis)进行整合 前台使用bootstrap框架 前后台交互使用Ajax进行发送 表结构: 登录页面后显示所有用户信息,可对每条进行增 ...

  2. C# 6.0中你不知道的新特性

    为什么写? 今天去上班的公交上,有朋友在张队(张善友)的微信群里,发了一个介绍C# 6.0新特性的视频,视频7分钟,加上本人英语实在太low,整体看下来是一脸懵逼的. 下班回到家里,打开这个视频,把视 ...

  3. 关于OpenAuth.Net被攻击的感想

    距离上次写博客应该是1年多以前的事情了,看过我博客的人都知道,我从来不在博客园发技术无关的贴子,除了上次离职.但这次我是实在忍不住了. 今天我个人开源项目OpenAuth.Net发布了最新版(有兴趣戳 ...

  4. 使用Git简单笔记

    这里只是作为简单的笔记整理,第一次使用的推荐先看一下廖大的教程,内容很多很细,可以边看边练.看不懂的地方先记着.争取七七八八看下来. ================================= ...

  5. 使用YOLOv2进行图像检测

    基本配置信息 tensorflow (1.4.0) tensorflow-tensorboard (0.4.0) Keras (2.1.5) Python (3.6.0) Anaconda 4.3.1 ...

  6. 简单的sql调优(批处理)

    最近在写一个java的爬虫程序时,遇到了一个大量数据进行插入更新和大量数据循环查询的问题,所以查了一下一般的调优的方式,下面主要介绍我采取的调优措施. 一 .调优思路 先说说我采取方式的调优的思路,这 ...

  7. [LeetCode] Reorganize String 重构字符串

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  8. [LeetCode] Next Greater Element I 下一个较大的元素之一

    You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...

  9. 51 nod 1439 互质对(Moblus容斥)

    1439 互质对 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有n个数字,a[1],a[2],…,a[n].有一个集合,刚开 ...

  10. [USACO Jan09] 安全路径

    Gremlins最近在农场上泛滥,它们经常会阻止牛们从农庄(牛棚_1)走到别的牛棚(牛_i的目的 地是牛棚_i).每一个gremlin只认识牛_i并且知道牛_i一般走到牛棚_i的最短路经.所以它 们在 ...