#!/usr/bin/env python

'''
This module contais some common routines used by other samples.
''' import numpy as np
import cv2
import os
from contextlib import contextmanager
import itertools as it 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, (x, y), s):
cv2.putText(dst, s, (x+1, y+1), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), thickness = 2, lineType=cv2.CV_AA)
cv2.putText(dst, s, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineType=cv2.CV_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
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()
else:
self.prev_pt = None # 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
return it.izip_longest(fillvalue=fillvalue, *args) 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)
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)

第15行: Bunch函数是将传入 的参数作为一个字典便于查询使用。使用例程如下

>>> jack = Bunch(a=4,b=5,c=6)
>>> print(jack)
{'c': 6, 'a': 4, 'b': 5}
bokeyuan={"b":1,
"o":2,
"k":3,
"e":4,
"y":5,
"u":6,
"a":7,
"n":8,
}

该对象是用于将一个字典转化成对象的代码例如 现在想转化一个对象,我们通常会这样写

class Dict2Obj:
def __init__(self,bokeyuan):
self.b = bokeyuan['b']
self.o = bokeyuan['o']
self.k = bokeyuan['k']
self.e = bokeyuan['e']
self.y = bokeyuan['y']
self.u = bokeyuan['u']
self.a = bokeyuan['a']
self.n = bokeyuan['n']

但是在了解这个方法时候我们会这样写,

1 class Dict2Obj:
2 def __init__(self,bokeyuan):
3 self.__dict__.update(bokeyuan)

然后这样调用

jack = Dict2Obj(bokeyuan)

总结:__dict__用于显示该对象的所有字典元素。__dict__.update()用于更新或者添加元素。




第21行:该函数的作用是传入路径,os.path.split分割 路径名和文件名  os.path.splitext传入文件名.后缀 用于分割文件名和后缀

>>> os.path.split('jack/2/3/asd.jpg')
('jack/2/3', 'asd.jpg')
>>> os.path.splitext('asd.jpg')
('asd', '.jpg')



第26行: 矩阵相乘,然后每一行进行求和返回新的矩阵

第28行: 将第26行的结果开方

第31行: 3*3的矩阵 将第一行的元素乘以x第二行乘以x第三行乘以x 然后将第一行和第二行的结果除以第三行。



第37行: np.ravel将矩阵多维矩阵a (其中只有四个元素或两个元素)转化为一维矩阵,如果其中只有两个元素的话,进行如下操作

a = (0, 0, a[0], a[1])

然后将其转化为float类型的2*2的矩阵。



第43行: rect2rect_mtx(src, dst): 首先将传入的两个图像进行to_rect(a) 操作,然后(dst的第2行-第一行)/(src的第二行-第一行), 




05-21 22:54