├── PCV ├── __init__.py ├── __init__.pyc ├── __pycache__ │ ├── __init__.cpython-36.pyc │ └── __init__.cpython-37.pyc ├── classifiers │ ├── __init__.pyc │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── __init__.cpython-37.pyc │ │ ├── knn.cpython-36.pyc │ │ └── knn.cpython-37.pyc │ ├── bayes.py │ └── knn.py ├── clustering │ ├── __init__.pyc │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ └── __init__.cpython-37.pyc │ └── hcluster.py ├── geometry │ ├── __init__.pyc │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── __init__.cpython-37.pyc │ │ └── homography.cpython-36.pyc │ ├── camera.py │ ├── camera.pyc │ ├── homography.py │ ├── homography.pyc │ ├── sfm.py │ ├── sfm.pyc │ └── warp.py ├── imagesearch │ ├── __init__.pyc │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── __init__.cpython-37.pyc │ │ ├── imagesearch.cpython-36.pyc │ │ └── vocabulary.cpython-36.pyc │ ├── imagesearch.py │ ├── imagesearch.pyc │ ├── vocabulary.py │ └── vocabulary.pyc ├── localdescriptors │ ├── __init__.pyc │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── __init__.cpython-37.pyc │ │ ├── dsift.cpython-36.pyc │ │ ├── dsift.cpython-37.pyc │ │ ├── sift.cpython-36.pyc │ │ └── sift.cpython-37.pyc │ ├── dsift.py │ ├── harris.py │ ├── sift.py │ ├── sift.pyc │ └── tmp.pgm └── tools │ ├── __init__.pyc │ ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── __init__.cpython-37.pyc │ ├── imtools.cpython-36.pyc │ └── imtools.cpython-37.pyc │ ├── graphcut.py │ ├── imregistration.py │ ├── imtools.py │ ├── imtools.pyc │ ├── ncut.py │ ├── pca.py │ ├── ransac.py │ ├── ransac.pyc │ └── rof.py ├── README.md ├── ch08_P168_2D.py ├── ch08_P169_normal.py ├── ch08_P172_dsift.py ├── ch08_P173_Fig8-3.py ├── ch08_P173_gesture.py ├── image ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg └── s └── win32vlfeat ├── Microsoft.VC90.CRT.manifest ├── aib.exe ├── mser.exe ├── msvcr90.dll ├── sift.exe ├── test_gauss_elimination.exe ├── test_getopt_long.exe ├── test_gmm.exe ├── test_heap-def.exe ├── test_host.exe ├── test_imopv.exe ├── test_kmeans.exe ├── test_liop.exe ├── test_mathop.exe ├── test_mathop_abs.exe ├── test_nan.exe ├── test_qsort-def.exe ├── test_rand.exe ├── test_sqrti.exe ├── test_stringop.exe ├── test_svd2.exe ├── test_threads.exe ├── test_vec_comp.exe ├── vl.dll └── vl.lib /PCV/__init__.py: -------------------------------------------------------------------------------- 1 | from PCV.classifiers import * 2 | from PCV.clustering import * 3 | from PCV.geometry import * 4 | from PCV.imagesearch import * 5 | from PCV.localdescriptors import * 6 | from PCV.tools import * -------------------------------------------------------------------------------- /PCV/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/__init__.pyc -------------------------------------------------------------------------------- /PCV/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/classifiers/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/classifiers/__init__.pyc -------------------------------------------------------------------------------- /PCV/classifiers/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/classifiers/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/classifiers/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/classifiers/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/classifiers/__pycache__/knn.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/classifiers/__pycache__/knn.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/classifiers/__pycache__/knn.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/classifiers/__pycache__/knn.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/classifiers/bayes.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | 3 | 4 | class BayesClassifier(object): 5 | 6 | def __init__(self): 7 | """ Initialize classifier with training data. """ 8 | 9 | self.labels = [] # class labels 10 | self.mean = [] # class mean 11 | self.var = [] # class variances 12 | self.n = 0 # nbr of classes 13 | 14 | def train(self,data,labels=None): 15 | """ Train on data (list of arrays n*dim). 16 | Labels are optional, default is 0...n-1. """ 17 | 18 | if labels==None: 19 | labels = range(len(data)) 20 | self.labels = labels 21 | self.n = len(labels) 22 | 23 | for c in data: 24 | self.mean.append(mean(c,axis=0)) 25 | self.var.append(var(c,axis=0)) 26 | 27 | def classify(self,points): 28 | """ Classify the points by computing probabilities 29 | for each class and return most probable label. """ 30 | 31 | # compute probabilities for each class 32 | est_prob = array([gauss(m,v,points) for m,v in zip(self.mean,self.var)]) 33 | 34 | print ('est prob',est_prob.shape,self.labels) 35 | # get index of highest probability, this gives class label 36 | ndx = est_prob.argmax(axis=0) 37 | 38 | est_labels = array([self.labels[n] for n in ndx]) 39 | 40 | return est_labels, est_prob 41 | 42 | 43 | def gauss(m,v,x): 44 | """ Evaluate Gaussian in d-dimensions with independent 45 | mean m and variance v at the points in (the rows of) x. 46 | http://en.wikipedia.org/wiki/Multivariate_normal_distribution """ 47 | 48 | if len(x.shape)==1: 49 | n,d = 1,x.shape[0] 50 | else: 51 | n,d = x.shape 52 | 53 | # covariance matrix, subtract mean 54 | S = diag(1/v) 55 | x = x-m 56 | # product of probabilities 57 | y = exp(-0.5*diag(dot(x,dot(S,x.T)))) 58 | 59 | # normalize and return 60 | return y * (2*pi)**(-d/2.0) / ( sqrt(prod(v)) + 1e-6) 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /PCV/classifiers/knn.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | 3 | class KnnClassifier(object): 4 | 5 | def __init__(self,labels,samples): 6 | """ Initialize classifier with training data. """ 7 | 8 | self.labels = labels 9 | self.samples = samples 10 | 11 | def classify(self,point,k=3): 12 | """ Classify a point against k nearest 13 | in the training data, return label. """ 14 | 15 | # compute distance to all training points 16 | dist = array([L2dist(point,s) for s in self.samples]) 17 | 18 | # sort them 19 | ndx = dist.argsort() 20 | 21 | # use dictionary to store the k nearest 22 | votes = {} 23 | for i in range(k): 24 | label = self.labels[ndx[i]] 25 | votes.setdefault(label,0) 26 | votes[label] += 1 27 | 28 | return max(votes, key=lambda x: votes.get(x)) 29 | 30 | 31 | def L2dist(p1,p2): 32 | return sqrt( sum( (p1-p2)**2) ) 33 | 34 | def L1dist(v1,v2): 35 | return sum(abs(v1-v2)) -------------------------------------------------------------------------------- /PCV/clustering/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/clustering/__init__.pyc -------------------------------------------------------------------------------- /PCV/clustering/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/clustering/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/clustering/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/clustering/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/clustering/hcluster.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | from itertools import combinations 3 | 4 | 5 | class ClusterNode(object): 6 | def __init__(self,vec,left,right,distance=0.0,count=1): 7 | self.left = left 8 | self.right = right 9 | self.vec = vec 10 | self.distance = distance 11 | self.count = count # only used for weighted average 12 | 13 | def extract_clusters(self,dist): 14 | """ Extract list of sub-tree clusters from 15 | hcluster tree with distance1: 99 | closest = float('Inf') 100 | 101 | # loop through every pair looking for the smallest distance 102 | for ni,nj in combinations(node,2): 103 | if (ni,nj) not in distances: 104 | distances[ni,nj] = distfcn(ni.vec,nj.vec) 105 | 106 | d = distances[ni,nj] 107 | if d=0) & (lt 0) 23 | 24 | return (1-alpha)*im2 + alpha*im1_t 25 | 26 | 27 | def combine_images(im1,im2,alpha): 28 | """ Blend two images with weights as in alpha. """ 29 | return (1-alpha)*im1 + alpha*im2 30 | 31 | 32 | def alpha_for_triangle(points,m,n): 33 | """ Creates alpha map of size (m,n) 34 | for a triangle with corners defined by points 35 | (given in normalized homogeneous coordinates). """ 36 | 37 | alpha = zeros((m,n)) 38 | for i in range(min(points[0]),max(points[0])): 39 | for j in range(min(points[1]),max(points[1])): 40 | x = linalg.solve(points,[i,j,1]) 41 | if min(x) > 0: #all coefficients positive 42 | alpha[i,j] = 1 43 | return alpha 44 | 45 | 46 | def triangulate_points(x,y): 47 | """ Delaunay triangulation of 2D points. """ 48 | 49 | centers,edges,tri,neighbors = md.delaunay(x,y) 50 | return tri 51 | 52 | 53 | def plot_mesh(x,y,tri): 54 | """ Plot triangles. """ 55 | 56 | for t in tri: 57 | t_ext = [t[0], t[1], t[2], t[0]] # add first point to end 58 | plot(x[t_ext],y[t_ext],'r') 59 | 60 | 61 | def pw_affine(fromim,toim,fp,tp,tri): 62 | """ Warp triangular patches from an image. 63 | fromim = image to warp 64 | toim = destination image 65 | fp = from points in hom. coordinates 66 | tp = to points in hom. coordinates 67 | tri = triangulation. """ 68 | 69 | im = toim.copy() 70 | 71 | # check if image is grayscale or color 72 | is_color = len(fromim.shape) == 3 73 | 74 | # create image to warp to (needed if iterate colors) 75 | im_t = zeros(im.shape, 'uint8') 76 | 77 | for t in tri: 78 | # compute affine transformation 79 | H = homography.Haffine_from_points(tp[:,t],fp[:,t]) 80 | 81 | if is_color: 82 | for col in range(fromim.shape[2]): 83 | im_t[:,:,col] = ndimage.affine_transform( 84 | fromim[:,:,col],H[:2,:2],(H[0,2],H[1,2]),im.shape[:2]) 85 | else: 86 | im_t = ndimage.affine_transform( 87 | fromim,H[:2,:2],(H[0,2],H[1,2]),im.shape[:2]) 88 | 89 | # alpha for triangle 90 | alpha = alpha_for_triangle(tp[:,t],im.shape[0],im.shape[1]) 91 | 92 | # add triangle to image 93 | im[alpha>0] = im_t[alpha>0] 94 | 95 | return im 96 | 97 | 98 | def panorama(H,fromim,toim,padding=2400,delta=2400): 99 | """ Create horizontal panorama by blending two images 100 | using a homography H (preferably estimated using RANSAC). 101 | The result is an image with the same height as toim. 'padding' 102 | specifies number of fill pixels and 'delta' additional translation. """ 103 | 104 | # check if images are grayscale or color 105 | is_color = len(fromim.shape) == 3 106 | 107 | # homography transformation for geometric_transform() 108 | def transf(p): 109 | p2 = dot(H,[p[0],p[1],1]) 110 | return (p2[0]/p2[2],p2[1]/p2[2]) 111 | 112 | if H[1,2]<0: # fromim is to the right 113 | print ('warp - right') 114 | # transform fromim 115 | if is_color: 116 | # pad the destination image with zeros to the right 117 | toim_t = hstack((toim,zeros((toim.shape[0],padding,3)))) 118 | fromim_t = zeros((toim.shape[0],toim.shape[1]+padding,toim.shape[2])) 119 | for col in range(3): 120 | fromim_t[:,:,col] = ndimage.geometric_transform(fromim[:,:,col], 121 | transf,(toim.shape[0],toim.shape[1]+padding)) 122 | else: 123 | # pad the destination image with zeros to the right 124 | toim_t = hstack((toim,zeros((toim.shape[0],padding)))) 125 | fromim_t = ndimage.geometric_transform(fromim,transf, 126 | (toim.shape[0],toim.shape[1]+padding)) 127 | else: 128 | print ('warp - left') 129 | # add translation to compensate for padding to the left 130 | H_delta = array([[1,0,0],[0,1,-delta],[0,0,1]]) 131 | H = dot(H,H_delta) 132 | # transform fromim 133 | if is_color: 134 | # pad the destination image with zeros to the left 135 | toim_t = hstack((zeros((toim.shape[0],padding,3)),toim)) 136 | fromim_t = zeros((toim.shape[0],toim.shape[1]+padding,toim.shape[2])) 137 | for col in range(3): 138 | fromim_t[:,:,col] = ndimage.geometric_transform(fromim[:,:,col], 139 | transf,(toim.shape[0],toim.shape[1]+padding)) 140 | else: 141 | # pad the destination image with zeros to the left 142 | toim_t = hstack((zeros((toim.shape[0],padding)),toim)) 143 | fromim_t = ndimage.geometric_transform(fromim, 144 | transf,(toim.shape[0],toim.shape[1]+padding)) 145 | 146 | # blend and return (put fromim above toim) 147 | if is_color: 148 | # all non black pixels 149 | alpha = ((fromim_t[:,:,0] * fromim_t[:,:,1] * fromim_t[:,:,2] ) > 0) 150 | for col in range(3): 151 | toim_t[:,:,col] = fromim_t[:,:,col]*alpha + toim_t[:,:,col]*(1-alpha) 152 | else: 153 | alpha = (fromim_t > 0) 154 | toim_t = fromim_t*alpha + toim_t*(1-alpha) 155 | 156 | return toim_t 157 | 158 | -------------------------------------------------------------------------------- /PCV/imagesearch/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/__init__.pyc -------------------------------------------------------------------------------- /PCV/imagesearch/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/imagesearch/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/imagesearch/__pycache__/imagesearch.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/__pycache__/imagesearch.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/imagesearch/__pycache__/vocabulary.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/__pycache__/vocabulary.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/imagesearch/imagesearch.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | import pickle 3 | import sqlite3 4 | from functools import cmp_to_key 5 | import operator 6 | 7 | class Indexer(object): 8 | 9 | def __init__(self,db,voc): 10 | """ Initialize with the name of the database 11 | and a vocabulary object. """ 12 | 13 | self.con = sqlite3.connect(db) 14 | self.voc = voc 15 | 16 | def __del__(self): 17 | self.con.close() 18 | 19 | def db_commit(self): 20 | self.con.commit() 21 | 22 | def get_id(self,imname): 23 | """ Get an entry id and add if not present. """ 24 | 25 | cur = self.con.execute( 26 | "select rowid from imlist where filename='%s'" % imname) 27 | res=cur.fetchone() 28 | if res==None: 29 | cur = self.con.execute( 30 | "insert into imlist(filename) values ('%s')" % imname) 31 | return cur.lastrowid 32 | else: 33 | return res[0] 34 | 35 | def is_indexed(self,imname): 36 | """ Returns True if imname has been indexed. """ 37 | 38 | im = self.con.execute("select rowid from imlist where filename='%s'" % imname).fetchone() 39 | return im != None 40 | 41 | def add_to_index(self,imname,descr): 42 | """ Take an image with feature descriptors, 43 | project on vocabulary and add to database. """ 44 | 45 | if self.is_indexed(imname): return 46 | print ('indexing', imname) 47 | 48 | # get the imid 49 | imid = self.get_id(imname) 50 | 51 | # get the words 52 | imwords = self.voc.project(descr) 53 | nbr_words = imwords.shape[0] 54 | 55 | # link each word to image 56 | for i in range(nbr_words): 57 | word = imwords[i] 58 | # wordid is the word number itself 59 | self.con.execute("insert into imwords(imid,wordid,vocname) values (?,?,?)", (imid,word,self.voc.name)) 60 | 61 | # store word histogram for image 62 | # use pickle to encode NumPy arrays as strings 63 | self.con.execute("insert into imhistograms(imid,histogram,vocname) values (?,?,?)", (imid,pickle.dumps(imwords),self.voc.name)) 64 | 65 | def create_tables(self): 66 | """ Create the database tables. """ 67 | 68 | self.con.execute('create table imlist(filename)') 69 | self.con.execute('create table imwords(imid,wordid,vocname)') 70 | self.con.execute('create table imhistograms(imid,histogram,vocname)') 71 | self.con.execute('create index im_idx on imlist(filename)') 72 | self.con.execute('create index wordid_idx on imwords(wordid)') 73 | self.con.execute('create index imid_idx on imwords(imid)') 74 | self.con.execute('create index imidhist_idx on imhistograms(imid)') 75 | self.db_commit() 76 | 77 | 78 | class Searcher(object): 79 | 80 | def __init__(self,db,voc): 81 | """ Initialize with the name of the database. """ 82 | self.con = sqlite3.connect(db) 83 | self.voc = voc 84 | 85 | def __del__(self): 86 | self.con.close() 87 | 88 | def get_imhistogram(self,imname): 89 | """ Return the word histogram for an image. """ 90 | 91 | im_id = self.con.execute( 92 | "select rowid from imlist where filename='%s'" % imname).fetchone() 93 | s = self.con.execute( 94 | "select histogram from imhistograms where rowid='%d'" % im_id).fetchone() 95 | 96 | # use pickle to decode NumPy arrays from string 97 | return pickle.loads(s[0]) 98 | 99 | def candidates_from_word(self,imword): 100 | """ Get list of images containing imword. """ 101 | 102 | im_ids = self.con.execute( 103 | "select distinct imid from imwords where wordid=%d" % imword).fetchall() 104 | return [i[0] for i in im_ids] 105 | 106 | def candidates_from_histogram(self,imwords): 107 | """ Get list of images with similar words. """ 108 | 109 | # get the word ids 110 | words = imwords.nonzero()[0] 111 | 112 | # find candidates 113 | candidates = [] 114 | for word in words: 115 | c = self.candidates_from_word(word) 116 | candidates+=c 117 | 118 | # take all unique words and reverse sort on occurrence 119 | tmp = [(w,candidates.count(w)) for w in set(candidates)] 120 | tmp.sort(key=cmp_to_key(lambda x,y:operator.gt(x[1],y[1]))) 121 | tmp.reverse() 122 | 123 | # return sorted list, best matches first 124 | return [w[0] for w in tmp] 125 | 126 | def query(self,imname): 127 | """ Find a list of matching images for imname. """ 128 | 129 | h = self.get_imhistogram(imname) 130 | candidates = self.candidates_from_histogram(h) 131 | 132 | matchscores = [] 133 | for imid in candidates: 134 | # get the name 135 | cand_name = self.con.execute( 136 | "select filename from imlist where rowid=%d" % imid).fetchone() 137 | cand_h = self.get_imhistogram(cand_name) 138 | cand_dist = sqrt( sum( self.voc.idf*(h-cand_h)**2 ) ) 139 | matchscores.append( (cand_dist,imid) ) 140 | 141 | # return a sorted list of distances and database ids 142 | matchscores.sort() 143 | return matchscores 144 | 145 | def get_filename(self,imid): 146 | """ Return the filename for an image id. """ 147 | 148 | s = self.con.execute( 149 | "select filename from imlist where rowid='%d'" % imid).fetchone() 150 | return s[0] 151 | 152 | 153 | def tf_idf_dist(voc,v1,v2): 154 | 155 | v1 /= sum(v1) 156 | v2 /= sum(v2) 157 | 158 | return sqrt( sum( voc.idf*(v1-v2)**2 ) ) 159 | 160 | 161 | def compute_ukbench_score(src,imlist): 162 | """ Returns the average number of correct 163 | images on the top four results of queries. """ 164 | 165 | nbr_images = len(imlist) 166 | pos = zeros((nbr_images,4)) 167 | # get first four results for each image 168 | for i in range(nbr_images): 169 | pos[i] = [w[1]-1 for w in src.query(imlist[i])[:4]] 170 | 171 | # compute score and return average 172 | score = array([ (pos[i]//4)==(i//4) for i in range(nbr_images)])*1.0 173 | return sum(score) / (nbr_images) 174 | 175 | 176 | # import PIL and pylab for plotting 177 | from PIL import Image 178 | from pylab import * 179 | 180 | def plot_results(src,res): 181 | """ Show images in result list 'res'. """ 182 | 183 | figure() 184 | nbr_results = len(res) 185 | for i in range(nbr_results): 186 | imname = src.get_filename(res[i]) 187 | subplot(1,nbr_results,i+1) 188 | imshow(array(Image.open(imname))) 189 | axis('off') 190 | show() -------------------------------------------------------------------------------- /PCV/imagesearch/imagesearch.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/imagesearch.pyc -------------------------------------------------------------------------------- /PCV/imagesearch/vocabulary.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | from scipy.cluster.vq import * 3 | 4 | from PCV.localdescriptors import sift 5 | 6 | 7 | class Vocabulary(object): 8 | 9 | def __init__(self,name): 10 | self.name = name 11 | self.voc = [] 12 | self.idf = [] 13 | self.trainingdata = [] 14 | self.nbr_words = 0 15 | 16 | def train(self,featurefiles,k=100,subsampling=10): 17 | """ Train a vocabulary from features in files listed 18 | in featurefiles using k-means with k number of words. 19 | Subsampling of training data can be used for speedup. """ 20 | 21 | nbr_images = len(featurefiles) 22 | # read the features from file 23 | descr = [] 24 | descr.append(sift.read_features_from_file(featurefiles[0])[1]) 25 | descriptors = descr[0] #stack all features for k-means 26 | for i in arange(1,nbr_images): 27 | descr.append(sift.read_features_from_file(featurefiles[i])[1]) 28 | descriptors = vstack((descriptors,descr[i])) 29 | 30 | # k-means: last number determines number of runs 31 | self.voc,distortion = kmeans(descriptors[::subsampling,:],k,1) 32 | self.nbr_words = self.voc.shape[0] 33 | 34 | # go through all training images and project on vocabulary 35 | imwords = zeros((nbr_images,self.nbr_words)) 36 | for i in range( nbr_images ): 37 | imwords[i] = self.project(descr[i]) 38 | 39 | nbr_occurences = sum( (imwords > 0)*1 ,axis=0) 40 | 41 | self.idf = log( (1.0*nbr_images) / (1.0*nbr_occurences+1) ) 42 | self.trainingdata = featurefiles 43 | 44 | def project(self,descriptors): 45 | """ Project descriptors on the vocabulary 46 | to create a histogram of words. """ 47 | 48 | # histogram of image words 49 | imhist = zeros((self.nbr_words)) 50 | words,distance = vq(descriptors,self.voc) 51 | for w in words: 52 | imhist[w] += 1 53 | 54 | return imhist 55 | 56 | def get_words(self,descriptors): 57 | """ Convert descriptors to words. """ 58 | return vq(descriptors,self.voc)[0] 59 | -------------------------------------------------------------------------------- /PCV/imagesearch/vocabulary.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/imagesearch/vocabulary.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__init__.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__pycache__/dsift.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__pycache__/dsift.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__pycache__/dsift.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__pycache__/dsift.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__pycache__/sift.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__pycache__/sift.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/__pycache__/sift.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/__pycache__/sift.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/dsift.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from numpy import * 3 | import os 4 | 5 | from PCV.localdescriptors import sift 6 | 7 | 8 | def process_image_dsift(imagename,resultname,size=20,steps=10,force_orientation=False,resize=None): 9 | """ Process an image with densely sampled SIFT descriptors 10 | and save the results in a file. Optional input: size of features, 11 | steps between locations, forcing computation of descriptor orientation 12 | (False means all are oriented upwards), tuple for resizing the image.""" 13 | 14 | im = Image.open(imagename).convert('L') 15 | if resize!=None: 16 | im = im.resize(resize) 17 | m,n = im.size 18 | 19 | if imagename[-3:] != 'pgm': 20 | #create a pgm file 21 | im.save('tmp.pgm') 22 | imagename = 'tmp.pgm' 23 | 24 | # create frames and save to temporary file 25 | scale = size/3.0 26 | x,y = meshgrid(range(steps,m,steps),range(steps,n,steps)) 27 | xx,yy = x.flatten(),y.flatten() 28 | frame = array([xx,yy,scale*ones(xx.shape[0]),zeros(xx.shape[0])]) 29 | savetxt('tmp.frame',frame.T,fmt='%03.3f') 30 | 31 | path = os.path.abspath(os.path.join(os.path.dirname("__file__"),os.path.pardir)) 32 | path = path + "\\python3-ch08\\win32vlfeat\\sift.exe " 33 | if force_orientation: 34 | cmmd = str(path+imagename+" --output="+resultname+ 35 | " --read-frames=tmp.frame --orientations") 36 | else: 37 | cmmd = str(path+imagename+" --output="+resultname+ 38 | " --read-frames=tmp.frame") 39 | os.system(cmmd) 40 | print ('processed', imagename, 'to', resultname) 41 | 42 | -------------------------------------------------------------------------------- /PCV/localdescriptors/harris.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | from numpy import * 3 | from scipy.ndimage import filters 4 | 5 | 6 | def compute_harris_response(im,sigma=3): 7 | """ Compute the Harris corner detector response function 8 | for each pixel in a graylevel image. """ 9 | 10 | # derivatives 11 | imx = zeros(im.shape) 12 | filters.gaussian_filter(im, (sigma,sigma), (0,1), imx) 13 | imy = zeros(im.shape) 14 | filters.gaussian_filter(im, (sigma,sigma), (1,0), imy) 15 | 16 | # compute components of the Harris matrix 17 | Wxx = filters.gaussian_filter(imx*imx,sigma) 18 | Wxy = filters.gaussian_filter(imx*imy,sigma) 19 | Wyy = filters.gaussian_filter(imy*imy,sigma) 20 | 21 | # determinant and trace 22 | Wdet = Wxx*Wyy - Wxy**2 23 | Wtr = Wxx + Wyy 24 | 25 | return Wdet / Wtr 26 | 27 | 28 | def get_harris_points(harrisim,min_dist=10,threshold=0.1): 29 | """ Return corners from a Harris response image 30 | min_dist is the minimum number of pixels separating 31 | corners and image boundary. """ 32 | 33 | # find top corner candidates above a threshold 34 | corner_threshold = harrisim.max() * threshold 35 | harrisim_t = (harrisim > corner_threshold) * 1 36 | 37 | # get coordinates of candidates 38 | coords = array(harrisim_t.nonzero()).T 39 | 40 | # ...and their values 41 | candidate_values = [harrisim[c[0],c[1]] for c in coords] 42 | 43 | # sort candidates (reverse to get descending order) 44 | index = argsort(candidate_values)[::-1] 45 | 46 | # store allowed point locations in array 47 | allowed_locations = zeros(harrisim.shape) 48 | allowed_locations[min_dist:-min_dist,min_dist:-min_dist] = 1 49 | 50 | # select the best points taking min_distance into account 51 | filtered_coords = [] 52 | for i in index: 53 | if allowed_locations[coords[i,0],coords[i,1]] == 1: 54 | filtered_coords.append(coords[i]) 55 | allowed_locations[(coords[i,0]-min_dist):(coords[i,0]+min_dist), 56 | (coords[i,1]-min_dist):(coords[i,1]+min_dist)] = 0 57 | 58 | return filtered_coords 59 | 60 | 61 | def plot_harris_points(image,filtered_coords): 62 | """ Plots corners found in image. """ 63 | 64 | figure() 65 | gray() 66 | imshow(image) 67 | plot([p[1] for p in filtered_coords], 68 | [p[0] for p in filtered_coords],'*') 69 | axis('off') 70 | show() 71 | 72 | 73 | def get_descriptors(image,filtered_coords,wid=5): 74 | """ For each point return pixel values around the point 75 | using a neighbourhood of width 2*wid+1. (Assume points are 76 | extracted with min_distance > wid). """ 77 | 78 | desc = [] 79 | for coords in filtered_coords: 80 | patch = image[coords[0]-wid:coords[0]+wid+1, 81 | coords[1]-wid:coords[1]+wid+1].flatten() 82 | desc.append(patch) 83 | 84 | return desc 85 | 86 | 87 | def match(desc1,desc2,threshold=0.5): 88 | """ For each corner point descriptor in the first image, 89 | select its match to second image using 90 | normalized cross correlation. """ 91 | 92 | n = len(desc1[0]) 93 | 94 | # pair-wise distances 95 | d = -ones((len(desc1),len(desc2))) 96 | for i in range(len(desc1)): 97 | for j in range(len(desc2)): 98 | d1 = (desc1[i] - mean(desc1[i])) / std(desc1[i]) 99 | d2 = (desc2[j] - mean(desc2[j])) / std(desc2[j]) 100 | ncc_value = sum(d1 * d2) / (n-1) 101 | if ncc_value > threshold: 102 | d[i,j] = ncc_value 103 | 104 | ndx = argsort(-d) 105 | matchscores = ndx[:,0] 106 | 107 | return matchscores 108 | 109 | 110 | def match_twosided(desc1,desc2,threshold=0.5): 111 | """ Two-sided symmetric version of match(). """ 112 | 113 | matches_12 = match(desc1,desc2,threshold) 114 | matches_21 = match(desc2,desc1,threshold) 115 | 116 | ndx_12 = where(matches_12 >= 0)[0] 117 | 118 | # remove matches that are not symmetric 119 | for n in ndx_12: 120 | if matches_21[matches_12[n]] != n: 121 | matches_12[n] = -1 122 | 123 | return matches_12 124 | 125 | 126 | def appendimages(im1,im2): 127 | """ Return a new image that appends the two images side-by-side. """ 128 | 129 | # select the image with the fewest rows and fill in enough empty rows 130 | rows1 = im1.shape[0] 131 | rows2 = im2.shape[0] 132 | 133 | if rows1 < rows2: 134 | im1 = concatenate((im1,zeros((rows2-rows1,im1.shape[1]))),axis=0) 135 | elif rows1 > rows2: 136 | im2 = concatenate((im2,zeros((rows1-rows2,im2.shape[1]))),axis=0) 137 | # if none of these cases they are equal, no filling needed. 138 | 139 | return concatenate((im1,im2), axis=1) 140 | 141 | 142 | def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True): 143 | """ Show a figure with lines joining the accepted matches 144 | input: im1,im2 (images as arrays), locs1,locs2 (feature locations), 145 | matchscores (as output from 'match()'), 146 | show_below (if images should be shown below matches). """ 147 | 148 | im3 = appendimages(im1,im2) 149 | if show_below: 150 | im3 = vstack((im3,im3)) 151 | 152 | imshow(im3) 153 | 154 | cols1 = im1.shape[1] 155 | for i,m in enumerate(matchscores): 156 | if m>0: 157 | plot([locs1[i][1],locs2[m][1]+cols1],[locs1[i][0],locs2[m][0]],'c') 158 | axis('off') 159 | -------------------------------------------------------------------------------- /PCV/localdescriptors/sift.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import os 3 | from numpy import * 4 | from pylab import * 5 | 6 | 7 | def process_image(imagename,resultname,params="--edge-thresh 10 --peak-thresh 5"): 8 | """ process an image and save the results in a file""" 9 | path = os.path.abspath(os.path.join(os.path.dirname("__file__"),os.path.pardir)) 10 | path = path + "\\ch07\\win32vlfeat\\sift.exe " 11 | print (path) 12 | if imagename[-3:] != 'pgm': 13 | #create a pgm file 14 | im = Image.open(imagename).convert('L') 15 | im.save('tmp.pgm') 16 | imagename = 'tmp.pgm ' 17 | cmmd = str(path+imagename+"--output="+resultname+ 18 | " "+params) 19 | os.system(cmmd) 20 | print ('processed' + imagename + 'to' + resultname) 21 | 22 | 23 | def read_features_from_file(filename): 24 | """ read feature properties and return in matrix form""" 25 | f = loadtxt(filename) 26 | return f[:,:4],f[:,4:] # feature locations, descriptors 27 | 28 | 29 | def write_features_to_file(filename,locs,desc): 30 | """ save feature location and descriptor to file""" 31 | savetxt(filename,hstack((locs,desc))) 32 | 33 | 34 | def plot_features(im,locs,circle=False): 35 | """ show image with features. input: im (image as array), 36 | locs (row, col, scale, orientation of each feature) """ 37 | 38 | def draw_circle(c,r): 39 | t = arange(0,1.01,.01)*2*pi 40 | x = r*cos(t) + c[0] 41 | y = r*sin(t) + c[1] 42 | plot(x,y,'b',linewidth=2) 43 | 44 | imshow(im) 45 | if circle: 46 | [draw_circle([p[0],p[1]],p[2]) for p in locs] 47 | else: 48 | plot(locs[:,0],locs[:,1],'ob') 49 | axis('off') 50 | 51 | 52 | def match(desc1,desc2): 53 | """ for each descriptor in the first image, 54 | select its match in the second image. 55 | input: desc1 (descriptors for the first image), 56 | desc2 (same for second image). """ 57 | 58 | desc1 = array([d/linalg.norm(d) for d in desc1]) 59 | desc2 = array([d/linalg.norm(d) for d in desc2]) 60 | 61 | dist_ratio = 0.6 62 | desc1_size = desc1.shape 63 | 64 | matchscores = zeros((desc1_size[0],1)) 65 | desc2t = desc2.T #precompute matrix transpose 66 | for i in range(desc1_size[0]): 67 | dotprods = dot(desc1[i,:],desc2t) #vector of dot products 68 | dotprods = 0.9999*dotprods 69 | #inverse cosine and sort, return index for features in second image 70 | indx = argsort(arccos(dotprods)) 71 | 72 | #check if nearest neighbor has angle less than dist_ratio times 2nd 73 | if arccos(dotprods)[indx[0]] < dist_ratio * arccos(dotprods)[indx[1]]: 74 | matchscores[i] = int(indx[0]) 75 | 76 | return matchscores 77 | 78 | 79 | def appendimages(im1,im2): 80 | """ return a new image that appends the two images side-by-side.""" 81 | 82 | #select the image with the fewest rows and fill in enough empty rows 83 | rows1 = im1.shape[0] 84 | rows2 = im2.shape[0] 85 | 86 | if rows1 < rows2: 87 | im1 = concatenate((im1,zeros((rows2-rows1,im1.shape[1]))), axis=0) 88 | elif rows1 > rows2: 89 | im2 = concatenate((im2,zeros((rows1-rows2,im2.shape[1]))), axis=0) 90 | #if none of these cases they are equal, no filling needed. 91 | 92 | return concatenate((im1,im2), axis=1) 93 | 94 | 95 | def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True): 96 | """ show a figure with lines joining the accepted matches 97 | input: im1,im2 (images as arrays), locs1,locs2 (location of features), 98 | matchscores (as output from 'match'), show_below (if images should be shown below). """ 99 | 100 | im3 = appendimages(im1,im2) 101 | if show_below: 102 | im3 = vstack((im3,im3)) 103 | 104 | # show image 105 | imshow(im3) 106 | 107 | # draw lines for matches 108 | cols1 = im1.shape[1] 109 | for i in range(len(matchscores)): 110 | if matchscores[i] > 0: 111 | plot([locs1[i,0], locs2[matchscores[i,0],0]+cols1], [locs1[i,1], locs2[matchscores[i,0],1]], 'c') 112 | axis('off') 113 | 114 | 115 | def match_twosided(desc1,desc2): 116 | """ two-sided symmetric version of match(). """ 117 | 118 | matches_12 = match(desc1,desc2) 119 | matches_21 = match(desc2,desc1) 120 | 121 | ndx_12 = matches_12.nonzero()[0] 122 | 123 | #remove matches that are not symmetric 124 | for n in ndx_12: 125 | if matches_21[int(matches_12[n])] != n: 126 | matches_12[n] = 0 127 | 128 | return matches_12 129 | 130 | 131 | if __name__ == "__main__": 132 | 133 | process_image('box.pgm','tmp.sift') 134 | l,d = read_features_from_file('tmp.sift') 135 | 136 | im = array(Image.open('box.pgm')) 137 | figure() 138 | plot_features(im,l,True) 139 | gray() 140 | 141 | process_image('scene.pgm','tmp2.sift') 142 | l2,d2 = read_features_from_file('tmp2.sift') 143 | im2 = array(Image.open('scene.pgm')) 144 | 145 | m = match_twosided(d,d2) 146 | figure() 147 | plot_matches(im,im2,l,l2,m) 148 | 149 | gray() 150 | show() 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /PCV/localdescriptors/sift.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/sift.pyc -------------------------------------------------------------------------------- /PCV/localdescriptors/tmp.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/localdescriptors/tmp.pgm -------------------------------------------------------------------------------- /PCV/tools/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/__init__.pyc -------------------------------------------------------------------------------- /PCV/tools/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/tools/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/tools/__pycache__/imtools.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/__pycache__/imtools.cpython-36.pyc -------------------------------------------------------------------------------- /PCV/tools/__pycache__/imtools.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/__pycache__/imtools.cpython-37.pyc -------------------------------------------------------------------------------- /PCV/tools/graphcut.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | from numpy import * 3 | 4 | from pygraph.classes.digraph import digraph 5 | from pygraph.algorithms.minmax import maximum_flow 6 | 7 | from PCV.classifiers import bayes 8 | 9 | """ 10 | Graph Cut image segmentation using max-flow/min-cut. 11 | """ 12 | 13 | def build_bayes_graph(im,labels,sigma=1e2,kappa=1): 14 | """ Build a graph from 4-neighborhood of pixels. 15 | Foreground and background is determined from 16 | labels (1 for foreground, -1 for background, 0 otherwise) 17 | and is modeled with naive Bayes classifiers.""" 18 | 19 | m,n = im.shape[:2] 20 | 21 | # RGB vector version (one pixel per row) 22 | vim = im.reshape((-1,3)) 23 | 24 | # RGB for foreground and background 25 | foreground = im[labels==1].reshape((-1,3)) 26 | background = im[labels==-1].reshape((-1,3)) 27 | train_data = [foreground,background] 28 | 29 | # train naive Bayes classifier 30 | bc = bayes.BayesClassifier() 31 | bc.train(train_data) 32 | 33 | # get probabilities for all pixels 34 | bc_lables,prob = bc.classify(vim) 35 | prob_fg = prob[0] 36 | prob_bg = prob[1] 37 | 38 | # create graph with m*n+2 nodes 39 | gr = digraph() 40 | gr.add_nodes(range(m*n+2)) 41 | 42 | source = m*n # second to last is source 43 | sink = m*n+1 # last node is sink 44 | 45 | # normalize 46 | for i in range(vim.shape[0]): 47 | vim[i] = vim[i] / (linalg.norm(vim[i]) + 1e-9) 48 | 49 | # go through all nodes and add edges 50 | for i in range(m*n): 51 | # add edge from source 52 | gr.add_edge((source,i), wt=(prob_fg[i]/(prob_fg[i]+prob_bg[i]))) 53 | 54 | # add edge to sink 55 | gr.add_edge((i,sink), wt=(prob_bg[i]/(prob_fg[i]+prob_bg[i]))) 56 | 57 | # add edges to neighbors 58 | if i%n != 0: # left exists 59 | edge_wt = kappa*exp(-1.0*sum((vim[i]-vim[i-1])**2)/sigma) 60 | gr.add_edge((i,i-1), wt=edge_wt) 61 | if (i+1)%n != 0: # right exists 62 | edge_wt = kappa*exp(-1.0*sum((vim[i]-vim[i+1])**2)/sigma) 63 | gr.add_edge((i,i+1), wt=edge_wt) 64 | if i//n != 0: # up exists 65 | edge_wt = kappa*exp(-1.0*sum((vim[i]-vim[i-n])**2)/sigma) 66 | gr.add_edge((i,i-n), wt=edge_wt) 67 | if i//n != m-1: # down exists 68 | edge_wt = kappa*exp(-1.0*sum((vim[i]-vim[i+n])**2)/sigma) 69 | gr.add_edge((i,i+n), wt=edge_wt) 70 | 71 | return gr 72 | 73 | 74 | def cut_graph(gr,imsize): 75 | """ Solve max flow of graph gr and return binary 76 | labels of the resulting segmentation.""" 77 | 78 | m,n = imsize 79 | source = m*n # second to last is source 80 | sink = m*n+1 # last is sink 81 | 82 | # cut the graph 83 | flows,cuts = maximum_flow(gr,source,sink) 84 | 85 | # convert graph to image with labels 86 | res = zeros(m*n) 87 | for pos,label in cuts.items()[:-2]: #don't add source/sink 88 | res[pos] = label 89 | 90 | return res.reshape((m,n)) 91 | 92 | 93 | def save_as_pdf(gr,filename,show_weights=False): 94 | 95 | from pygraph.readwrite.dot import write 96 | import gv 97 | dot = write(gr, weighted=show_weights) 98 | gvv = gv.readstring(dot) 99 | gv.layout(gvv,'fdp') 100 | gv.render(gvv,'pdf',filename) 101 | 102 | 103 | def show_labeling(im,labels): 104 | """ Show image with foreground and background areas. 105 | labels = 1 for foreground, -1 for background, 0 otherwise.""" 106 | 107 | imshow(im) 108 | contour(labels,[-0.5,0.5]) 109 | contourf(labels,[-1,-0.5],colors='b',alpha=0.25) 110 | contourf(labels,[0.5,1],colors='r',alpha=0.25) 111 | #axis('off') 112 | xticks([]) 113 | yticks([]) 114 | 115 | -------------------------------------------------------------------------------- /PCV/tools/imregistration.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from xml.dom import minidom 3 | from numpy import * 4 | from pylab import * 5 | 6 | from scipy import ndimage, linalg 7 | from scipy.misc import imsave 8 | import os 9 | 10 | def read_points_from_xml(xmlFileName): 11 | """ Reads control points for face alignment. """ 12 | 13 | xmldoc = minidom.parse(xmlFileName) 14 | facelist = xmldoc.getElementsByTagName('face') 15 | faces = {} 16 | for xmlFace in facelist: 17 | fileName = xmlFace.attributes['file'].value 18 | xf = int(xmlFace.attributes['xf'].value) 19 | yf = int(xmlFace.attributes['yf'].value) 20 | xs = int(xmlFace.attributes['xs'].value) 21 | ys = int(xmlFace.attributes['ys'].value) 22 | xm = int(xmlFace.attributes['xm'].value) 23 | ym = int(xmlFace.attributes['ym'].value) 24 | faces[fileName] = array([xf, yf, xs, ys, xm, ym]) 25 | return faces 26 | 27 | 28 | def write_points_to_xml(faces, xmlFileName): 29 | xmldoc = minidom.Document() 30 | xmlFaces = xmldoc.createElement("faces") 31 | 32 | keys = faces.keys() 33 | for k in keys: 34 | xmlFace = xmldoc.createElement("face") 35 | xmlFace.setAttribute("file", k) 36 | xmlFace.setAttribute("xf", "%d" % faces[k][0]) 37 | xmlFace.setAttribute("yf", "%d" % faces[k][1]) 38 | xmlFace.setAttribute("xs", "%d" % faces[k][2]) 39 | xmlFace.setAttribute("ys", "%d" % faces[k][3]) 40 | xmlFace.setAttribute("xm", "%d" % faces[k][4]) 41 | xmlFace.setAttribute("ym", "%d" % faces[k][5]) 42 | xmlFaces.appendChild(xmlFace) 43 | 44 | xmldoc.appendChild(xmlFaces) 45 | 46 | fp = open(xmlFileName, "w") 47 | fp.write(xmldoc.toprettyxml(encoding='utf-8')) 48 | fp.close() 49 | 50 | 51 | def compute_rigid_transform(refpoints,points): 52 | """ Computes rotation, scale and translation for 53 | aligning points to refpoints. """ 54 | 55 | A = array([ [points[0], -points[1], 1, 0], 56 | [points[1], points[0], 0, 1], 57 | [points[2], -points[3], 1, 0], 58 | [points[3], points[2], 0, 1], 59 | [points[4], -points[5], 1, 0], 60 | [points[5], points[4], 0, 1]]) 61 | 62 | y = array([ refpoints[0], 63 | refpoints[1], 64 | refpoints[2], 65 | refpoints[3], 66 | refpoints[4], 67 | refpoints[5]]) 68 | 69 | # least sq solution to mimimize ||Ax - y|| 70 | a,b,tx,ty = linalg.lstsq(A,y)[0] 71 | R = array([[a, -b], [b, a]]) # rotation matrix incl scale 72 | 73 | return R,tx,ty 74 | 75 | 76 | def rigid_alignment(faces,path,plotflag=False): 77 | """ Align images rigidly and save as new images. 78 | path determines where the aligned images are saved 79 | set plotflag=True to plot the images. """ 80 | 81 | # take the points in the first image as reference points 82 | refpoints = faces.values()[0] 83 | 84 | # warp each image using affine transform 85 | for face in faces: 86 | points = faces[face] 87 | 88 | R,tx,ty = compute_rigid_transform(refpoints, points) 89 | T = array([[R[1][1], R[1][0]], [R[0][1], R[0][0]]]) 90 | 91 | im = array(Image.open(os.path.join(path,face))) 92 | im2 = zeros(im.shape, 'uint8') 93 | 94 | # warp each color channel 95 | for i in range(len(im.shape)): 96 | im2[:,:,i] = ndimage.affine_transform(im[:,:,i],linalg.inv(T),offset=[-ty,-tx]) 97 | 98 | if plotflag: 99 | imshow(im2) 100 | show() 101 | 102 | # crop away border and save aligned images 103 | h,w = im2.shape[:2] 104 | border = (w+h)/20 105 | 106 | # crop away border 107 | imsave(os.path.join(path, 'aligned/'+face),im2[border:h-border,border:w-border,:]) 108 | 109 | -------------------------------------------------------------------------------- /PCV/tools/imtools.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PIL import Image 3 | from pylab import * 4 | from numpy import * 5 | 6 | 7 | 8 | def get_imlist(path): 9 | """ Returns a list of filenames for 10 | all jpg images in a directory. """ 11 | 12 | return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')] 13 | 14 | 15 | def compute_average(imlist): 16 | """ Compute the average of a list of images. """ 17 | 18 | # open first image and make into array of type float 19 | averageim = array(Image.open(imlist[0]), 'f') 20 | 21 | skipped = 0 22 | 23 | for imname in imlist[1:]: 24 | try: 25 | averageim += array(Image.open(imname)) 26 | except: 27 | print (imname + "...skipped") 28 | skipped += 1 29 | 30 | averageim /= (len(imlist) - skipped) 31 | 32 | # return average as uint8 33 | return array(averageim, 'uint8') 34 | 35 | 36 | def convert_to_grayscale(imlist): 37 | """ Convert a set of images to grayscale. """ 38 | 39 | for imname in imlist: 40 | im = Image.open(imname).convert("L") 41 | im.save(imname) 42 | 43 | 44 | def imresize(im,sz): 45 | """ Resize an image array using PIL. """ 46 | pil_im = Image.fromarray(uint8(im)) 47 | 48 | return array(pil_im.resize(sz)) 49 | 50 | 51 | def histeq(im,nbr_bins=256): 52 | """ Histogram equalization of a grayscale image. """ 53 | 54 | # get image histogram 55 | imhist,bins = histogram(im.flatten(),nbr_bins,normed=True) 56 | cdf = imhist.cumsum() # cumulative distribution function 57 | cdf = 255 * cdf / cdf[-1] # normalize 58 | 59 | # use linear interpolation of cdf to find new pixel values 60 | im2 = interp(im.flatten(),bins[:-1],cdf) 61 | 62 | return im2.reshape(im.shape), cdf 63 | 64 | 65 | def plot_2D_boundary(plot_range,points,decisionfcn,labels,values=[0]): 66 | """ Plot_range is (xmin,xmax,ymin,ymax), points is a list 67 | of class points, decisionfcn is a funtion to evaluate, 68 | labels is a list of labels that decisionfcn returns for each class, 69 | values is a list of decision contours to show. """ 70 | 71 | clist = ['b','r','g','k','m','y'] # colors for the classes 72 | 73 | # evaluate on a grid and plot contour of decision function 74 | x = arange(plot_range[0],plot_range[1],.1) 75 | y = arange(plot_range[2],plot_range[3],.1) 76 | xx,yy = meshgrid(x,y) 77 | xxx,yyy = xx.flatten(),yy.flatten() # lists of x,y in grid 78 | zz = array(decisionfcn(xxx,yyy)) 79 | zz = zz.reshape(xx.shape) 80 | # plot contour(s) at values 81 | contour(xx,yy,zz,values) 82 | 83 | # for each class, plot the points with '*' for correct, 'o' for incorrect 84 | for i in range(len(points)): 85 | d = decisionfcn(points[i][:,0],points[i][:,1]) 86 | correct_ndx = labels[i]==d 87 | incorrect_ndx = labels[i]!=d 88 | plot(points[i][correct_ndx,0],points[i][correct_ndx,1],'*',color=clist[i]) 89 | plot(points[i][incorrect_ndx,0],points[i][incorrect_ndx,1],'o',color=clist[i]) 90 | 91 | axis('equal') 92 | -------------------------------------------------------------------------------- /PCV/tools/imtools.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/imtools.pyc -------------------------------------------------------------------------------- /PCV/tools/ncut.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from pylab import * 3 | from numpy import * 4 | from scipy.cluster.vq import * 5 | 6 | 7 | def cluster(S,k,ndim): 8 | """ Spectral clustering from a similarity matrix.""" 9 | 10 | # check for symmetry 11 | if sum(abs(S-S.T)) > 1e-10: 12 | print ('not symmetric') 13 | 14 | # create Laplacian matrix 15 | rowsum = sum(abs(S),axis=0) 16 | D = diag(1 / sqrt(rowsum + 1e-6)) 17 | L = dot(D,dot(S,D)) 18 | 19 | # compute eigenvectors of L 20 | U,sigma,V = linalg.svd(L,full_matrices=False) 21 | 22 | # create feature vector from ndim first eigenvectors 23 | # by stacking eigenvectors as columns 24 | features = array(V[:ndim]).T 25 | 26 | # k-means 27 | features = whiten(features) 28 | centroids,distortion = kmeans(features,k) 29 | code,distance = vq(features,centroids) 30 | 31 | return code,V 32 | 33 | 34 | def ncut_graph_matrix(im,sigma_d=1e2,sigma_g=1e-2): 35 | """ Create matrix for normalized cut. The parameters are 36 | the weights for pixel distance and pixel similarity. """ 37 | 38 | m,n = im.shape[:2] 39 | N = m*n 40 | 41 | # normalize and create feature vector of RGB or grayscale 42 | if len(im.shape)==3: 43 | for i in range(3): 44 | im[:,:,i] = im[:,:,i] / im[:,:,i].max() 45 | vim = im.reshape((-1,3)) 46 | else: 47 | im = im / im.max() 48 | vim = im.flatten() 49 | 50 | # x,y coordinates for distance computation 51 | xx,yy = meshgrid(range(n),range(m)) 52 | x,y = xx.flatten(),yy.flatten() 53 | 54 | # create matrix with edge weights 55 | W = zeros((N,N),'f') 56 | for i in range(N): 57 | for j in range(i,N): 58 | d = (x[i]-x[j])**2 + (y[i]-y[j])**2 59 | W[i,j] = W[j,i] = exp(-1.0*sum((vim[i]-vim[j])**2)/sigma_g) * exp(-d/sigma_d) 60 | 61 | return W 62 | -------------------------------------------------------------------------------- /PCV/tools/pca.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from numpy import * 3 | 4 | 5 | def pca(X): 6 | """ Principal Component Analysis 7 | input: X, matrix with training data stored as flattened arrays in rows 8 | return: projection matrix (with important dimensions first), variance and mean. 9 | """ 10 | 11 | # get dimensions 12 | num_data,dim = X.shape 13 | 14 | # center data 15 | mean_X = X.mean(axis=0) 16 | X = X - mean_X 17 | 18 | if dim>num_data: 19 | # PCA - compact trick used 20 | M = dot(X,X.T) # covariance matrix 21 | e,EV = linalg.eigh(M) # eigenvalues and eigenvectors 22 | tmp = dot(X.T,EV).T # this is the compact trick 23 | V = tmp[::-1] # reverse since last eigenvectors are the ones we want 24 | S = sqrt(e)[::-1] # reverse since eigenvalues are in increasing order 25 | for i in range(V.shape[1]): 26 | V[:,i] /= S 27 | else: 28 | # PCA - SVD used 29 | U,S,V = linalg.svd(X) 30 | V = V[:num_data] # only makes sense to return the first num_data 31 | 32 | # return the projection matrix, the variance and the mean 33 | return V,S,mean_X 34 | 35 | 36 | def center(X): 37 | """ Center the square matrix X (subtract col and row means). """ 38 | 39 | n,m = X.shape 40 | if n != m: 41 | raise Exception('Matrix is not square.') 42 | 43 | colsum = X.sum(axis=0) / n 44 | rowsum = X.sum(axis=1) / n 45 | totalsum = X.sum() / (n**2) 46 | 47 | #center 48 | Y = array([[ X[i,j]-rowsum[i]-colsum[j]+totalsum for i in range(n) ] for j in range(n)]) 49 | 50 | return Y -------------------------------------------------------------------------------- /PCV/tools/ransac.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import scipy # use numpy if scipy unavailable 3 | import scipy.linalg # use numpy if scipy unavailable 4 | 5 | ## Copyright (c) 2004-2007, Andrew D. Straw. All rights reserved. 6 | 7 | ## Redistribution and use in source and binary forms, with or without 8 | ## modification, are permitted provided that the following conditions are 9 | ## met: 10 | 11 | ## * Redistributions of source code must retain the above copyright 12 | ## notice, this list of conditions and the following disclaimer. 13 | 14 | ## * Redistributions in binary form must reproduce the above 15 | ## copyright notice, this list of conditions and the following 16 | ## disclaimer in the documentation and/or other materials provided 17 | ## with the distribution. 18 | 19 | ## * Neither the name of the Andrew D. Straw nor the names of its 20 | ## contributors may be used to endorse or promote products derived 21 | ## from this software without specific prior written permission. 22 | 23 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | def ransac(data,model,n,k,t,d,debug=False,return_all=False): 36 | """fit model parameters to data using the RANSAC algorithm 37 | 38 | This implementation written from pseudocode found at 39 | http://en.wikipedia.org/w/index.php?title=RANSAC&oldid=116358182 40 | 41 | {{{ 42 | Given: 43 | data - a set of observed data points 44 | model - a model that can be fitted to data points 45 | n - the minimum number of data values required to fit the model 46 | k - the maximum number of iterations allowed in the algorithm 47 | t - a threshold value for determining when a data point fits a model 48 | d - the number of close data values required to assert that a model fits well to data 49 | Return: 50 | bestfit - model parameters which best fit the data (or nil if no good model is found) 51 | iterations = 0 52 | bestfit = nil 53 | besterr = something really large 54 | while iterations < k { 55 | maybeinliers = n randomly selected values from data 56 | maybemodel = model parameters fitted to maybeinliers 57 | alsoinliers = empty set 58 | for every point in data not in maybeinliers { 59 | if point fits maybemodel with an error smaller than t 60 | add point to alsoinliers 61 | } 62 | if the number of elements in alsoinliers is > d { 63 | % this implies that we may have found a good model 64 | % now test how good it is 65 | bettermodel = model parameters fitted to all points in maybeinliers and alsoinliers 66 | thiserr = a measure of how well model fits these points 67 | if thiserr < besterr { 68 | bestfit = bettermodel 69 | besterr = thiserr 70 | } 71 | } 72 | increment iterations 73 | } 74 | return bestfit 75 | }}} 76 | """ 77 | iterations = 0 78 | bestfit = None 79 | besterr = numpy.inf 80 | best_inlier_idxs = None 81 | while iterations < k: 82 | maybe_idxs, test_idxs = random_partition(n,data.shape[0]) 83 | maybeinliers = data[maybe_idxs,:] 84 | test_points = data[test_idxs] 85 | maybemodel = model.fit(maybeinliers) 86 | test_err = model.get_error( test_points, maybemodel) 87 | also_idxs = test_idxs[test_err < t] # select indices of rows with accepted points 88 | alsoinliers = data[also_idxs,:] 89 | if debug: 90 | print ('test_err.min()',test_err.min()) 91 | print ('test_err.max()',test_err.max()) 92 | print ('numpy.mean(test_err)',numpy.mean(test_err)) 93 | print ('iteration %d:len(alsoinliers) = %d'%( 94 | iterations,len(alsoinliers))) 95 | if len(alsoinliers) > d: 96 | betterdata = numpy.concatenate( (maybeinliers, alsoinliers) ) 97 | bettermodel = model.fit(betterdata) 98 | better_errs = model.get_error( betterdata, bettermodel) 99 | thiserr = numpy.mean( better_errs ) 100 | if thiserr < besterr: 101 | bestfit = bettermodel 102 | besterr = thiserr 103 | best_inlier_idxs = numpy.concatenate( (maybe_idxs, also_idxs) ) 104 | iterations+=1 105 | if bestfit is None: 106 | raise ValueError("did not meet fit acceptance criteria") 107 | if return_all: 108 | return bestfit, {'inliers':best_inlier_idxs} 109 | else: 110 | return bestfit 111 | 112 | def random_partition(n,n_data): 113 | """return n random rows of data (and also the other len(data)-n rows)""" 114 | all_idxs = numpy.arange( n_data ) 115 | numpy.random.shuffle(all_idxs) 116 | idxs1 = all_idxs[:n] 117 | idxs2 = all_idxs[n:] 118 | return idxs1, idxs2 119 | 120 | class LinearLeastSquaresModel: 121 | """linear system solved using linear least squares 122 | 123 | This class serves as an example that fulfills the model interface 124 | needed by the ransac() function. 125 | 126 | """ 127 | def __init__(self,input_columns,output_columns,debug=False): 128 | self.input_columns = input_columns 129 | self.output_columns = output_columns 130 | self.debug = debug 131 | def fit(self, data): 132 | A = numpy.vstack([data[:,i] for i in self.input_columns]).T 133 | B = numpy.vstack([data[:,i] for i in self.output_columns]).T 134 | x,resids,rank,s = numpy.linalg.lstsq(A,B) 135 | return x 136 | def get_error( self, data, model): 137 | A = numpy.vstack([data[:,i] for i in self.input_columns]).T 138 | B = numpy.vstack([data[:,i] for i in self.output_columns]).T 139 | B_fit = scipy.dot(A,model) 140 | err_per_point = numpy.sum((B-B_fit)**2,axis=1) # sum squared error per row 141 | return err_per_point 142 | 143 | def test(): 144 | # generate perfect input data 145 | 146 | n_samples = 500 147 | n_inputs = 1 148 | n_outputs = 1 149 | A_exact = 20*numpy.random.random((n_samples,n_inputs) ) 150 | perfect_fit = 60*numpy.random.normal(size=(n_inputs,n_outputs) ) # the model 151 | B_exact = scipy.dot(A_exact,perfect_fit) 152 | assert B_exact.shape == (n_samples,n_outputs) 153 | 154 | # add a little gaussian noise (linear least squares alone should handle this well) 155 | A_noisy = A_exact + numpy.random.normal(size=A_exact.shape ) 156 | B_noisy = B_exact + numpy.random.normal(size=B_exact.shape ) 157 | 158 | if 1: 159 | # add some outliers 160 | n_outliers = 100 161 | all_idxs = numpy.arange( A_noisy.shape[0] ) 162 | numpy.random.shuffle(all_idxs) 163 | outlier_idxs = all_idxs[:n_outliers] 164 | non_outlier_idxs = all_idxs[n_outliers:] 165 | A_noisy[outlier_idxs] = 20*numpy.random.random((n_outliers,n_inputs) ) 166 | B_noisy[outlier_idxs] = 50*numpy.random.normal(size=(n_outliers,n_outputs) ) 167 | 168 | # setup model 169 | 170 | all_data = numpy.hstack( (A_noisy,B_noisy) ) 171 | input_columns = range(n_inputs) # the first columns of the array 172 | output_columns = [n_inputs+i for i in range(n_outputs)] # the last columns of the array 173 | debug = True 174 | model = LinearLeastSquaresModel(input_columns,output_columns,debug=debug) 175 | 176 | linear_fit,resids,rank,s = numpy.linalg.lstsq(all_data[:,input_columns],all_data[:,output_columns]) 177 | 178 | # run RANSAC algorithm 179 | ransac_fit, ransac_data = ransac(all_data,model, 180 | 5, 5000, 7e4, 50, # misc. parameters 181 | debug=debug,return_all=True) 182 | if 1: 183 | import pylab 184 | 185 | sort_idxs = numpy.argsort(A_exact[:,0]) 186 | A_col0_sorted = A_exact[sort_idxs] # maintain as rank-2 array 187 | 188 | if 1: 189 | pylab.plot( A_noisy[:,0], B_noisy[:,0], 'k.', label='data' ) 190 | pylab.plot( A_noisy[ransac_data['inliers'],0], B_noisy[ransac_data['inliers'],0], 'bx', label='RANSAC data' ) 191 | else: 192 | pylab.plot( A_noisy[non_outlier_idxs,0], B_noisy[non_outlier_idxs,0], 'k.', label='noisy data' ) 193 | pylab.plot( A_noisy[outlier_idxs,0], B_noisy[outlier_idxs,0], 'r.', label='outlier data' ) 194 | pylab.plot( A_col0_sorted[:,0], 195 | numpy.dot(A_col0_sorted,ransac_fit)[:,0], 196 | label='RANSAC fit' ) 197 | pylab.plot( A_col0_sorted[:,0], 198 | numpy.dot(A_col0_sorted,perfect_fit)[:,0], 199 | label='exact system' ) 200 | pylab.plot( A_col0_sorted[:,0], 201 | numpy.dot(A_col0_sorted,linear_fit)[:,0], 202 | label='linear fit' ) 203 | pylab.legend() 204 | pylab.show() 205 | 206 | if __name__=='__main__': 207 | test() 208 | 209 | -------------------------------------------------------------------------------- /PCV/tools/ransac.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/PCV/tools/ransac.pyc -------------------------------------------------------------------------------- /PCV/tools/rof.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | 3 | 4 | def denoise(im,U_init,tolerance=0.1,tau=0.125,tv_weight=100): 5 | """ An implementation of the Rudin-Osher-Fatemi (ROF) denoising model 6 | using the numerical procedure presented in Eq. (11) of A. Chambolle 7 | (2005). Implemented using periodic boundary conditions. 8 | 9 | Input: noisy input image (grayscale), initial guess for U, weight of 10 | the TV-regularizing term, steplength, tolerance for the stop criterion 11 | 12 | Output: denoised and detextured image, texture residual. """ 13 | 14 | m,n = im.shape #size of noisy image 15 | 16 | # initialize 17 | U = U_init 18 | Px = zeros((m, n)) #x-component to the dual field 19 | Py = zeros((m, n)) #y-component of the dual field 20 | error = 1 21 | 22 | while (error > tolerance): 23 | Uold = U 24 | 25 | # gradient of primal variable 26 | GradUx = roll(U,-1,axis=1)-U # x-component of U's gradient 27 | GradUy = roll(U,-1,axis=0)-U # y-component of U's gradient 28 | 29 | # update the dual varible 30 | PxNew = Px + (tau/tv_weight)*GradUx # non-normalized update of x-component (dual) 31 | PyNew = Py + (tau/tv_weight)*GradUy # non-normalized update of y-component (dual) 32 | NormNew = maximum(1,sqrt(PxNew**2+PyNew**2)) 33 | 34 | Px = PxNew/NormNew # update of x-component (dual) 35 | Py = PyNew/NormNew # update of y-component (dual) 36 | 37 | # update the primal variable 38 | RxPx = roll(Px,1,axis=1) # right x-translation of x-component 39 | RyPy = roll(Py,1,axis=0) # right y-translation of y-component 40 | 41 | DivP = (Px-RxPx)+(Py-RyPy) # divergence of the dual field. 42 | U = im + tv_weight*DivP # update of the primal variable 43 | 44 | # update of error 45 | error = linalg.norm(U-Uold)/sqrt(n*m); 46 | 47 | return U,im-U # denoised image and texture residual 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PythonComputerVision-9-Image-Content-Classification 2 | 图像内容分类--本文主要阐述:①knn可视化。②dense sift(稠密sift)原理。③手势识别 3 | ## 一.K邻近分类法(KNN) 4 | 目前存在很多分类方法,其中最简单且用的最多的一种方法就是KNN(K-Nearest Neighbor,K邻近分类法),这种算法把要分类的对象,比如我们后面要用到的特征向量,与训练集中已知类标记的所有对象进行对比,并由k近邻对指派到哪个类进行投票。这种方法通常分类效果较好,但是也有很多弊端:与K-means聚类算法一样,需要预先设定K值,K值的选择会影响分类的性能;此外,这种方法要求将整个训练集存储起来,如果训练集非常大,搜索起来会比歼缓慢。对于大训练集,采取某些装箱形式通常会减少对比的次数。 5 | 实现最基本的KNN很简单。这里会展示一个简单的二维示例: 6 | ### 1.创建数据集 7 | 源码如下: 8 | 9 | ~~~python 10 | # -*- coding: utf-8 -*- 11 | from numpy.random import randn 12 | import pickle 13 | from pylab import * 14 | 15 | # create sample data of 2D points 16 | n = 250 17 | # 2个正态分布数据集 18 | class_1 = 0.7 * randn(n,2) 19 | class_2 = 1.4 * randn(n,2) + array([5,1]) 20 | labels = hstack((ones(n),-ones(n))) 21 | # save with Pickle 22 | #with open('points_normal.pkl', 'wb') as f: 23 | with open('points_normal_test.pkl', 'wb') as f: 24 | pickle.dump(class_1,f) 25 | pickle.dump(class_2,f) 26 | pickle.dump(labels,f) 27 | # 正态分布并且使数据环绕装分布 28 | print ("save OK!") 29 | class_1 = 0.7 * randn(n,2) 30 | r = 0.9 * randn(n,1) + 5 31 | angle = 3*pi * randn(n,1) 32 | class_2 = hstack((r*cos(angle),r*sin(angle))) 33 | labels = hstack((ones(n),-ones(n))) 34 | # save with Pickle 35 | #with open('points_ring.pkl', 'wb') as f: 36 | with open('points_ring_test.pkl', 'wb') as f: 37 | pickle.dump(class_1,f) 38 | pickle.dump(class_2,f) 39 | pickle.dump(labels,f) 40 | 41 | print ("save OK!") 42 | 43 | ~~~ 44 | 用不同的保存文件名运行上述代码两次,就可以得到4个二维数据集。每个分布有两个文件,一个训练,一个测试。 45 | ### 2.KNN分类器及结果可视化 46 | 源码如下: 47 | ~~~python 48 | # -*- coding: utf-8 -*- 49 | import pickle 50 | from pylab import * 51 | from PCV.classifiers import knn 52 | from PCV.tools import imtools 53 | 54 | pklist=['points_normal.pkl','points_ring.pkl'] 55 | 56 | figure() 57 | 58 | # load 2D points using Pickle 59 | for i, pklfile in enumerate(pklist): 60 | with open(pklfile, 'rb') as f: 61 | class_1 = pickle.load(f) 62 | class_2 = pickle.load(f) 63 | labels = pickle.load(f) 64 | # load test data using Pickle 65 | with open(pklfile[:-4]+'_test.pkl', 'rb') as f: 66 | class_1 = pickle.load(f) 67 | class_2 = pickle.load(f) 68 | labels = pickle.load(f) 69 | 70 | model = knn.KnnClassifier(labels,vstack((class_1,class_2))) 71 | # test on the first point 72 | print (model.classify(class_1[0])) 73 | 74 | #define function for plotting 75 | def classify(x,y,model=model): 76 | return array([model.classify([xx,yy]) for (xx,yy) in zip(x,y)]) 77 | 78 | # lot the classification boundary 79 | subplot(1,2,i+1) 80 | imtools.plot_2D_boundary([-6,6,-6,6],[class_1,class_2],classify,[1,-1]) 81 | titlename=pklfile[:-4] 82 | title(titlename) 83 | show() 84 | ~~~ 85 | 上述代码载入训练数据来创建一个KNN分类器模型,并载入另外的测试数据集来对测试数据点进行分类。最后的部分可视化这些测试点(如下图:) 86 | ![image](https://github.com/Nocami/PythonComputerVision-9-Image-Content-Classification/blob/master/image/1.jpg) 87 | 用K邻近分类器分类二维数据,每个示例中,不同颜色代表类标记,正确分类的点用星星表示,错误的用圆点表示,曲线是分类器的决策边界。 88 | ## 二.计算机视觉快速特征描述子--稠密SIFT(dense sift) 89 | dense SIFT在目标分类和场景分类有重要的应用。该算法首先将表达目标的区域分成相同大小的区域块,计算每一个小块的SIFT特征,再对各个小块的稠密SIFT特征在中心位置进行采样,建模目标的表达。然后度量两个图像区域的不相似性,先计算两个区域对应小块的巴氏距离,再对各距离加权求和作为两个区域间的距离。因为目标所在区域靠近边缘的部分可能受到背景像素的影响,而区域的内部则更一致,所以越靠近区域中心权函数的值越大。 90 | 普通的SIFT在之前的博客中有详细的介绍,这里主要讲一下二者的不同点。dense SIFT是提取我们感兴趣的区域中的每个位置的SIFT特征。而通常做特征匹配的SIFT算法只是得到感兴趣区域或者图像上若干个稳定的关键点的SIFT特征。总而言之,当研究目标是对同样的物体或者场景寻找对应关系时,SIFT更好。而研究目标是图像表示或者场景理解时,Dense SIFT更好,因为即使密集采样的区域不能够被准确匹配,这块区域也包含了表达图像内容的信息。 91 | 利用如下的例子,可以计算dense SIFT描述子,并可视化它们的位置: 92 | ~~~python 93 | # -*- coding: utf-8 -*- 94 | from PCV.localdescriptors import sift, dsift 95 | from pylab import * 96 | from PIL import Image 97 | 98 | dsift.process_image_dsift('gesture/empire.jpg','empire.dsift',90,40,True) 99 | l,d = sift.read_features_from_file('empire.dsift') 100 | im = array(Image.open('gesture/empire.jpg')) 101 | sift.plot_features(im,l,True) 102 | title('dense SIFT') 103 | show() 104 | ~~~ 105 | 其他相关代码可以用之前博客介绍过的执行角本通过添加一些额外的参数来得到稠密sift特征。 106 | 使用用于定位描述子的局部梯度方向(force_orientation设置为真),该代码可以在整个图像中计算出dense SIFT特征。下图显示了这些位置: 107 | ![image](https://github.com/Nocami/PythonComputerVision-9-Image-Content-Classification/blob/master/image/2.jpg) 108 | ## 三.图像分类:手势识别 109 | 在这个示例中,使用dense SIFT描述子来表示这些手势图像,并建立一个简单的手势识别系统。我这里用自己的手进行比划拍照,共有6种手势,每种40张图片。 110 | 下面这段代码展示了6类简单手势图像的dense SIFT描述子: 111 | ~~~python 112 | # -*- coding: utf-8 -*- 113 | import os 114 | from PCV.localdescriptors import sift, dsift 115 | from pylab import * 116 | from PIL import Image 117 | 118 | imlist=['gesture/image2/feichang01.jpg','gesture/image2/er01.jpg', 119 | 'gesture/image2/san01.jpg','gesture/image2/wu01.jpg', 120 | 'gesture/image2/damu01.jpg','gesture/image2/xiaomu01.jpg'] 121 | 122 | figure() 123 | for i, im in enumerate(imlist): 124 | print (im) 125 | dsift.process_image_dsift(im,im[:-3]+'dsift',10,5,True) 126 | l,d = sift.read_features_from_file(im[:-3]+'dsift') 127 | dirpath, filename=os.path.split(im) 128 | im = array(Image.open(im)) 129 | #显示手势含义title 130 | titlename=filename[:-14] 131 | subplot(2,3,i+1) 132 | sift.plot_features(im,l,True) 133 | title(titlename) 134 | show() 135 | 其中,10,5指的是对图像进行SIFT特征计算的次数。 136 | ~~~ 137 | ![image](https://github.com/Nocami/PythonComputerVision-9-Image-Content-Classification/blob/master/image/3.jpg) 138 | 139 | 下面我们可以使用一些代码来读取训练集与测试集,我采用的数据集为自己拍摄的自己左手照片,其中训练集180张,测试集50-60张。 140 | 需要**特别注意**的是:图片的命名方式决定了最后的混淆矩阵的布局,这里推荐使用**字母+uniform+编号**的方式,如“B-uniform01”。 141 | ~~~python 142 | # -*- coding: utf-8 -*- 143 | from PCV.localdescriptors import dsift 144 | import os 145 | from PCV.localdescriptors import sift 146 | from pylab import * 147 | from PCV.classifiers import knn 148 | 149 | def get_imagelist(path): 150 | """ Returns a list of filenames for 151 | all jpg images in a directory. """ 152 | 153 | return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')] 154 | 155 | def read_gesture_features_labels(path): 156 | # create list of all files ending in .dsift 157 | featlist = [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.dsift')] 158 | # read the features 159 | features = [] 160 | for featfile in featlist: 161 | l,d = sift.read_features_from_file(featfile) 162 | features.append(d.flatten()) 163 | features = array(features) 164 | # create labels 165 | labels = [featfile.split('/')[-1][0] for featfile in featlist] 166 | return features,array(labels) 167 | 168 | def print_confusion(res,labels,classnames): 169 | n = len(classnames) 170 | # confusion matrix 171 | class_ind = dict([(classnames[i],i) for i in range(n)]) 172 | confuse = zeros((n,n)) 173 | for i in range(len(test_labels)): 174 | confuse[class_ind[res[i]],class_ind[test_labels[i]]] += 1 175 | print ('Confusion matrix for') 176 | print (classnames) 177 | print (confuse) 178 | 179 | filelist_train = get_imagelist('gesture/train') 180 | filelist_test = get_imagelist('gesture/test') 181 | imlist=filelist_train+filelist_test 182 | 183 | # process images at fixed size (50,50) 184 | for filename in imlist: 185 | featfile = filename[:-3]+'dsift' 186 | dsift.process_image_dsift(filename,featfile,10,5,resize=(50,50)) 187 | 188 | features,labels = read_gesture_features_labels('gesture/train/') 189 | test_features,test_labels = read_gesture_features_labels('gesture/test/') 190 | classnames = unique(labels) 191 | 192 | # test kNN 193 | k = 1 194 | knn_classifier = knn.KnnClassifier(labels,features) 195 | res = array([knn_classifier.classify(test_features[i],k) for i in 196 | range(len(test_labels))]) 197 | # accuracy 198 | acc = sum(1.0*(res==test_labels)) / len(test_labels) 199 | print ('Accuracy:', acc) 200 | 201 | print_confusion(res,test_labels,classnames) 202 | 203 | ~~~ 204 | ![image](https://github.com/Nocami/PythonComputerVision-9-Image-Content-Classification/blob/master/image/5.jpg) 205 | 上图展示我个人数据集的一部分。 206 | ![image](https://github.com/Nocami/PythonComputerVision-9-Image-Content-Classification/blob/master/image/4.jpg) 207 | 最终,我这个示例的正确率达到了98%,其混淆矩阵如上图: 208 | **特别说明:**B指汉语“布”,G指good竖大拇指,L指垃圾竖小拇指,F指非常六加一,V指胜利,O指OK。 209 | -------------------------------------------------------------------------------- /ch08_P168_2D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from numpy.random import randn 3 | import pickle 4 | from pylab import * 5 | 6 | # create sample data of 2D points 7 | n = 250 8 | # two normal distributions 9 | class_1 = 0.7 * randn(n,2) 10 | class_2 = 1.4 * randn(n,2) + array([5,1]) 11 | labels = hstack((ones(n),-ones(n))) 12 | # save with Pickle 13 | #with open('points_normal.pkl', 'wb') as f: 14 | with open('points_normal_test.pkl', 'wb') as f: 15 | pickle.dump(class_1,f) 16 | pickle.dump(class_2,f) 17 | pickle.dump(labels,f) 18 | # normal distribution and ring around it 19 | print ("save OK!") 20 | class_1 = 0.7 * randn(n,2) 21 | r = 0.9 * randn(n,1) + 5 22 | angle = 3*pi * randn(n,1) 23 | class_2 = hstack((r*cos(angle),r*sin(angle))) 24 | labels = hstack((ones(n),-ones(n))) 25 | # save with Pickle 26 | #with open('points_ring.pkl', 'wb') as f: 27 | with open('points_ring_test.pkl', 'wb') as f: 28 | pickle.dump(class_1,f) 29 | pickle.dump(class_2,f) 30 | pickle.dump(labels,f) 31 | 32 | print ("save OK!") 33 | -------------------------------------------------------------------------------- /ch08_P169_normal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pickle 3 | from pylab import * 4 | from PCV.classifiers import knn 5 | from PCV.tools import imtools 6 | 7 | pklist=['points_normal.pkl','points_ring.pkl'] 8 | 9 | figure() 10 | 11 | # load 2D points using Pickle 12 | for i, pklfile in enumerate(pklist): 13 | with open(pklfile, 'rb') as f: 14 | class_1 = pickle.load(f) 15 | class_2 = pickle.load(f) 16 | labels = pickle.load(f) 17 | # load test data using Pickle 18 | with open(pklfile[:-4]+'_test.pkl', 'rb') as f: 19 | class_1 = pickle.load(f) 20 | class_2 = pickle.load(f) 21 | labels = pickle.load(f) 22 | 23 | model = knn.KnnClassifier(labels,vstack((class_1,class_2))) 24 | # test on the first point 25 | print (model.classify(class_1[0])) 26 | 27 | #define function for plotting 28 | def classify(x,y,model=model): 29 | return array([model.classify([xx,yy]) for (xx,yy) in zip(x,y)]) 30 | 31 | # lot the classification boundary 32 | subplot(1,2,i+1) 33 | imtools.plot_2D_boundary([-6,6,-6,6],[class_1,class_2],classify,[1,-1]) 34 | titlename=pklfile[:-4] 35 | title(titlename) 36 | show() -------------------------------------------------------------------------------- /ch08_P172_dsift.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from PCV.localdescriptors import sift, dsift 3 | from pylab import * 4 | from PIL import Image 5 | 6 | dsift.process_image_dsift('gesture/empire.jpg','empire.dsift',90,40,True) 7 | l,d = sift.read_features_from_file('empire.dsift') 8 | im = array(Image.open('gesture/empire.jpg')) 9 | sift.plot_features(im,l,True) 10 | title('dense SIFT') 11 | show() -------------------------------------------------------------------------------- /ch08_P173_Fig8-3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | from PCV.localdescriptors import sift, dsift 4 | from pylab import * 5 | from PIL import Image 6 | 7 | imlist=['gesture/image2/B-uniform01.jpg','gesture/image2/F-uniform01.jpg', 8 | 'gesture/image2/G-uniform01.jpg','gesture/image2/L-uniform01.jpg', 9 | 'gesture/image2/O-uniform01.jpg','gesture/image2/V-uniform01.jpg'] 10 | 11 | figure() 12 | for i, im in enumerate(imlist): 13 | print (im) 14 | dsift.process_image_dsift(im,im[:-3]+'dsift',10,5,True) 15 | l,d = sift.read_features_from_file(im[:-3]+'dsift') 16 | dirpath, filename=os.path.split(im) 17 | im = array(Image.open(im)) 18 | #显示手势含义title 19 | titlename=filename[:-14] 20 | subplot(2,3,i+1) 21 | sift.plot_features(im,l,True) 22 | title(titlename) 23 | show() 24 | -------------------------------------------------------------------------------- /ch08_P173_gesture.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from PCV.localdescriptors import dsift 3 | import os 4 | from PCV.localdescriptors import sift 5 | from pylab import * 6 | from PCV.classifiers import knn 7 | 8 | def get_imagelist(path): 9 | """ Returns a list of filenames for 10 | all jpg images in a directory. """ 11 | 12 | return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')] 13 | 14 | def read_gesture_features_labels(path): 15 | # create list of all files ending in .dsift 16 | featlist = [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.dsift')] 17 | # read the features 18 | features = [] 19 | for featfile in featlist: 20 | l,d = sift.read_features_from_file(featfile) 21 | features.append(d.flatten()) 22 | features = array(features) 23 | # create labels 24 | labels = [featfile.split('/')[-1][0] for featfile in featlist] 25 | return features,array(labels) 26 | 27 | def print_confusion(res,labels,classnames): 28 | n = len(classnames) 29 | # confusion matrix 30 | class_ind = dict([(classnames[i],i) for i in range(n)]) 31 | confuse = zeros((n,n)) 32 | for i in range(len(test_labels)): 33 | confuse[class_ind[res[i]],class_ind[test_labels[i]]] += 1 34 | print ('Confusion matrix for') 35 | print (classnames) 36 | print (confuse) 37 | 38 | filelist_train = get_imagelist('gesture/train') 39 | filelist_test = get_imagelist('gesture/test') 40 | imlist=filelist_train+filelist_test 41 | 42 | # process images at fixed size (50,50) 43 | for filename in imlist: 44 | featfile = filename[:-3]+'dsift' 45 | dsift.process_image_dsift(filename,featfile,10,5,resize=(50,50)) 46 | 47 | features,labels = read_gesture_features_labels('gesture/train/') 48 | test_features,test_labels = read_gesture_features_labels('gesture/test/') 49 | classnames = unique(labels) 50 | 51 | # test kNN 52 | k = 1 53 | knn_classifier = knn.KnnClassifier(labels,features) 54 | res = array([knn_classifier.classify(test_features[i],k) for i in 55 | range(len(test_labels))]) 56 | # accuracy 57 | acc = sum(1.0*(res==test_labels)) / len(test_labels) 58 | print ('Accuracy:', acc) 59 | 60 | print_confusion(res,test_labels,classnames) 61 | -------------------------------------------------------------------------------- /image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/image/1.jpg -------------------------------------------------------------------------------- /image/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/image/2.jpg -------------------------------------------------------------------------------- /image/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/image/3.jpg -------------------------------------------------------------------------------- /image/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/image/4.jpg -------------------------------------------------------------------------------- /image/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/image/5.jpg -------------------------------------------------------------------------------- /image/s: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /win32vlfeat/Microsoft.VC90.CRT.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /win32vlfeat/aib.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/aib.exe -------------------------------------------------------------------------------- /win32vlfeat/mser.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/mser.exe -------------------------------------------------------------------------------- /win32vlfeat/msvcr90.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/msvcr90.dll -------------------------------------------------------------------------------- /win32vlfeat/sift.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/sift.exe -------------------------------------------------------------------------------- /win32vlfeat/test_gauss_elimination.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_gauss_elimination.exe -------------------------------------------------------------------------------- /win32vlfeat/test_getopt_long.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_getopt_long.exe -------------------------------------------------------------------------------- /win32vlfeat/test_gmm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_gmm.exe -------------------------------------------------------------------------------- /win32vlfeat/test_heap-def.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_heap-def.exe -------------------------------------------------------------------------------- /win32vlfeat/test_host.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_host.exe -------------------------------------------------------------------------------- /win32vlfeat/test_imopv.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_imopv.exe -------------------------------------------------------------------------------- /win32vlfeat/test_kmeans.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_kmeans.exe -------------------------------------------------------------------------------- /win32vlfeat/test_liop.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_liop.exe -------------------------------------------------------------------------------- /win32vlfeat/test_mathop.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_mathop.exe -------------------------------------------------------------------------------- /win32vlfeat/test_mathop_abs.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_mathop_abs.exe -------------------------------------------------------------------------------- /win32vlfeat/test_nan.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_nan.exe -------------------------------------------------------------------------------- /win32vlfeat/test_qsort-def.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_qsort-def.exe -------------------------------------------------------------------------------- /win32vlfeat/test_rand.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_rand.exe -------------------------------------------------------------------------------- /win32vlfeat/test_sqrti.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_sqrti.exe -------------------------------------------------------------------------------- /win32vlfeat/test_stringop.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_stringop.exe -------------------------------------------------------------------------------- /win32vlfeat/test_svd2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_svd2.exe -------------------------------------------------------------------------------- /win32vlfeat/test_threads.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_threads.exe -------------------------------------------------------------------------------- /win32vlfeat/test_vec_comp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/test_vec_comp.exe -------------------------------------------------------------------------------- /win32vlfeat/vl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/vl.dll -------------------------------------------------------------------------------- /win32vlfeat/vl.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nocami/PythonComputerVision-9-Image-Content-Classification/06b77b5cf954331b34dc5768cafaa0deac3743c5/win32vlfeat/vl.lib --------------------------------------------------------------------------------