This article from http://blog.csdn.net/hellogv/, reference must indicate the source!
Recently, I heard from my friends in the CV field about asift, And then I searched for it and found that asift is more adaptable to perspective changes than sift and is open-source (Web site: http://www.ipol.im/pub/algo/my_affine_sift ), I really want to thank Jean-micel Morel and guoshen Yu for their selfless dedication, so that I can play asift with this hobbyist.
The source code of asift provided by the my_affine_sift project is based on C ++ and uses STL extensively. it is not difficult for developers with C ++ experience to use it. This article mainly encapsulates the source code of asift into DLL, and makes it easier to use asift on Windows and Windows Mobile platforms by using the rich image codec class libraries on the. NET/. Net CF platform.
PS: Since STL objects cannot be transferred between C # And C ++ compiled DLL, processing of STL objects is done in the DLL.
Let's take a look at the implementation results of the Code in this article:
The asift algorithm runs slowly, which is slower than the surf of opencv introduced last time. Therefore, when used on mobile devices, you must sacrifice the accuracy to get the speed, the picture on the left shows the matching result with the lowest recognition rate, and the picture on the right shows the result with a low recognition rate.
The code for this article can be downloaded here: http://www.pudn.com/downloads312/sourcecode/windows/csharp/detail1387079.html
The following is part of the source code of asift_dll.cpp on the DLL end:
PS: Because STL objects cannot be passed, when initializing the first image, the feature set and other long-width data of the first image are saved as static data, if the value is equal to 1, the recognition rate is the lowest.
Static int im_x = 320; <br/> static int im_y = 240; <br/> static vector <keypointslist> keys1; <br/> STD :: vector <float> ipixels1; <br/> static int WS1, HS1, W1, H1; <br/> vector <keypointslist> loadkeypoints (STD :: vector <float> ipixels, int W, int H, int num_of_tilts, int * out_ws, int * out_hs); <br/> matchingslist matchkeypoints (INT num_of_tilts, int WS1, int HS1, int WS2, int hs2, vector <keypointslist> keys1, vector <keypointslist> keys2 ); <br/>/** <br/> * size of the initialized enlarged/reduced image <br/> */<br/> extern "C" _ declspec (dllexport) void initzoomsize (int w, int h) <br/>{< br/> im_x = W; <br/> im_y = h; <br/>}< br/>/** <br/> * calculate the feature set of image 1, and save it in static variables <br/> */<br/> extern "C" _ declspec (dllexport) void initimage1 (float * iarr, int W, int H, int num_of_tilts) <br/>{< br/> W1 = W; <br/> H1 = H; <br/> ipixels1 = STD: vector <float> (iarr, iarr + W * H); <br/> keys1 = loadkeypoints (ipixels1, W, H, num_of_tilts, & WS1, & HS1 ); <br/>}< br/>/** <br/> * calculate the feature set of Image 2 and match it with the feature set of image 1, returns the number of similar features <br/> */<br/> extern "C" _ declspec (dllexport) int match2imagefornum (float * iarr2, int W2, int H2, int num_of_tilts2) <br/>{< br/> int WS2, hs2; <br/> STD: vector <float> ipixels2 (iarr2, iarr2 + W2 * H2 ); <br/> vector <keypointslist> keys2 = loadkeypoints (ipixels2, W2, H2, num_of_tilts2, & WS2, & hs2 ); <br/> // match asift keypoints <br/> matchingslist matchings = matchkeypoints (num_of_tilts2, WS1, HS1, WS2, hs2, keys1, keys2 ); <br/> return matchings. size (); <br/>}< br/>/** <br/> * calculate the feature set of Image 2, match with the feature set of image 1, and return the array of image pixels after comparison. <br/> */<br/> extern "C" _ declspec (dllexport) float * match2imageforimg (float * iarr2, int W2, int H2, int num_of_tilts2, int * outw, int * outh) <br/>{< br/> int WS2, hs2; <br/> STD: vector <float> ipixels2 (iarr2, iarr2 + W2 * H2); <br/> vector <keypointslist> keys2 = loadkeypoints (ipixels2, w2, H2, num_of_tilts2, & WS2, & hs2); <br/> // match asift keypoints <br/> matchingslist matchings = matchkeypoints (num_of_tilts2, WS1, HS1, WS2, hs2, keys1, keys2 ); <br/> ///////// // output image containing line matches (the two images are concatenated one above the other) <br/> int band_w = 10; // insert a black band of width band_w between the two images for better visibility <br/> int Wo = max (W1, W2 ); <br/> int ho = H1 + H2 + band_w; <br/> float areas = im_x * im_y; <br/> float zoom1 = SQRT (W1 * H1) /areas); <br/> floatzoom2 = SQRT (W2 * H2)/areas); <br/> float * opixelsasift = new float [wo * Ho]; <br/> for (Int J = 0; j <(INT) Ho; j ++) <br/> for (INT I = 0; I <(INT) Wo; I ++) opixelsasift [J x WO + I] = 255; <br/> //////////////////////////////////// /// // copy both images to output <br/> for (Int J = 0; j <(INT) H1; j ++) <br/> for (INT I = 0; I <(INT) W1; I ++) opixelsasift [J * wo + I] = ipixels1 [J * W1 + I]; <br/> for (Int J = 0; j <(INT) H2; j ++) <br/> for (INT I = 0; I <(INT) W2; I ++) opixelsasift [(H1 + band_w + J) * wo + I] = ipixels2 [J * W2 + I]; <br/> //////////////////////////////////// ///////////////////////// draw matches <br/> matchingslist:: iterator PTR = matchings. begin (); <br/> for (INT I = 0; I <(INT) matchings. size (); I ++, PTR ++) <br/>{< br/> draw_line (opixelsasift, (INT) (zoom1 * PTR-> first. x), (INT) (zoom1 * PTR-> first. y), <br/> (INT) (zoom2 * PTR-> second. x), (INT) (zoom2 * PTR-> second. y) + H1 + band_w, 255.0f, wo, Ho); <br/>}< br/> * outw = Wo; <br/> * outh = Ho; <br/> return opixelsasift; <br/>}
The following are some source code of C #. On C #, convert the image (JPG, BMP, and PNG) to a grayscale image (an 8-Bit Array) and then transmit it to DLL to calculate the feature points, finally, we matched the feature points of the two graphs and drew the matching results:
Private void btnmatch_click (Object sender, eventargs e) <br/>{< br/> initzoomsize (160,240); <br/> bitmap image1 = new Bitmap (getappdir () + "// adam1.png"); <br/> float [] grayimg1 = imgtogray (image1); <br/> initimage1 (grayimg1, image1.width, image1.height, 2 ); <br/> This. TEXT = "image1 OK, please wait ...... "; <br/> bitmap image2 = new Bitmap (getappdir () +" // adam2.png "); <br/> float [] grayimg2 = imgtogray (image2 ); </P> <p> int width = 0, Height = 0; <br/> intptr result = match2imageforimg (grayimg2, image2.width, image2.height, 2, ref width, ref height ); <br/> bitmap resultimg = intptrtoimg (result, width, height); <br/> This. picturebox1.image = resultimg; <br/> This. TEXT = "finish"; <br/>}