def getBowDictionary(self,dictionarySize, descriptors, featureExtraType): ''' get the dictionary of Bog of words :param dictionarySize: the size of dictionary :param descriptors: the all images' descriptors :param featureExtraType: the feature type: sift or surf :return: the dictionary of Bag of words ''' BOW = cv2.BOWKMeansTrainer(dictionarySize) for dsc in descriptors: BOW.add(dsc) # dictionary created dictionary = BOW.cluster() if (featureExtraType.upper() == "SIFT"): extra = cv2.DescriptorExtractor_create("SIFT") if (featureExtraType.upper() == "SURF"): extra = cv2.DescriptorExtractor_create("SURF") bowDictionary = cv2.BOWImgDescriptorExtractor(extra, cv2.BFMatcher(cv2.NORM_L2)) bowDictionary.setVocabulary(dictionary) return bowDictionary
def describe(self, image): # detect keypoints in the image detector = cv2.FeatureDetector_create(self.kpMethod) kps = detector.detect(image) # extract local invariant descriptors from each keypoint, # then convert the keypoints to a numpy array extractor = cv2.DescriptorExtractor_create(self.descMethod) (kps, descs) = extractor.compute(image, kps) kps = np.float32([kp.pt for kp in kps]) # return a tuple of keypoints and descriptors return (kps, descs)
def __init__(self, im1_file, im2_file, descriptor_name): rospack = rospkg.RosPack() self.im1_file = rospack.get_path('computer_vision_examples') + '/images/' + im1_file self.im2_file = rospack.get_path('computer_vision_examples') + '/images/' + im2_file self.detector = cv2.FeatureDetector_create(descriptor_name) self.extractor = cv2.DescriptorExtractor_create(descriptor_name) self.matcher = cv2.BFMatcher() self.im = None self.corner_threshold = 0.0 self.ratio_threshold = 1.0
def brief_heavy(img): star = cv2.FeatureDetector_create("STAR") # Initiate BRIEF extractor brief = cv2.DescriptorExtractor_create("BRIEF") kp = star.detect(img, None) kp, des = brief.compute(img, kp) print des.shape x = des x = np.average(x, axis=0) return x
def get_cls_features_vec(self, cls_path, classname): cls_feat_vecs = [] images = os.listdir(cls_path) # pbar = tqdm(total = len(images), desc=classname) for gray in images: img = cv2.imread(cls_path+gray) detector = cv2.FeatureDetector_create(self.feature_type) kp = detector.detect(img) sift = cv2.DescriptorExtractor_create(self.feature_type) des = sift.compute(img, kp) cls_feat_vecs.append(self.get_fea_vec(des[1])) # pbar.update(1) self.feature_vectors.append(cls_feat_vecs)
def doSIFT(self, image): # SIFT gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) sift = cv2.FeatureDetector_create("SIFT") kps = sift.detect(gray) sift2 = cv2.DescriptorExtractor_create("SIFT") (kps, features) = sift2.compute(gray, kps) # 把关键点转为 Numpy 数组 kps = np.float32([kp.pt for kp in kps]) # 返回关键点和特征的元组 return (kps, features)
def extract_features_sift(image, config): sift_edge_threshold = config['sift_edge_threshold'] sift_peak_threshold = float(config['sift_peak_threshold']) i = 0 if context.OPENCV3: try: detector = cv2.xfeatures2d.SIFT_create( edgeThreshold=sift_edge_threshold, contrastThreshold=sift_peak_threshold) except AttributeError as ae: if "no attribute 'xfeatures2d'" in ae.message: logger.error('OpenCV Contrib modules are required to extract SIFT features') raise descriptor = detector else: detector = cv2.FeatureDetector_create('SIFT') descriptor = cv2.DescriptorExtractor_create('SIFT') detector.setDouble('edgeThreshold', sift_edge_threshold) while True: logger.debug('Computing sift with threshold {0}'.format(sift_peak_threshold)) t = time.time() if context.OPENCV3: detector = cv2.xfeatures2d.SIFT_create( edgeThreshold=sift_edge_threshold, contrastThreshold=sift_peak_threshold) else: detector.setDouble("contrastThreshold", sift_peak_threshold) points = detector.detect(image) logger.debug('Found {0} points in {1}s'.format(len(points), time.time() - t)) # write sift feature points if False: imgOut = np.empty((image.shape[0], image.shape[1], 3), dtype=np.uint8) cv2.drawKeypoints(image, points, imgOut) #cv2.imshow(str(i),imgOut) cv2.imwrite('/home/qli/workspace/OpenSfM/data/MattTest/sift_keypoints_'+str(i)+'.jpg',imgOut) fig=plt.figure('keypoints'+str(i)) plt.imshow(imgOut) plt.show() i = i+1 if len(points) < config['feature_min_frames'] and sift_peak_threshold > 0.0001: sift_peak_threshold = (sift_peak_threshold * 2) / 3 logger.debug('reducing threshold') else: logger.debug('done') break points, desc = descriptor.compute(image, points) print( cv2. __version__) if config['feature_root']: desc = root_feature(desc) points = np.array([(i.pt[0], i.pt[1], i.size, i.angle) for i in points]) return points, desc
def extract_features_surf(image, config, name): surf_hessian_threshold = config.get('surf_hessian_threshold', 3000) if context.OPENCV3: try: detector = cv2.xfeatures2d.SURF_create() except AttributeError as ae: if "no attribute 'xfeatures2d'" in ae.message: logger.error( 'OpenCV Contrib modules are required to extract SURF features' ) raise descriptor = detector detector.setHessianThreshold(surf_hessian_threshold) detector.setNOctaves(config.get('surf_n_octaves', 4)) detector.setNOctaveLayers(config.get('surf_n_octavelayers', 2)) detector.setUpright(config.get('surf_upright', 0)) else: detector = cv2.FeatureDetector_create('SURF') descriptor = cv2.DescriptorExtractor_create('SURF') detector.setDouble('hessianThreshold', surf_hessian_threshold) detector.setDouble('nOctaves', config.get('surf_n_octaves', 4)) detector.setDouble('nOctaveLayers', config.get('surf_n_octavelayers', 2)) detector.setInt('upright', config.get('surf_upright', 0)) while True: logger.debug( 'Computing surf with threshold {0}'.format(surf_hessian_threshold)) t = time.time() if context.OPENCV3: detector.setHessianThreshold(surf_hessian_threshold) else: detector.setDouble("hessianThreshold", surf_hessian_threshold) # default: 0.04 points = detector.detect(image) logger.debug( name + ' Found {0} points in {1}s'.format(len(points), time.time() - t)) if len(points) < config.get('feature_min_frames', 0) and surf_hessian_threshold > 0.0001: surf_hessian_threshold = (surf_hessian_threshold * 2) / 3 logger.debug('reducing threshold') else: logger.debug('done') break points, desc = descriptor.compute(image, points) if config.get('feature_root', False): desc = root_feature_surf(desc, partial=True) points = np.array([(i.pt[0], i.pt[1], i.size, i.angle) for i in points]) return points, desc
def get_key_points_from_img(img): if isinstance(img,str): img = cv2.imread(img) if len(img.shape)>2: im = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: im = img surfDetector = cv2.FeatureDetector_create("SIFT") surfDescriptorExtractor = cv2.DescriptorExtractor_create("SIFT") keypoints = surfDetector.detect(im) (keypoints, descriptors) = surfDescriptorExtractor.compute(im, keypoints) return (keypoints, descriptors)
def search(image_path, candidatenum): pklfile = open('bof.pkl', 'rb') im_features, true_paths, idf, numWords, voc = joblib.load(pklfile) fea_det = cv2.FeatureDetector_create('SIFT') des_ext = cv2.DescriptorExtractor_create('SIFT') des_list = [] im = cv2.imread(image_path) kpts = fea_det.detect(im) kpts, des = des_ext.compute(im, kpts) des_list.append((image_path, des)) descriptors = des_list[0][1] test_features = np.zeros((1, numWords), 'float32') words, distance = vq(descriptors, voc) for w in words: test_features[0][w] += 1 test_features = test_features * idf test_features = preprocessing.normalize(test_features, norm='l2') # distances = [] # test_vector = np.array(test_features[0]) # for imvector in im_features: # imvector = np.array(imvector) # dis = np.linalg.norm(test_vector - imvector) # distances.append(dis) # distances = np.array(distances) score = np.dot(test_features, im_features.T) rank_ID = np.argsort(-score) pklfile = open('urldict.pkl', 'rb') urldict = pickle.load(pklfile) urllist = [] for i, ID in enumerate(rank_ID[0][0:candidatenum]): # if image_paths[ID] == "bowtrain/1.jpg": # print "that is", i path = true_paths[ID] imagename = re.findall('/(.*)', path)[0] print "imagename", imagename print urldict[imagename] urllist.append(urldict[imagename]) return urllist
def surfFromPixel(image_surfl, image_surfl2, image_surfl3, x, y): surf = cv2.DescriptorExtractor_create('SURF') # use 128-long descriptor surf.setBool('extended', True) # reverse the axis key_point = cv2.KeyPoint(y, x, surf_window) # compute surf descriptor at 3 different scales # each descriptor has dim. 1x128 _, descriptor1 = surf.compute(image_surfl, [key_point]) _, descriptor2 = surf.compute(image_surfl2, [key_point]) _, descriptor3 = surf.compute(image_surfl3, [key_point]) # concatenate the 3 descriptors to for a 1x384 feature vector return np.reshape( np.concatenate((descriptor1, descriptor2, descriptor3), axis=1), -1)
def detectAndDescribe(self, image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if self.isv3: descriptor = cv2.xfeatures2d.SIFT_create() (kps, features) = descriptor.detectAndCompute(image, None) else: detector = cv2.FeatureDetector_create("SIFT") kps = detector.detector.detect(gray) extractor = cv2.DescriptorExtractor_create("SIFT") (kps, features) = extractor.compute(gray, kps) kps = np.float32([kp.pt for kp in kps]) return (kps, features)
def analyze_rep(img): # Assume image is rectified! if 'cv2' not in globals() or 'cv' not in globals(): import cv, cv2 detector = cv2.FeatureDetector_create("SIFT") descriptor = cv2.DescriptorExtractor_create("SIFT") skp=detector.detect(img) skp,sd=descriptor.compute(img,skp) if not len(skp): return None smoothed = cv2.GaussianBlur(img,(0,0),3*max(1024,*img.shape)/2048.) edges = cv2.Canny(smoothed,0.3,0.8) pedges = process_edges(edges,smoothed) cluster(img,skp,sd)
def calculate(self, resource): """ Append descriptors to SURF h5 table """ #initalizing extended = 0 HessianThresh = 400 nOctaves = 3 nOctaveLayers = 4 (image_url, mask_url, gobject_url) = resource if image_url is '': raise FeatureExtractionError(resource, 400, 'Image resource is required') if mask_url is not '': raise FeatureExtractionError(resource, 400, 'Mask resource is not accepted') #image_url = BQServer().prepare_url(image_url, remap='display') im = image2numpy(image_url, remap='display') im = np.uint8(im) if gobject_url is '': fs = cv2.SURF().detect(im) if gobject_url: (x, y, size) = gobject2keypoint(gobject_url) fs = [cv2.KeyPoint(x, y, size)] # keypoints descriptor_extractor = cv2.DescriptorExtractor_create("SURF") (kpts, descriptors) = descriptor_extractor.compute(im, fs) if descriptors == None: #taking Nonetype into account raise FeatureExtractionError(resource, 500, 'No feature was calculated') x = [] y = [] response = [] size = [] angle = [] octave = [] for k in kpts[:500]: x.append(k.pt[0]) y.append(k.pt[1]) response.append(k.response) size.append(k.size) angle.append(k.angle) octave.append(k.octave) return (descriptors, x, y, response, size, angle, octave)
def describe(path, dictionary): matcher = cv2.FlannBasedMatcher(flann_params, {}) # блять detector = cv2.SIFT() extractor = cv2.DescriptorExtractor_create('SIFT') bowDE = cv2.BOWImgDescriptorExtractor(extractor, matcher) bowDE.setVocabulary(dictionary) image = cv2.imread(path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) kp = detector.detect(gray, None) des = bowDE.compute(gray, kp, None) return des
def getSiftDescriptor(self): if self.siftDes is None: img1 = self.img img1 = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) img1 = cv2.resize(img1, (256, 250)) detector = cv2.FeatureDetector_create("SIFT") # SURF, FAST, SIFT descriptor = cv2.DescriptorExtractor_create("SIFT") # SURF, SIFT # find the keypoints with the chosen detector self.siftKP = detector.detect(img1) # find the descriptors with the chosen descriptor [k1, self.siftDes] = descriptor.compute(img1, self.siftKP) return [self.siftKP, self.siftDes]
def findKeyPoints(img, template, maxdist=200): import cv2 import numpy as np import itertools import sys detector = cv2.FeatureDetector_create("FAST") descriptor = cv2.DescriptorExtractor_create("SIFT") skp = detector.detect(img) skp, sd = descriptor.compute(img, skp) tkp = detector.detect(template) tkp, td = descriptor.compute(template, tkp) flann_params = dict(algorithm=1, trees=4) flann = cv2.flann_Index(sd, flann_params) idx, dist = flann.knnSearch(td, 1, params={}) del flann dist = dist[:,0]/2500.0 dist = dist.reshape(-1,).tolist() idx = idx.reshape(-1).tolist() indices = range(len(dist)) indices.sort(key=lambda i: dist[i]) dist = [dist[i] for i in indices] idx = [idx[i] for i in indices] skp_final = [] for i, dis in itertools.izip(idx, dist): if dis < maxdist: skp_final.append(skp[i]) flann = cv2.flann_Index(td, flann_params) idx, dist = flann.knnSearch(sd, 1, params={}) del flann dist = dist[:,0]/2500.0 dist = dist.reshape(-1,).tolist() idx = idx.reshape(-1).tolist() indices = range(len(dist)) indices.sort(key=lambda i: dist[i]) dist = [dist[i] for i in indices] idx = [idx[i] for i in indices] tkp_final = [] for i, dis in itertools.izip(idx, dist): if dis < maxdist: tkp_final.append(tkp[i]) return skp_final, tkp_final
def __init__(self, descriptor_name): self.detector = cv2.FeatureDetector_create(descriptor_name) self.extractor = cv2.DescriptorExtractor_create(descriptor_name) self.matcher = cv2.BFMatcher() self.query_img = None self.query_roi = None self.query_img_test = None #For testing update_query_roi self.query_roi_test = None #For testing update_query_roi self.last_detection = None self.corner_threshold = 0.0 self.ratio_threshold = 1.0 self.state = ObjectTracker.SELECTING_QUERY_IMG
def extract_features_surf( image: np.ndarray, config: Dict[str, Any], features_count: int) -> Tuple[np.ndarray, np.ndarray]: surf_hessian_threshold = config["surf_hessian_threshold"] if context.OPENCV3: try: detector = cv2.xfeatures2d.SURF_create() except AttributeError as ae: if "no attribute 'xfeatures2d'" in str(ae): logger.error( "OpenCV Contrib modules are required to extract SURF features" ) raise descriptor = detector detector.setHessianThreshold(surf_hessian_threshold) detector.setNOctaves(config["surf_n_octaves"]) detector.setNOctaveLayers(config["surf_n_octavelayers"]) detector.setUpright(config["surf_upright"]) else: detector = cv2.FeatureDetector_create("SURF") descriptor = cv2.DescriptorExtractor_create("SURF") detector.setDouble("hessianThreshold", surf_hessian_threshold) detector.setDouble("nOctaves", config["surf_n_octaves"]) detector.setDouble("nOctaveLayers", config["surf_n_octavelayers"]) detector.setInt("upright", config["surf_upright"]) while True: logger.debug( "Computing surf with threshold {0}".format(surf_hessian_threshold)) t = time.time() if context.OPENCV3: detector.setHessianThreshold(surf_hessian_threshold) else: detector.setDouble("hessianThreshold", surf_hessian_threshold) # default: 0.04 points = detector.detect(image) logger.debug("Found {0} points in {1}s".format(len(points), time.time() - t)) if len(points) < features_count and surf_hessian_threshold > 0.0001: surf_hessian_threshold = (surf_hessian_threshold * 2) / 3 logger.debug("reducing threshold") else: logger.debug("done") break points, desc = descriptor.compute(image, points) if config["feature_root"]: desc = root_feature_surf(desc, partial=True) points = np.array([(i.pt[0], i.pt[1], i.size, i.angle) for i in points]) return points, desc
def InitStatic(): detecteurs_type = [ 'FAST', 'STAR', 'SIFT', 'SURF', 'ORB', 'BRISK', 'MSER', 'GFTT', 'HARRIS', 'Dense', 'SimpleBlob' ] descripteur_type = ['SIFT', 'SURF', 'BRIEF', 'BRISK', 'ORB', 'FREAK'] Matcheur.detecteurs = {} Matcheur.descripteurs = {} for key in detecteurs_type: detect = cv2.FeatureDetector_create(key) Matcheur.detecteurs[key.upper()] = detect for key in descripteur_type: descripteur = cv2.DescriptorExtractor_create(key) Matcheur.descripteurs[key.upper()] = descripteur
def image_local_features(params, image): #llegim la imatge: #img = cv2.imread(image) #Cambiem la mida de la imatge: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) detector = cv2.FeatureDetector_create("SIFT") kp = detector.detect(gray) extractor = cv2.DescriptorExtractor_create("SIFT") (kp, des) = extractor.compute(gray, kp) des_sift = des rs = RootSIFT() kp,des = rs.compute(gray, kp, params['descriptor_size']) return des
def main(): """Main execution of the program""" objects = [] matcher = cv2.BFMatcher(cv2.NORM_HAMMING) detector = cv2.FeatureDetector_create("ORB") extractor = cv2.DescriptorExtractor_create("ORB") camera = cv2.VideoCapture("test2.mp4") global frameNumber frameNumber = 0 # Colors for debugging, each object is given a color to differentiate in the debug image global colors colors = [(255,0,0), (0,255,0), (0,0,255), (255,255,0), (255,0,255), (0,255,255)] colorIndex = 0 #bst = BinarySearchTree() while 1: ret, frame = camera.read() segmented = segmentation(frame) cv2.imwrite("%i%s" % (frameNumber, 'labels.jpg'), segmented) segments = extractSegments(frame, segmented) features, shapes = featureExtractor(detector, extractor, segments) featureMatches = matchFinder(features, objects, frameNumber, colorIndex, matcher, shapes) #featureMatches = bst.startSearch(features, matcher, colorIndex) # Render object bounding box, keypoints and name if found in current frame lastName = "" for match in featureMatches: for pair in match.keypointPairs: cv2.line(frame, (int(pair[0].pt[0]), int(pair[0].pt[1])),(int(pair[1].pt[0]), int(pair[1].pt[1])), match.object.color, 1) cv2.rectangle(frame, match.min, match.max, match.object.color, 2) if lastName != match.object.name: cv2.putText(frame, match.object.name, match.min, cv2.FONT_HERSHEY_PLAIN, 2, match.object.color, 2) cv2.putText(frame, match.object.shape, match.min, cv2.FONT_HERSHEY_PLAIN, 2, match.object.color, 2) lastName = match.object.name cv2.imwrite("%i%s" % (frameNumber, '.jpg'), frame) print 'saving image', frameNumber for i, segment in enumerate(segments): cv2.imwrite("%i%s%i%s" % (frameNumber, '_seg', i, '.jpg'), segment) frameNumber += 1
def init_detect_extract(params): ''' Initialize detector and extractor from parameters ''' if params['descriptor_type'] == 'RootSIFT': extractor = RootSIFT() else: extractor = cv2.DescriptorExtractor_create(params['descriptor_type']) detector = cv2.FeatureDetector_create(params['keypoint_type']) return detector, extractor
def createDictionary(argv): args = parseArguments() trainPool = [] for i, row in enumerate(icoll.getPoolUrlsIterator(args.pool)): if row['valid_image']: trainPool.append(row) sys.stdout.write("Pool size: %d\n" % len(trainPool)) # Create feature extraction and keypoint detector objects fea_det = cv2.FeatureDetector_create("SIFT") des_ext = cv2.DescriptorExtractor_create("SIFT") # List where all the descriptors are stored des_list = [] for imageRow in trainPool: im = cv2.imread(imageRow['path']) if im is None: continue kpts = fea_det.detect(im) kpts, des = des_ext.compute(im, kpts) des_list.append(des) # Stack all the descriptors vertically in a numpy array descriptors = des_list[0][1] for descriptor in des_list[1:]: descriptors = np.vstack((descriptors, descriptor)) # Perform k-means clustering sys.stdout.write("Perform k-means clustering... ") sys.stdout.flush() k = 100 voc, variance = kmeans(descriptors, k, 1) sys.stdout.write("done\n") imFeatures = np.zeros((len(des_list), k), "float32") for i in xrange(len(des_list)): words, distance = vq(des_list[i], voc) for w in words: imFeatures[i][w] += 1 # Scaling the words stdSlr = StandardScaler().fit(imFeatures) joblib.dump((stdSlr, k, voc), args.output, compress=3) sys.stdout.write("Result stored in args.output\n") return 0
def init_surf(image_paths): """ Program: Gettig surf descriptors from images Input: list of images Output: descriptors and descriptor lists """ # Create feature extraction and keypoint detector objects fea_det = cv2.FeatureDetector_create('FAST') des_ext = cv2.DescriptorExtractor_create("SURF") print(len(image_paths)) print("Feature detection ...") # List where all the descriptors are stored des_list = [] i = 0 for i in range(0, len(image_paths)): print(1, i) im = image_paths[i] im = pre_surf1(im) im = np.uint8(im) fea_det = cv2.SURF(10000) kpts = fea_det.detect(im) kpts, des = des_ext.compute(im, kpts) img = cv2.drawKeypoints(im, kpts) #plt.imshow(im) plt.imshow(img) if des is None: #print("HELLUEP") zero_des = np.zeros((1, 64), "float32") des_list.append((i, zero_des)) else: #print(np.shape(des)) des_list.append((i, des)) print("Keypoints and descriptors extracted") print("Stacking desriptors") # Stack all the descriptors vertically in a numpy array #print(des_list) descriptors = des_list[0][1] #print((descriptors)) for image_path, descriptor in des_list[1:]: print(2, image_path) descriptors = np.vstack((descriptors, descriptor)) descriptors = descriptors[~np.all(descriptors == 0, axis=1)] print("Descriptors extracted") return descriptors, des_list
def detect_match_with(self, fr_list=[], mod=dict(kp_algo='FAST', des_algo='SIFT')): """ Detect and find best matched result from slides results """ fd = cv2.FeatureDetector_create(mod['kp_algo']) de = cv2.DescriptorExtractor_create(mod['des_algo']) for im in fr_list: # iid = im['index'] img = im['img'] with ExpTimer(verbose=0) as ts: kps = fd.detect(img, None) kps, des = de.compute(img, kps) ts.msecs
def findFeatures(self, img): ''' Finds features in the image using DOG and finds interest points by \ detecting gaussian blobs ''' gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) detector = cv2.FeatureDetector_create("SIFT") # Can use FAST or MSER kps = detector.detect(gray) extractor = cv2.DescriptorExtractor_create("SIFT") #SIFT or SURF (kps, features) = extractor.compute(gray, kps) kps = numpy.float32([i.pt for i in kps]) return (kps, features)
def i2t_feature_detector(detector, image): featureDetector = cv2.FeatureDetector_create(detector) gridAdaptedDetector = cv2.GridAdaptedFeatureDetector(featureDetector, 200) descriptorExtractor = cv2.DescriptorExtractor_create(detector) start_time = time.time() feature_points = gridAdaptedDetector.detect( cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)) (feature_points, descriptors) = descriptorExtractor.compute(image, feature_points) end_time = time.time() print detector, ": Number of Feature Points is", len( feature_points), "[", end_time - start_time, "]" return (feature_points, descriptors)
def starbrief(imgPath): img = cv2.imread(imgPath) img = np.float32(img) star = cv2.FeatureDetector_create('STAR') brief = cv2.DescriptorExtractor_create('BRIEF') kp = star.detect(img, None) kp, des = brief.compute(img, kp) des = preprocessing.normalize(des) des = des.T print des.shape pca = decomposition.PCA(n_components=4) des = pca.fit_transform(des) des = des.ravel() print des.shape return des
def findDescriptors(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # detect keypoints using Differnce of Gaussian detector detector = cv2.FeatureDetector_create("SIFT") kps = detector.detect(gray) # extract features using SIFT festure extractor extractor = cv2.DescriptorExtractor_create("SIFT") (kps, features) = extractor.compute(gray, kps) # convert keypoints from objects to NumPy arrays kps = np.float32([kp.pt for kp in kps]) return (kps, features) # return keypoints and features