def get_features(im): im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) detector = cv2.SURF(400, 5, 5) t0 = time.time() kps, descs = detector.detectAndCompute(im, None) logger.debug('feature detection: %f sec' % (time.time() - t0)) return (kps, descs)
def __init__(self, visualwords, index_filepath=None, algorithm='kdtree', loglevel='WARNING'): """Create or load index of visual words. :param visualwords: 2D array of base vectors :type visualwords: M x len(feature) `numpy.ndarray`, where each element is `numpy.float32` :param index_filepath: If not `None`, index is not created but load from specified file. The file must be created by :func:`BoFMaker.save` :param algorithm: passed to `pyflann.FLANN().build_index` """ self._n_visualwords = visualwords.shape[0] self._flann = pyflann.FLANN() if index_filepath is not None: # load index logger.debug('Loading visual words index from %s ...' % (index_filepath)) t0 = time.time() with open(BoFMaker.meta_filepath(index_filepath)) as f: self._index_param = json.load(f) self._flann.load_index(index_filepath, visualwords) logger.debug('%f sec to load index' % (time.time() - t0)) else: # create index logger.debug('Creating index of visual words...') t0 = time.time() self._index_param = self._flann.build_index( visualwords, algorithm=algorithm) logger.debug('%f sec to create index' % (time.time() - t0))
def __init__(self, visualwords, index_filepath=None, algorithm='kdtree', loglevel='WARNING'): """Create or load index of visual words. :param visualwords: 2D array of base vectors :type visualwords: M x len(feature) `numpy.ndarray`, where each element is `numpy.float32` :param index_filepath: If not `None`, index is not created but load from specified file. The file must be created by :func:`BoFMaker.save` :param algorithm: passed to `pyflann.FLANN().build_index` """ self._n_visualwords = visualwords.shape[0] self._flann = pyflann.FLANN() if index_filepath is not None: # load index logger.debug('Loading visual words index from %s ...' % (index_filepath)) t0 = time.time() with open(BoFMaker.meta_filepath(index_filepath)) as f: self._index_param = json.load(f) self._flann.load_index(index_filepath, visualwords) logger.debug('%f sec to load index' % (time.time() - t0)) else: # create index logger.debug('Creating index of visual words...') t0 = time.time() self._index_param = self._flann.build_index(visualwords, algorithm=algorithm) logger.debug('%f sec to create index' % (time.time() - t0))
def visualwords_union(features, loglevel='WARNING'): """Create simple visual words just by making union of feature vectors Not suitable for large number of features. :param features: feature vectors. Iterable of 2-D `numpy.ndarray`. Example: .. code-block: python ( [[1.2, 3.5], [2.3, 4.1]], # image0's feature vectors ... ) :rtype: 2-D `numpy.ndarray` """ t0 = time.time() visualwords = np.array(list(itertools.chain.from_iterable(features))) logger.debug('%f sec to union feature vectors' % (time.time() - t0)) return visualwords
def make(self, features, norm_order=None): """Create BoF representation of features. :param features: 2D array of feature vectors :type features: N x len(feature) `numpy.ndarray`, where each element is `numpy.float32` :param norm_order: `1` for L1-norm, `2` for L2-norm, ... Histogram is not normalized when this is `None`. """ # nearest neighbor search t0 = time.time() nn_idx, dists = self._flann.nn_index( features, 1, checks=self._index_param['checks']) logger.debug('%f sec to search approx nearest neighbor' % (time.time() - t0)) # make BoF histogram bof_hist, bins = np.histogram(nn_idx, bins=self._n_visualwords) if norm_order is None: return bof_hist return bof_hist / np.linalg.norm(bof_hist, ord=norm_order)
def capdetector(imgpath, max_candidates, loglevel='WARNING'): """Detect circles from an image :rtype: [{'x': <cap circle center x>, 'y': <cap circle center y>, 'r': <cap circle radius>}, ...] """ logger.setLevel(loglevel) im = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) im_height, im_width = im.shape[0:2] logger.debug('%s: size=(%d,%d)' % (basename(imgpath), im_width, im_height)) im = cv2.GaussianBlur(im, ksize=(5, 5), sigmaX=0) # circles => [(x, y, r), ...] ; left one is most voted t0 = time.time() circles = cv2.HoughCircles( im, cv2.cv.CV_HOUGH_GRADIENT, dp=1, minDist=1, param1=85, param2=40, minRadius=int(min(im_width, im_height) * 0.2), maxRadius=int(min(im_width, im_height) * 0.6)) t1 = time.time() logger.debug('cv2.HoughCircles(): %d circles detected in %f sec' % (circles.size, t1 - t0)) # filter beer cap candidates from circles (at most `max_caididates`) center_x, center_y = (im_width / 2, im_height / 2) near_center_r = min(im_width, im_height) * 0.2 caps = [] t0 = time.time() for x, y, r in circles[0, :]: # only see near-center circle if (x - center_x) ** 2 + (y - center_y) ** 2 > near_center_r ** 2: continue caps.append({'x': int(x), 'y': int(y), 'r': int(r)}) if len(caps) >= max_candidates: break t1 = time.time() logger.debug('finding top-%d possible circles: %f sec' % (max_candidates, t1 - t0)) return caps