cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
common.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # *****************************************************************************
4 # * cloudFPGA
5 # * Copyright 2016 -- 2022 IBM Corporation
6 # * Licensed under the Apache License, Version 2.0 (the "License");
7 # * you may not use this file except in compliance with the License.
8 # * You may obtain a copy of the License at
9 # *
10 # * http://www.apache.org/licenses/LICENSE-2.0
11 # *
12 # * Unless required by applicable law or agreed to in writing, software
13 # * distributed under the License is distributed on an "AS IS" BASIS,
14 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # * See the License for the specific language governing permissions and
16 # * limitations under the License.
17 # *----------------------------------------------------------------------------
18 
19 # *****************************************************************************
20 # * OpenCV
21 # * Copyright 2021 -- OpenCV team
22 # * Licensed under the Apache License, Version 2.0 (the "License");
23 # * you may not use this file except in compliance with the License.
24 # * You may obtain a copy of the License at
25 # *
26 # * http://www.apache.org/licenses/LICENSE-2.0
27 # *
28 # * Unless required by applicable law or agreed to in writing, software
29 # * distributed under the License is distributed on an "AS IS" BASIS,
30 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 # * See the License for the specific language governing permissions and
32 # * limitations under the License.
33 # *----------------------------------------------------------------------------
34 
35 '''
36 This module contains some common routines used by other samples.
37 '''
38 
39 # Python 2/3 compatibility
40 from __future__ import print_function
41 import sys
42 PY3 = sys.version_info[0] == 3
43 
44 if PY3:
45  from functools import reduce
46 
47 import numpy as np
48 import cv2 as cv
49 
50 # built-in modules
51 import os
52 import itertools as it
53 from contextlib import contextmanager
54 
55 image_extensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.pbm', '.pgm', '.ppm']
56 
57 class Bunch(object):
58  def __init__(self, **kw):
59  self.__dict__.update(kw)
60  def __str__(self):
61  return str(self.__dict__)
62 
63 def splitfn(fn):
64  path, fn = os.path.split(fn)
65  name, ext = os.path.splitext(fn)
66  return path, name, ext
67 
68 def anorm2(a):
69  return (a*a).sum(-1)
70 def anorm(a):
71  return np.sqrt( anorm2(a) )
72 
73 def homotrans(H, x, y):
74  xs = H[0, 0]*x + H[0, 1]*y + H[0, 2]
75  ys = H[1, 0]*x + H[1, 1]*y + H[1, 2]
76  s = H[2, 0]*x + H[2, 1]*y + H[2, 2]
77  return xs/s, ys/s
78 
79 def to_rect(a):
80  a = np.ravel(a)
81  if len(a) == 2:
82  a = (0, 0, a[0], a[1])
83  return np.array(a, np.float64).reshape(2, 2)
84 
85 def rect2rect_mtx(src, dst):
86  src, dst = to_rect(src), to_rect(dst)
87  cx, cy = (dst[1] - dst[0]) / (src[1] - src[0])
88  tx, ty = dst[0] - src[0] * (cx, cy)
89  M = np.float64([[ cx, 0, tx],
90  [ 0, cy, ty],
91  [ 0, 0, 1]])
92  return M
93 
94 
95 def lookat(eye, target, up = (0, 0, 1)):
96  fwd = np.asarray(target, np.float64) - eye
97  fwd /= anorm(fwd)
98  right = np.cross(fwd, up)
99  right /= anorm(right)
100  down = np.cross(fwd, right)
101  R = np.float64([right, down, fwd])
102  tvec = -np.dot(R, eye)
103  return R, tvec
104 
105 def mtx2rvec(R):
106  w, u, vt = cv.SVDecomp(R - np.eye(3))
107  p = vt[0] + u[:,0]*w[0] # same as np.dot(R, vt[0])
108  c = np.dot(vt[0], p)
109  s = np.dot(vt[1], p)
110  axis = np.cross(vt[0], vt[1])
111  return axis * np.arctan2(s, c)
112 
113 def draw_str(dst, target, s):
114  x, y = target
115  cv.putText(dst, s, (x+1, y+1), cv.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), thickness = 2, lineType=cv.LINE_AA)
116  cv.putText(dst, s, (x, y), cv.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineType=cv.LINE_AA)
117 
118 class Sketcher:
119  def __init__(self, windowname, dests, colors_func):
120  self.prev_ptprev_pt = None
121  self.windownamewindowname = windowname
122  self.destsdests = dests
123  self.colors_funccolors_func = colors_func
124  self.dirtydirty = False
125  self.showshow()
126  cv.setMouseCallback(self.windownamewindowname, self.on_mouseon_mouse)
127 
128  def show(self):
129  cv.imshow(self.windownamewindowname, self.destsdests[0])
130 
131  def on_mouse(self, event, x, y, flags, param):
132  pt = (x, y)
133  if event == cv.EVENT_LBUTTONDOWN:
134  self.prev_ptprev_pt = pt
135  elif event == cv.EVENT_LBUTTONUP:
136  self.prev_ptprev_pt = None
137 
138  if self.prev_ptprev_pt and flags & cv.EVENT_FLAG_LBUTTON:
139  for dst, color in zip(self.destsdests, self.colors_funccolors_func()):
140  cv.line(dst, self.prev_ptprev_pt, pt, color, 5)
141  self.dirtydirty = True
142  self.prev_ptprev_pt = pt
143  self.showshow()
144 
145 
146 # palette data from matplotlib/_cm.py
147 _jet_data = {'red': ((0., 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89,1, 1),
148  (1, 0.5, 0.5)),
149  'green': ((0., 0, 0), (0.125,0, 0), (0.375,1, 1), (0.64,1, 1),
150  (0.91,0,0), (1, 0, 0)),
151  'blue': ((0., 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (0.65,0, 0),
152  (1, 0, 0))}
153 
154 cmap_data = { 'jet' : _jet_data }
155 
156 def make_cmap(name, n=256):
157  data = cmap_data[name]
158  xs = np.linspace(0.0, 1.0, n)
159  channels = []
160  eps = 1e-6
161  for ch_name in ['blue', 'green', 'red']:
162  ch_data = data[ch_name]
163  xp, yp = [], []
164  for x, y1, y2 in ch_data:
165  xp += [x, x+eps]
166  yp += [y1, y2]
167  ch = np.interp(xs, xp, yp)
168  channels.append(ch)
169  return np.uint8(np.array(channels).T*255)
170 
171 def nothing(*arg, **kw):
172  pass
173 
174 def clock():
175  return cv.getTickCount() / cv.getTickFrequency()
176 
177 @contextmanager
178 def Timer(msg):
179  print(msg, '...',)
180  start = clock()
181  try:
182  yield
183  finally:
184  print("%.2f ms" % ((clock()-start)*1000))
185 
186 class StatValue:
187  def __init__(self, smooth_coef = 0.5):
188  self.valuevalue = None
189  self.smooth_coefsmooth_coef = smooth_coef
190  def update(self, v):
191  if self.valuevalue is None:
192  self.valuevalue = v
193  else:
194  c = self.smooth_coefsmooth_coef
195  self.valuevalue = c * self.valuevalue + (1.0-c) * v
196 
198  def __init__(self, win, callback):
199  self.winwin = win
200  self.callbackcallback = callback
201  cv.setMouseCallback(win, self.onmouseonmouse)
202  self.drag_startdrag_start = None
203  self.drag_rectdrag_rect = None
204  def onmouse(self, event, x, y, flags, param):
205  x, y = np.int16([x, y]) # BUG
206  if event == cv.EVENT_LBUTTONDOWN:
207  self.drag_startdrag_start = (x, y)
208  return
209  if self.drag_startdrag_start:
210  if flags & cv.EVENT_FLAG_LBUTTON:
211  xo, yo = self.drag_startdrag_start
212  x0, y0 = np.minimum([xo, yo], [x, y])
213  x1, y1 = np.maximum([xo, yo], [x, y])
214  self.drag_rectdrag_rect = None
215  if x1-x0 > 0 and y1-y0 > 0:
216  self.drag_rectdrag_rect = (x0, y0, x1, y1)
217  else:
218  rect = self.drag_rectdrag_rect
219  self.drag_startdrag_start = None
220  self.drag_rectdrag_rect = None
221  if rect:
222  self.callbackcallback(rect)
223  def draw(self, vis):
224  if not self.drag_rectdrag_rect:
225  return False
226  x0, y0, x1, y1 = self.drag_rectdrag_rect
227  cv.rectangle(vis, (x0, y0), (x1, y1), (0, 255, 0), 2)
228  return True
229  @property
230  def dragging(self):
231  return self.drag_rectdrag_rect is not None
232 
233 
234 def grouper(n, iterable, fillvalue=None):
235  '''grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx'''
236  args = [iter(iterable)] * n
237  if PY3:
238  output = it.zip_longest(fillvalue=fillvalue, *args)
239  else:
240  output = it.izip_longest(fillvalue=fillvalue, *args)
241  return output
242 
243 def mosaic(w, imgs):
244  '''Make a grid from images.
245 
246  w -- number of grid columns
247  imgs -- images (must have same size and format)
248  '''
249  imgs = iter(imgs)
250  if PY3:
251  img0 = next(imgs)
252  else:
253  img0 = imgs.next()
254  pad = np.zeros_like(img0)
255  imgs = it.chain([img0], imgs)
256  rows = grouper(w, imgs, pad)
257  return np.vstack(map(np.hstack, rows))
258 
259 def getsize(img):
260  h, w = img.shape[:2]
261  return w, h
262 
263 def mdot(*args):
264  return reduce(np.dot, args)
265 
266 def draw_keypoints(vis, keypoints, color = (0, 255, 255)):
267  for kp in keypoints:
268  x, y = kp.pt
269  cv.circle(vis, (int(x), int(y)), 2, color)
def __init__(self, **kw)
Definition: common.py:58
def __str__(self)
Definition: common.py:60
def draw(self, vis)
Definition: common.py:223
def __init__(self, win, callback)
Definition: common.py:198
def dragging(self)
Definition: common.py:230
def onmouse(self, event, x, y, flags, param)
Definition: common.py:204
def on_mouse(self, event, x, y, flags, param)
Definition: common.py:131
def __init__(self, windowname, dests, colors_func)
Definition: common.py:119
def show(self)
Definition: common.py:128
def update(self, v)
Definition: common.py:190
def __init__(self, smooth_coef=0.5)
Definition: common.py:187
def splitfn(fn)
Definition: common.py:63
def clock()
Definition: common.py:174
def mosaic(w, imgs)
Definition: common.py:243
def to_rect(a)
Definition: common.py:79
def nothing(*arg, **kw)
Definition: common.py:171
def Timer(msg)
Definition: common.py:178
def getsize(img)
Definition: common.py:259
def anorm2(a)
Definition: common.py:68
def homotrans(H, x, y)
Definition: common.py:73
def anorm(a)
Definition: common.py:70
def draw_str(dst, target, s)
Definition: common.py:113
def mdot(*args)
Definition: common.py:263
def mtx2rvec(R)
Definition: common.py:105
def make_cmap(name, n=256)
Definition: common.py:156
def grouper(n, iterable, fillvalue=None)
Definition: common.py:234
def rect2rect_mtx(src, dst)
Definition: common.py:85
def draw_keypoints(vis, keypoints, color=(0, 255, 255))
Definition: common.py:266
def lookat(eye, target, up=(0, 0, 1))
Definition: common.py:95