{"id":44,"date":"2009-08-27T05:42:00","date_gmt":"2009-08-27T05:42:00","guid":{"rendered":"http:\/\/pkmital.com\/home\/?p=44"},"modified":"2009-08-27T05:42:00","modified_gmt":"2009-08-27T05:42:00","slug":"siftgpu-cgglslcuda-for-matlab","status":"publish","type":"post","link":"https:\/\/pkmital.com\/home\/siftgpu-cgglslcuda-for-matlab\/","title":{"rendered":"SiftGPU (Cg\/GLSL\/CUDA) for Matlab"},"content":{"rendered":"<p><a href=\"http:\/\/www.cs.unc.edu\/%7Eccwu\/siftgpu\/\">Changchang Wu has a beautiful implementation<\/a> of <a href=\"http:\/\/people.cs.ubc.ca\/%7Elowe\/keypoints\/\">David Lowe&#8217;s scale invariant feature transform (SIFT)<\/a> inspired by <a href=\"http:\/\/www.vlfeat.org\/%7Evedaldi\/code\/siftpp.html\">Andrea Vedaldi&#8217;s        sift++<\/a> and Sudipta N Sinha et al&#8217;s  GPU-SIFT.  <a href=\"http:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectId=18441&amp;objectType=File\">Adam Chapman has also made a MATLAB mex version<\/a> which will allow you to pass in the filename of an image and retrieve the SIFT descriptors and keys as well as perform the matching. If that sounds like a lot of people have implemented this algorithm, then <a href=\"http:\/\/people.csail.mit.edu\/albert\/ladypack\/wiki\/index.php\/Known_implementations_of_SIFT\">check this out<\/a>.<\/p>\n<p>I had tried using <a href=\"http:\/\/www.mathworks.co.uk\/matlabcentral\/fileexchange\/18441\">Adam Chapman&#8217;s version<\/a> though, unfortunately, I already had my images loaded into the MATLAB workspace after performing some manipulations and didn&#8217;t want to keep writing\/reading from disk, thinking that it would be a waste of computation time.  I was also processing a lot of images in turn and was running into a lot of crashes, perhaps from continually loading and unloading the library?  I haven&#8217;t seen anyone complain about this version on the mathworks site, so maybe it is just me.<\/p>\n<p>In finding a way to avoid writing and reading to disk, I did not foresee a problem in the way MATLAB and OpenGL handle their image data.  After a brief exchange with Changchang Wu, he led me on to the problem of needing the data in row major as opposed to column major format.  As it turns out, the overhead of converting the image to row major is slightly worse than writing and reading the image to disk (at least for an 800&#215;600 with jpeg compression) with the SiftGPU library.  Though, there is probably a better way of doing this than in MATLAB, (like most tasks).<\/p>\n<p>Not all is lost though (I could have been sleeping!), I slipped in another simple extension of Adam Chapman&#8217;s build which will allow you to keep the SiftGPU library loaded in memory and process as many images as you like without fear of crashing (or is it just me?).  I&#8217;ve also included a demo app which shows how to do this for a grayscale and rgb image and shows the results in timing on a few different ways of finding the sift features.  It also includes V340 of the SiftGPU library which will let you do matching on the GPU!<\/p>\n<p>You can download it <a href=\"http:\/\/code.google.com\/p\/siftgpu\/\">here<\/a>.<\/p>\n<p><strong>[update 25\/10\/10]: \u00a0you can get an updated download with the yasift files <a href=\"http:\/\/code.google.com\/p\/siftgpu\/downloads\/detail?name=yasiftgpu.zip\">here<\/a>.<\/strong><\/p>\n<p>To run, first compile:<\/p>\n<blockquote style=\"font-family: courier new;\"><p>&gt;&gt; mex -setup<br \/>\n&gt;&gt; mex -c yasift.cpp<br \/>\n&gt;&gt; mex yasift.cpp<\/p><\/blockquote>\n<p>Now try out the demos:<\/p>\n<blockquote style=\"font-family: courier new;\"><p>&gt;&gt; yasiftdemo<br \/>\n&gt;&gt; yasiftmatchdemo<\/p><\/blockquote>\n<p>The general idea is to first open or initialize the library by doing:<\/p>\n<blockquote style=\"font-family: courier new;\"><p>&gt;&gt; yasift(&#8216;open&#8217;)<\/p><\/blockquote>\n<p>Then you can set the parameters like so (check out Adam Chapmans .doc file for possible settings):<\/p>\n<blockquote style=\"font-family: courier new;\"><p>&gt;&gt; yasift({&#8216;e&#8217;, &#8217;10&#8217;, &#8230;.})<\/p><\/blockquote>\n<p>Now you are ready to process any images:<\/p>\n<blockquote><p><span style=\"font-family: courier new;\">&gt;&gt; img = imread(&#8216;frame0.jpg&#8217;);<\/span><br \/>\n<span style=\"font-family: courier new;\">&gt;&gt; [desc keys] = yasift(img);<\/span><br \/>\n<span style=\"font-family: courier new;\"> &gt;&gt; [desc keys] = yasift(&#8216;frame1.jpg&#8217;);<\/span><br \/>\n<span style=\"font-family: courier new;\"> &gt;&gt; [desc keys] = yasift(&#8216;frame2.jpg&#8217;);<\/span><br \/>\n<span style=\"font-family: courier new;\"> &gt;&gt; [desc keys] = yasift(&#8216;frame3.jpg&#8217;);<br \/>\n<\/span><\/p><\/blockquote>\n<p>You can also do matching by passing in two images at once:<br \/>\n<span style=\"font-family: courier new;\"> <\/span><\/p>\n<blockquote><p><span style=\"font-family: courier new;\">&gt;&gt; img1 = imread(&#8216;frame0.jpg&#8217;);<\/span><br \/>\n<span style=\"font-family: courier new;\">&gt;&gt; img2 = imread(&#8216;frame1.jpg&#8217;);<\/span><br \/>\n<span style=\"font-family: courier new;\">&gt;&gt; [desc1 keys1 desc2 keys2 matches] = yasift(img1, img2);<\/span><\/p><\/blockquote>\n<p>When you are done, unload the library:<\/p>\n<blockquote style=\"font-family: courier new;\"><p>&gt;&gt; yasift(&#8216;destroy&#8217;)<\/p><\/blockquote>\n<p>I sometimes find that the actual mex file is still in memory and can be cleared with a <span style=\"font-family: courier new;\">clear all <\/span>command.<\/p>\n<p>Hope it works for you<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Changchang Wu has a beautiful implementation of David Lowe&#8217;s scale invariant feature transform (SIFT) inspired by Andrea Vedaldi&#8217;s sift++ and Sudipta N Sinha et al&#8217;s GPU-SIFT. Adam Chapman has also&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[96,169,181,224,314,329],"class_list":["post-44","post","type-post","status-publish","format-standard","hentry","category-computer-vision","tag-cuda","tag-gpu","tag-i-hate-matlab","tag-matlab","tag-sift","tag-source-code"],"acf":[],"_links":{"self":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/posts\/44","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/comments?post=44"}],"version-history":[{"count":0,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/posts\/44\/revisions"}],"wp:attachment":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/media?parent=44"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/categories?post=44"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/tags?post=44"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}