~bertrand-nouvel/pycvf-keypoints/trunk

« back to all changes in this revision

Viewing changes to lib/siftgpu.py

  • Committer: tranx
  • Date: 2010-10-01 16:56:14 UTC
  • Revision ID: tranx@havane-20101001165614-u938mdd1y1fgd0o5
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
import os,numpy 
 
3
import pycvfext.keypoints
 
4
from pycvf.core.errors import pycvf_warning
 
5
import scipy
 
6
import scipy.spatial
 
7
from scipy.weave import converters
 
8
from scipy.weave import inline
 
9
 
 
10
 
 
11
class SiftGPU:
 
12
  def __init__(self,params=["-cuda","0", "-v","1"],nodescr=False):
 
13
    self.params=params
 
14
    self.nodescr=nodescr
 
15
  def process(self,img):
 
16
    if (img.ndim==2):
 
17
      img=img[:,:,numpy.newaxis]
 
18
    assert(img.ndim==3)
 
19
    img=numpy.require(img,numpy.uint8,'C')
 
20
    SIFTGPU_DIR=os.path.join(pycvfext.keypoints.__path__[0],'wrappers','SiftGPU')
 
21
    ny,nx,c=img.shape
 
22
    code="""
 
23
    if (!sg_initialized) {
 
24
      siftgpu=new SiftGPU();
 
25
      char * params[%d]=%s;
 
26
      siftgpu->ParseParam(%d,params);
 
27
      siftgpu->CreateContextGL();
 
28
      int support = siftgpu->VerifyContextGL();
 
29
      if(support != SiftGPU::SIFTGPU_FULL_SUPPORTED) {
 
30
      fprintf(stderr,"Your video card is not fully supported\\n");
 
31
      exit(-1);
 
32
      }
 
33
      fprintf(stderr,"Sift GPU is initialized...\\n");
 
34
      sg_initialized=1;
 
35
      
 
36
    }
 
37
 
 
38
      //gl_format (e.g. GL_LUMINANCE, GL_RGB) is the format of the pixel data
 
39
      //gl_type (e.g. GL_UNSIGNED_BYTE, GL_FLOAT) is the data type of the pixel data;
 
40
 
 
41
      siftgpu->RunSIFT(nx, ny,  img_array->data, %s, GL_UNSIGNED_BYTE);
 
42
      int numfeat=siftgpu->GetFeatureNum();
 
43
      PyArray_Dims keys_d;
 
44
      
 
45
      //npy_intp * keys_dims=(npy_intp *)malloc(sizeof(npy_intp)*2);
 
46
      //npy_intp *  keys_dims=PyArray_DIMS(keys_ar_array);
 
47
      npy_intp keys_dims[2];
 
48
      keys_dims[0]=numfeat;
 
49
      keys_dims[1]=4;
 
50
      
 
51
      PyArray_Dims desc_d;
 
52
      //npy_intp * desc_dims=(npy_intp *)malloc(sizeof(npy_intp)*2);//PyArray_DIMS(desc_ar_array);
 
53
      npy_intp desc_dims[2];
 
54
      desc_dims[0]=numfeat;
 
55
      desc_dims[1]=128;
 
56
 
 
57
      keys_d.len=2;
 
58
      desc_d.len=2;
 
59
      keys_d.ptr=keys_dims;
 
60
      desc_d.ptr=desc_dims;
 
61
      PyArray_Resize(keys_ar_array,&keys_d,0,NPY_CORDER);
 
62
      if (!nodescr){
 
63
      PyArray_Resize(desc_ar_array,&desc_d,0,NPY_CORDER);
 
64
      }
 
65
      
 
66
      siftgpu->GetFeatureVector((SiftGPU::SiftKeypoint *)keys_ar_array->data,(float*)((nodescr)?NULL:desc_ar_array->data));
 
67
      fprintf(stderr,"On C side we are done...\\n");
 
68
    """%(len(self.params), "{%s}"%(",".join(map(lambda x:("\"%s\""%(x,) if type(x) ==str else "\"%r\""%(x,) ) ,self.params))),len(self.params), ("GL_LUMINANCE" if c==1 else  "GL_RGB"))
 
69
    #assert(c==1)
 
70
    keys_ar=numpy.zeros((0,4),dtype=numpy.float32)
 
