Created
March 27, 2017 06:44
-
-
Save zhenchuan/e7b96b375a2ed16af68243d8a87c810f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[root@web144135 code]# more 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) | |
return | |
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[root@web144135 code]# more find_obj.py | |
# Python 2/3 compatibility | |
from __future__ import print_function | |
import numpy as np | |
import cv2 | |
from common import anorm, getsize | |
from os import listdir | |
from os.path import isfile, join | |
FLANN_INDEX_KDTREE = 1 # bug: flann enums are missing | |
FLANN_INDEX_LSH = 6 | |
mypath = "/workspace/picture/prod/" | |
## detector = cv2.ORB_create(400) | |
## norm = cv2.NORM_HAMMING | |
detector = cv2.xfeatures2d.SURF_create(800) | |
norm = cv2.NORM_L2 | |
## detector = cv2.xfeatures2d.SIFT_create() | |
## norm = cv2.NORM_L2 | |
matcher = cv2.BFMatcher(norm) | |
def filter_matches(kp1, kp2, matches, ratio = 0.75): | |
mkp1, mkp2 = [], [] | |
for m in matches: | |
if len(m) == 2 and m[0].distance < m[1].distance * ratio: | |
m = m[0] | |
mkp1.append( kp1[m.queryIdx] ) | |
mkp2.append( kp2[m.trainIdx] ) | |
p1 = np.float32([kp.pt for kp in mkp1]) | |
p2 = np.float32([kp.pt for kp in mkp2]) | |
kp_pairs = zip(mkp1, mkp2) | |
return p1, p2, list(kp_pairs) | |
def match_images(target,logos): | |
img1 = cv2.imread(target, 0) | |
kp1, desc1 = detector.detectAndCompute(img1, None) | |
return [ single(logos[i],kp1,desc1,True) for i in range(len(logos))] | |
def safe_single(file_name,kp1, desc1,inverse=False): | |
try: | |
single(file_name,kp1,desc1,inverse) | |
except: | |
print("excption %s" %(file_name)) | |
return 0.0 | |
def single(file_name,kp1, desc1,inverse=False): | |
img_file = cv2.imread(file_name, 0) | |
kp2, desc2 = detector.detectAndCompute(img_file, None) | |
if inverse: | |
kp1,kp2 = kp2,kp1 | |
desc1,desc2 = desc2,desc1 | |
raw_matches = matcher.knnMatch(desc1, trainDescriptors = desc2, k = 2) #2 | |
p1, p2, kp_pairs = filter_matches(kp1, kp2, raw_matches) | |
if len(p1) > 4: | |
H, status = cv2.findHomography(p1, p2, cv2.RANSAC, 5.0) | |
print('%d / %d inliers/matched' % (np.sum(status), len(status))) | |
return 1.0 * (np.sum(status)) /len(status) | |
return 0.0 | |
def search_image(query_file): | |
result = {} | |
img1 = cv2.imread(query_file, 0) | |
kp1, desc1 = detector.detectAndCompute(img1, None) | |
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))] | |
for file in onlyfiles: | |
try: | |
target_file = (join(mypath, file)) | |
score = single(target_file,kp1,desc1) | |
if score > 0.5 : | |
result[file] = score | |
except: | |
print(file) | |
return (result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment