File Exchange

image thumbnail

OpenSURF (including Image Warp)

version (706 KB) by Dirk-Jan Kroon
SURF (Speeded Up Robust Features) image feature point detection / matching, as in SIFT


Updated 06 Sep 2010

View License

This function OPENSURF, is an implementation of SURF (Speeded Up Robust Features). SURF will detect landmark points in an image, and describe the points by a vector which is robust against (a little bit) rotation ,scaling and noise. It can be used in the same way as SIFT (Scale-invariant feature transform) which is patented. Thus to align (register) two or more images based on corresponding points (see example3.m), or make 3D reconstructions.

This Matlab implementation of Surf is a Matlab optimized translation of the OpenSurf C# code of Chris Evans, and gives exactly the same answer. Chris Evans wrote one of the best, well structured all inclusive SURF implementations. On his site you can find Evaluations of OpenSURF and the C# and C++ code.
Chris Evans gave me permisson to publish this code under the (Mathworks) BSD license.

Usage :
Ipts = OpenSurf(I, Options)

I : The 2D input image color or greyscale
Options : A struct with options (see below)

Type "help OpenSurf" or "doc OpenSurf" for a basic surf example, and try the example2.m and example3.m for more advanced point matching and affine registration examples.

If you want to use opensurf for nonrigid registration, see "B-spline Grid, Image and Point based Registration" on Mathworks.

Please leave a comment if you find a bug, like the code, or have a question. Visit the page of Chris Evans if you want more detailed information about the algorithm.

Cite As

Dirk-Jan Kroon (2020). OpenSURF (including Image Warp) (, MATLAB Central File Exchange. Retrieved .

Comments and Ratings (80)

simo kim

I think there is something wrong with Dxx because the application of the box filter is not aligned and centered on target pixels....however, this code is good to really understand the theory of SURF, if in case you do not understand the original paper.

Yongkai liu

Now are trying. Hope it can solve my problem!

I'm looking for a way to limit the number of interest points that comes out to the top 50 (for example). Are they sorted by importance or is there a way to get or calculate the strength of an interest point?



This an excellent bit of code and I have used it before for co-registering photos. However, I am having issues with it today. I am sure the code itself is fine but I am getting an error:
Reference to non-existent field 'descriptor'.

Error in example2 (line 11)
D1 = reshape([Ipts1.descriptor],64,[]);

The only way I can think this is happening is that no tie points have been found. Could there be any reason why that might be? I did have to resample my images to a coarser resolution so that they would not exceed my PCs memory (I am working with large orthophotos created from drone imagery). Could this influence the algorithm? Any advice would be much appreciated. Kind Regards,

Misbah Abid

Kindly guide me about this error
Error using OpenSurf (line 82) iimg=IntegralImage_IntegralImage(img);
Not enough input arguments.

Kevin Kevin

Why it is getting fail to detect same keypoints if the input image contains copy of a part of its own.

shaoyu chen


Yoshi Ri


There are Many bugs in this code. Do not use it as it is



I have one question about the mapping of Surf feature in example3.m.
I think the matching strategy is not good. It is different from matching algorithm is vl_feat vl_ubcmatch function.

Simply sort based on the L2 norm is not a good idea. Actually choosing the ratio of second nearest distance and first nearest distance is a good idea.

Can't seem to get the OpenSurf function work. Getting multiple errors.
Error using \
Linear algebra is not supported for integer data types.
To compute elementwise LDIVIDE, use LDIVIDE (.\) instead.
Error in FastHessian_interpolateExtremum (line 24)
Of = - H\D;
Am I doing something wrong ?

Han zid

Great Job , but I have a question , why do you fixed the number of matchinf manually ( 30 points), and how to keep automatically only the number of correct matching, once there is an incorrect matching, return to the last correct matching and break the loop. how to know this number, is Type d'ecart or variance or something else help to do this?? if someone can Help me in code I will be grateful, I'm stuck here.



I selected two other images But it shows an error like
??? Reference to non-existent field 'descriptor'.

Error in ==> example3 at 13
D1 = reshape([Ipts1.descriptor],64,[]);

How can i rectify it pleas help me


How to Calculate the time of matching?

How to Calculate the number of features?

How to Calculate the percentage of matching?

Please help me, I worked on the graduation project comparison between two algorithm ( SURF AND SIFT)


Does anybody know how to observe the responses of a concrete point of an image? I don't know how to fix the filter to observe it etc. Thank you!


Once I run OpenSurf on the two images, and find all the matching points I run into:

1) some lines are correct (60%)
2) some lines are incorrect (40%)

I would like to continue the code to:

1) Take the group of lines that are most a like, in this case group 1 is 60%. is is the majority.

2) overlay the two images where they overlap.

How do I access the points to perform this? Any help or brainstorming would save me great lengths.

Thank you very much everyone.


Dear Dirk-Jan-Kroon

When interpolation scale I dont know why you multiple by 2/15. Could you explain what it means?


Peter Bone


Dear Dirk-Jan Kroon,

could you help me how to count correspondence points in example2.m so we could determine percentage of it's match? Thanks

best regards,

Hardian O.

Nice Job..
After Getting the Interest Points how we use that... Please tell all available ways u know?


Great Job ! It;s been really helpful ! thanks !
I am trying to modify the code for use in 3D . I have a problem understanding the function fastHessian_getResponse . Could you please give a little description on it so i would know what should be expected from this part so I would know how to change it for 3D ?


Should line 58 in SurfDescriptor_GetOrientation be corrected as follows? (change pi to 2*pi)

check2= (ang2 < ang1) & ( ((Ang > 0) & (Ang < ang2)) | ((Ang > ang1) & (Ang < pi)) );


check2= (ang2 < ang1) & ( ((Ang > 0) & (Ang < ang2)) | ((Ang > ang1) & (Ang < 2*pi)) );

Good job I have benefited it a lot

But I have a question:

How to Calculate the time of matching?

How to Calculate the number of features?

How to Calculate the percentage of matching?

Please help me, I worked on the graduation project comparison between two algorithm ( SURF AND SIFT)

opensurf gives us keypoints and features .i generate code for matching these features in an image for duplication detection. but my code is not working properly in all images of my dataset. it gives result in some images .what can i do ?please reply

I found a solution. I just used MATLABs tranformation functions from Image Processing Toolbox

my_M = cp2tform(Pos1(:,1:2) ,Pos2(:,1:2),'affine');
my_warped = imtransform(I1,my_M);


I tried to run example 3 with a re-sized source image (scaled 0.5 time).
After fixing some of the plotting issues, openSURF seems to find correct features, but the warped image is "cropped" at the top-left corner (but upright).
I then un-commented the following lines in affine_warp.m:
mean= size(Iin)/2;

now the warped image is cropped around the center of the image (and upright).

any hints?


I want to search for similarities in one image using OpenSURF implementation. would you please help me how I can group identical SURF features (matching them) and display the resulting imge with matched regions? Please give me any suggestions

Pan Ou




Dear Dirk-Jan Kroon,

While getting into your code, I got an impression that Gasp below (26 May 2011 ) is correct:
"I'm quit sure there is a little mistake in FastHessian_buildResponseLayer line 31-32 : instead of "b" I think it should be "b-1" ; could someone confirm or invalidate?"
I would like to clarify, that on my oppinion, "r - b" should be replaced with "r-b+1", and "c-b" should be replaced with "c-b+1"
Thank you.


May i know how to get the x-y coordinates for the feature points detected using OPENSURF.

i Need to store in a array

hi, i'm having a trouble with the code; it's detecting points which lie on the background of a logical image. Can you tell why?

Royi Avital

@Youssra, 'row' and 'col' are the row and column index of the top left corner of a rectangle.
'rows' and 'cols' are the number of rows / columns in the rectangle.


any one know??!!


hi, thank you Mr Kroon for the code, but i have a question!! what it is the difference between row , col and rows , cols in the function IntegralImage_BoxIntegral..??
thank's again

Royi Avital

Are there any updates which follows Chris's code?

hi all, do anyone know that in the function orientation=SurfDescriptor_Getorientation, the gauss25 is come from where?do anyone know it?urgent need the information...thx a lot..


Great code, thank you a lot Mr Kroon.
I have one problem with the function affine_warp.m :
When I choose a different size for the output image of the image_interpolation.m function I get the error
??? Error using ==> reshape
To RESHAPE the number of elements must not change.

Error in ==> affine_warp>image_interpolation at 241
Iout(:,:,i)=reshape(Iout_one, ImageSize);

Error in ==> affine_warp at 64
Iout=image_interpolation(Iin,Tlocalx,Tlocaly,Interpolation,Boundary,[200 200]);

Is it something that can be solved? I want to display the whole transformed image. In case I use the original size, I loose part of the transformed image.

Thank you in advance,


Your Code is very Good! but can you tell me that i have different dimension images and i want to apply surf on that, and if i do it gives me the following error--> ??? Subscripted assignment dimension mismatch.

Error in ==> example2 at 27
I(:,1:size(I1,2),:)=I1; I(:,size(I1,2)+1:size(I1,2)+size(I2,2),:)=I2;
can you resolve this for me?


is it possible to limit somehow the number of feature points to be extracted by OpenSURF, I mean is it possible to extract e.g. at most 50 points or so? how to do that?

Hi all.

Dirk-Jan, thanks very much for your work on this. It was very useful for me, but I would like to point out a design flaw I encountered. In case someone just needs to use U-Surf (the upright version of surf), you still compute the orientation of each point prior to producing the descriptor, although it is not needed at all - and the computational overhead is somewhat significant.

So, I would suggest the following change to whoever is interested.

In file SubFunctions/SurfDescriptor_DescribeInterestPoints at line 32, I changed



if ~upright ip.orientation=SurfDescriptor_GetOrientation(ip,img,verbose);

and then I also removed


from line 38.


To Sarhat: You simply work with too big images. Read You might try to optimize the code by deleting big variables as soon as possible by the command "clear('varName')", but it's probably not worth the effort.


Hello Everyone

I am new to Matlab and I used Opensurf for feature matching between two images. the original image is (4064x2704)pixels. I used resize the images to lower resolution and OpenSurf perfectly working (Thanks for the Author) but when I used the original images size I got the following errors...
??? Out of memory. Type HELP MEMORY for your options.

Error in ==> IntegralImage_IntegralImage at 31

Error in ==> OpenSurf at 82
is there ant idea please or suggestion...

Martin cho

lovely good!! thanks.

could'nt understand


Hi , i am trying to implement SURF 36 , can i have any help to get this through this code


this matlab code takes 2.98 seconds for the example picture.kindly sufggest how to minimze the time



km g

sorry there is something i could not understand. During the descriptor part we need to extract 25 sample points for each region right?but is one sample point equals to one pixel?how if the scale is getting bigger?can anyone who is very familiar with SURF can answer my question?i really feel confused about that. Hope to get ur reply in my email address




Kyle: use ransac with a similarity transform.


Hi every1,

Does any1 know how to extract the scale n rotation translation between 2 image from opensurf?



Hi evryone,

I'm quit sure there is a little mistake in FastHessian_buildResponseLayer line 31-32 : instead of "b" I think it should be "b-1" ; could someone confirm or invalidate?


Peng Li

Dear Kroon, I am using it for object detection, however, it doesn't work because the object is small (e.g. 30 * 50). In contrast, the SIFT can works well. So I think there are some places of improment

Peng Li

Athough there are some limitations, i think it's useful for me, as a counterpart to SIFT.

piet fue


I need to extract only feature vectors, how can I do this using SURF?


pls assist me in working with SURF...


sorry, why u use 30 best matches points and if i want to use ratio divide matches points ex. err< 0.5 <<<< ratio
how to modifier


Nam Le

Great implementation

Thank you for your code-hint! I can use it in almost all my code to speed up :-) .


In Example 2 you can write shortly
This 2 rows
D1 = zeros([64 length(Ipts1)]);
for i=1:length(Ipts1), D1(:,i)=Ipts1(i).descriptor; end
D1 = reshape([Ipts1.descriptor],64,[]);

*worker_matlab Ness,
Yes, there is documentation on the website of

Implementation description in, "Notes on the OpenSURF Library". Also a view papers with reviews of OpenSurf are available there.

wonderful work, there is a complete documentation?


Still same error code. Would you please tell me how to run this?
Thank you very much.

Strange error. I don't think it is a bug in OpenSurf.

Maybe you can solve this by using
I = imread(('example.jpg','jpg') instead of I=imread('example.jpg') in your code.


Sorry, the error code as below. I don't know why?
Matlab version:2008a

?? Maximum recursion limit of 500 reached. Use
to change the limit. Be aware that exceeding your available stack
space can
crash MATLAB and/or your computer.

Error in ==> imformats>find_in_registry

Ah. thanks

Thank you for your comment. With the default option setting, the minimum size of the image is 256 x 256.
If you reduce the octaves you can use a smaller size, minsize = 2^Options.octaves*8 .
I will build a check in a new version.



Toolbox looks nice, but

feats = openSurf(randn(49,285));


??? Index exceeds matrix dimensions.

Error in ==> FastHessian_isExtremum>FastHessian_getResponse at 44
an=a.responses(fix(scale*row) * a.width + fix(scale*column)+1);

Error in ==> FastHessian_isExtremum at 25
candidate = FastHessian_getResponse(m,r,c,t);

Any ideas?

I have optimized the Matlab code, replacing all for-loops by 1D and 2D indexing. This version takes less then 1 sec for the example picture.
The original C# version is only 2x as fast for large images.
Of course a mex file is faster, but this Matlab code is easier to study, debug, and doesn't need external libraries or compilers.

(Tomorrow a new version wil be online were I fixed a small bug in the image display function)


Using the example image test.png I got

>> tic; Ipts=OpenSurf(I); toc;
Elapsed time is 11.341135 seconds

This is way too slow to be useful. The whole point of SURF is its speed, so a MEX interface is essential.


Updated example see comment "Evgeny". Added Affine image transformation example.

Now always works for small images. Added verbose information option.

Fixed small bug in paint function

Speed Up 10x ...

MATLAB Release Compatibility
Created with R2010a
Compatible with any release
Platform Compatibility
Windows macOS Linux