71
    desc_ar=numpy.zeros((0,128),dtype=numpy.float32)
 
72
    os.environ["LD_LIBRARY_PATH"]=":".join(os.environ.get( "LD_LIBRARY_PATH","").split(":")+[os.path.join(SIFTGPU_DIR,'linux','bin'),os.path.join('/usr','local','cuda','lib')])
 
73
    #print os.environ
 
74
    nodescr=int(self.nodescr)
 
75
    inline(code, ['img','nx','ny','desc_ar','keys_ar','nodescr'],
 
76
            headers=[],
 
77
            support_code="""
 
78
#include "GL/glew.h"
 
79
 
 
80
#include "GlobalUtil.h"
 
81
#include "GLTexImage.h"
 
82
 
 
83
#include <SiftGPU.h>
 
84
 
 
85
#include <cstdio>
 
86
 
 
87
SiftGPU* siftgpu=NULL;
 
88
int sg_initialized=0;
 
89
            """,
 
90
            sources=[], 
 
91
                  libraries=['siftgpu','GLEW','glut','IL','GL'],
 
92
                  include_dirs=[os.path.join(SIFTGPU_DIR,'include'),os.path.join(SIFTGPU_DIR,'src','SiftGPU')],
 
93
                  library_dirs=[os.path.join(SIFTGPU_DIR,'linux','bin'),os.path.join('/usr','local','cuda','lib')],
 
94
                  compiler='gcc', extra_compile_args=['-fPIC'], extra_link_args=['-fPIC'] )
 
95
    #print "INLINE DONE",img.mean()
 
96
    return keys_ar, desc_ar
 
97
 
 
98
 
 
99
 
 
100
def SiftMatchGPU(descr1,descr2,maxsift=2048,distmax = 100.0,  ratiomax = 100.0, mutual_best_match = 0):
 
101
    SIFTGPU_DIR=os.path.join(pycvfext.keypoints.__path__[0],'wrappers','SiftGPU')
 
102
    match_buf=numpy.zeros((maxsift,2),dtype=numpy.int32)
 
103
    nmatch=0
 
104
 
 
105
 
 
106
    code="""
 
107
      if (!smg_initialized) {
 
108
        siftmatchgpu=new SiftMatchGPU(maxsift);
 
109
        if (siftmatchgpu->VerifyContextGL()==0) {
 
110
          fprintf(stderr,"Sift Matching Initialization Failed !!\\n");
 
111
        }
 
112
        smg_initialized=1;
 
113
      }
 
114
 
 
115
      siftmatchgpu->SetDescriptors(0,descr1_array->dimensions[0],descr1);
 
116
      siftmatchgpu->SetDescriptors(1,descr2_array->dimensions[0],descr2);
 
117
      /* 
 
118
      int  *_match_buf[2];
 
119
      _match_buf[0]=match_buf;
 
120
      _match_buf[1]=match_buf+maxsift;
 
121
      */
 
122
      nmatch[0] = siftmatchgpu->GetSiftMatch(maxsift,(int [%s][2])(int *) match_buf,distmax,ratiomax,mutual_best_match);
 
123
      fprintf(stderr,"On C side we are done... %%d\\n",nmatch[0]);
 
124
    """%(maxsift,)
 
125
    nmatch=numpy.ndarray([0,],dtype=numpy.int32)
 
126
    os.environ["LD_LIBRARY_PATH"]=":".join(os.environ.get( "LD_LIBRARY_PATH","").split(":")+[os.path.join(SIFTGPU_DIR,'linux','bin'),os.path.join('/usr','local','cuda','lib')])
 
127
    ir=inline(code, 
 
128
            ['descr1','descr2','match_buf','nmatch','maxsift','distmax',  'ratiomax', 'mutual_best_match'],
 
129
            headers=[],
 
130
            support_code="""
 
131
#include "GL/glew.h"
 
132
 
 
133
#include "GlobalUtil.h"
 
134
#include "GLTexImage.h"
 
135
 
 
136
#include <SiftGPU.h>
 
137
 
 
138
#include <cstdio>
 
139
 
 
140
SiftMatchGPU* siftmatchgpu=NULL;
 
141
int smg_initialized=0;
 
142
            """,
 
143
            sources=[], 
 
144
                  libraries=['siftgpu','GLEW','glut','IL','GL'],
 
145
                  include_dirs=[os.path.join(SIFTGPU_DIR,'include'),os.path.join(SIFTGPU_DIR,'src','SiftGPU')],
 
146
                  library_dirs=[os.path.join(SIFTGPU_DIR,'linux','bin'),os.path.join('/usr','local','cuda','lib')],
 
147
                  compiler='gcc', extra_compile_args=['-fPIC','-fpermissive'], extra_link_args=['-fPIC','-fpermissive']  ) # TODO: find the correct C++ writting
 
148
    #print ir,match_buf,nmatch 
 
149
    return match_buf[:nmatch[0]]
 
150
    
 
151
    
 
152
def match_dist1(descr1, descr2,subdist=scipy.spatial.distance.cosine):
 
153
  ##
 
154
  ## The distance is simply the sum of the minimal distances
 
155
  import scipy.spatial
 
156
  if (len(descr1)==0):
 
157
    return numpy.inf
 
158
  if (len(descr2)==0):
 
159
    return numpy.inf
 
160
  #print type(descr1),type(descr2),descr1.shape, descr2.shape
 
161
  md=scipy.spatial.distance.cdist(descr1,descr2,subdist).min(axis=0).mean()
 
162
  return md
 
163
 
 
164
 
 
165
def match_dist1b(descr1, descr2,subdist=scipy.spatial.distance.cosine):
 
166
  ##
 
167
  ## The distance is simply the sum of the minimal distances
 
168
  import scipy.spatial
 
169
  if (len(descr1)==0):
 
170
    return numpy.inf
 
171
  if (len(descr2)==0):
 
172
    return numpy.inf
 
173
  #print type(descr1),type(descr2),descr1.shape, descr2.shape
 
174
  md=scipy.spatial.distance.cdist(descr1,descr2,subdist).min(axis=1).cumprod()[-1]
 
175
  return md
 
176
 
 
177
 
 
178
def match_dist1x(descr1, descr2):
 
179
  ##
 
180
  ## The distance is simply the number of unmatched descriptors...
 
181
  ##
 
182
  #print "sh1",descr1.shape
 
183
  #print "sh2",descr2.shape
 
184
  #print "[",descr1.shape[0],descr2.shape[0]
 
185
  nmatch=SiftMatchGPU(descr1,descr2).shape[0]
 
186
  #print nmatch,"]"
 
187
  print "NM=",nmatch
 
188
  maxmatch=min(descr1.shape[0],descr2.shape[0])
 
189
  return 1.-(nmatch/maxmatch)
 
190
 
 
191
 
 
192
 
 
193
def match_dist2(descr1, descr2):
 
194
  ##
 
195
  ## Other possibility we care only on the number of match
 
196
  ##
 
197
  nmatch=SiftMatchGPU(descr1,descr2).shape[0]
 
198
  return (nmatch+1)**-1
 
199
 
 
200
def match_dist3(kpdescr1, kpdescr2):
 
201
  ##
 
202
  ## Other possibility we care only on the number of match
 
203
  ##
 
204
  
 
205
  ##
 
206
  ## We also care about the diversity  of the directions....
 
207
  ## 
 
208
  kp1,descr1=kpdescr1
 
209
  kp2,descr2=kpdescr2  
 
210
  match=SiftMatchGPU(descr1,descr2)
 
211
  nmatch=match.shape[0]
 
212
  if nmatch==0:
 
213
    return numpy.inf
 
214
  dirvec=kp2[match[numpy.arange(nmatch),1]]-kp1[match[numpy.arange(nmatch),0]]
 
215
  #xm=dirvec.mean(axis=0)
 
216
  xs=dirvec.std(axis=0).mean()
 
217
  ##
 
218
  ##
 
219
  ## the smaler xs is the better the approximation is
 
220
  return xs**(nmatch) #**-1
 
221
 
 
222
  
 
223
if __name__=="__main__":
 
224
  import time
 
225
  for i in range(60):
 
226
    a,b=SiftGPU().process(scipy.lena())
 
227
    print a,a.min(axis=0),a.max(axis=0)#,b,i
 
228
    #print a.shape,b.shape,time.clock(),i
 
229
  
 
 
b'\\ No newline at end of file'