2016-08-19 64 views
0

我最近開始在Android Studio上開發應用程序,並且剛完成編寫代碼。我得到的準確性比令人滿意的多,但設備所用的時間是lot。 {}我跟着一些關於如何監視android studio性能的教程,我看到我的代碼的一小部分正在拍攝6秒,其中我的應用程序需要一半時間來顯示整個結果。我在OpenCV/JavaCV上看到很多帖子Java OpenCV - extracting good matches from knnMatch,OpenCV filtering ORB matches,但沒有遇到任何人提出這個問題。 OpenCV鏈接http://docs.opencv.org/2.4/doc/tutorials/features2d/feature_homography/feature_homography.html確實提供了一個很好的教程,但與C++相比,OpenCV中的RANSAC函數爲關鍵點提供了不同的參數。OpenCV for Android中的性能問題Keypoint匹配和使用ORB和RANSAC的閾值

這裏是我的代碼

 public Mat ORB_detection (Mat Scene_image, Mat Object_image){ 
    /*This function is used to find the reference card in the captured image with the help of 
    * the reference card saved in the application 
    * Inputs - Captured image (Scene_image), Reference Image (Object_image)*/ 
    FeatureDetector orb = FeatureDetector.create(FeatureDetector.DYNAMIC_ORB); 
    /*1.a Keypoint Detection for Scene Image*/ 
    //convert input to grayscale 
    channels = new ArrayList<Mat>(3); 
    Core.split(Scene_image, channels); 
    Scene_image = channels.get(0); 
    //Sharpen the image 
    Scene_image = unsharpMask(Scene_image); 
    MatOfKeyPoint keypoint_scene = new MatOfKeyPoint(); 
    //Convert image to eight bit, unsigned char 
    Scene_image.convertTo(Scene_image, CvType.CV_8UC1); 
    orb.detect(Scene_image, keypoint_scene); 
    channels.clear(); 

    /*1.b Keypoint Detection for Object image*/ 
    //convert input to grayscale 
    Core.split(Object_image,channels); 
    Object_image = channels.get(0); 
    channels.clear(); 
    MatOfKeyPoint keypoint_object = new MatOfKeyPoint(); 
    Object_image.convertTo(Object_image, CvType.CV_8UC1); 
    orb.detect(Object_image, keypoint_object); 

    //2. Calculate the descriptors/feature vectors 
    //Initialize orb descriptor extractor 
    DescriptorExtractor orb_descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB); 
    Mat Obj_descriptor = new Mat(); 
    Mat Scene_descriptor = new Mat(); 
    orb_descriptor.compute(Object_image, keypoint_object, Obj_descriptor); 
    orb_descriptor.compute(Scene_image, keypoint_scene, Scene_descriptor); 

    //3. Matching the descriptors using Brute-Force 
    DescriptorMatcher brt_frc = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); 
    MatOfDMatch matches = new MatOfDMatch(); 
    brt_frc.match(Obj_descriptor, Scene_descriptor, matches); 

    //4. Calculating the max and min distance between Keypoints 
    float max_dist = 0,min_dist = 100,dist =0; 
    DMatch[] for_calculating; 
    for_calculating = matches.toArray(); 
    for(int i = 0; i < Obj_descriptor.rows(); i++) 
    { dist = for_calculating[i].distance; 
     if(dist < min_dist) min_dist = dist; 
     if(dist > max_dist) max_dist = dist; 
    } 

    System.out.print("\nInterval min_dist: " + min_dist + ", max_dist:" + max_dist); 
    //-- Use only "good" matches (i.e. whose distance is less than 2.5*min_dist) 
    LinkedList<DMatch> good_matches = new LinkedList<DMatch>(); 
    double ratio_dist=2.5; 
    ratio_dist = ratio_dist*min_dist; 
    int i, iter = matches.toArray().length; 
    matches.release(); 

    for(i = 0;i < iter; i++){ 
     if (for_calculating[i].distance <=ratio_dist) 
      good_matches.addLast(for_calculating[i]); 
    } 
    System.out.print("\n done Good Matches"); 

    /*Necessary type conversion for drawing matches 
    MatOfDMatch goodMatches = new MatOfDMatch(); 
    goodMatches.fromList(good_matches); 
    Mat matches_scn_obj = new Mat(); 
    Features2d.drawKeypoints(Object_image, keypoint_object, new Mat(Object_image.rows(), keypoint_object.cols(), keypoint_object.type()), new Scalar(0.0D, 0.0D, 255.0D), 4); 
    Features2d.drawKeypoints(Scene_image, keypoint_scene, new Mat(Scene_image.rows(), Scene_image.cols(), Scene_image.type()), new Scalar(0.0D, 0.0D, 255.0D), 4); 
    Features2d.drawMatches(Object_image, keypoint_object, Scene_image, keypoint_scene, goodMatches, matches_scn_obj); 
    SaveImage(matches_scn_obj,"drawing_good_matches.jpg"); 
    */ 

    if(good_matches.size() <= 6){ 
     ph_value = "7"; 
     System.out.println("Wrong Detection"); 
     return Scene_image; 
    } 
    else{ 
     //5. RANSAC thresholding for finding the optimum homography 
     Mat outputImg = new Mat(); 
     LinkedList<Point> objList = new LinkedList<Point>(); 
     LinkedList<Point> sceneList = new LinkedList<Point>(); 

     List<org.opencv.core.KeyPoint> keypoints_objectList = keypoint_object.toList(); 
     List<org.opencv.core.KeyPoint> keypoints_sceneList = keypoint_scene.toList(); 

     //getting the object and scene points from good matches 
     for(i = 0; i<good_matches.size(); i++){ 
      objList.addLast(keypoints_objectList.get(good_matches.get(i).queryIdx).pt); 
      sceneList.addLast(keypoints_sceneList.get(good_matches.get(i).trainIdx).pt); 
     } 
     good_matches.clear(); 
     MatOfPoint2f obj = new MatOfPoint2f(); 
     obj.fromList(objList); 
     objList.clear(); 

     MatOfPoint2f scene = new MatOfPoint2f(); 
     scene.fromList(sceneList); 
     sceneList.clear(); 

     float RANSAC_dist=(float)2.0; 
     Mat hg = Calib3d.findHomography(obj, scene, Calib3d.RANSAC, RANSAC_dist); 

     for(i = 0;i<hg.cols();i++) { 
      String tmp = ""; 
      for (int j = 0; j < hg.rows(); j++) { 

       Point val = new Point(hg.get(j, i)); 
       tmp= tmp + val.x + " "; 
      } 
     } 

     Mat scene_image_transformed_color = new Mat(); 
     Imgproc.warpPerspective(original_image, scene_image_transformed_color, hg, Object_image.size(), Imgproc.WARP_INVERSE_MAP); 
     processing(scene_image_transformed_color, template_match); 

     return outputImg; 
    } 
} } 

,這部分是什麼正在6秒上運行時實現 -

LinkedList<DMatch> good_matches = new LinkedList<DMatch>(); 
    double ratio_dist=2.5; 
    ratio_dist = ratio_dist*min_dist; 
    int i, iter = matches.toArray().length; 
    matches.release(); 

    for(i = 0;i < iter; i++){ 
     if (for_calculating[i].distance <=ratio_dist) 
      good_matches.addLast(for_calculating[i]); 
    } 
    System.out.print("\n done Good Matches");} 

我想可能是我可以寫在這部分代碼C++使用NDK,但我只是想確保語言是問題而不是代碼本身。 請不要嚴格,第一個問題!任何批評都非常感謝!

+0

蠻力匹配是'O(n^2)',所以要麼使用更快的匹配方法(FLANN),要麼可以減少關鍵點的數量。但是特徵提取本身可能相當昂貴。我懷疑切換到C++會給opencv函數帶來好處(可能它們會啓動一些C二進制文件?),但我從來沒有嘗試過...... – Micka

+0

您在圖像上提取了多少個關鍵點? – Micka

+0

我會說它更可能是檢測部分的圖像分辨率。 OpenCV中ORB的默認功能數量爲500,我在2012年1ms內對Nexus 4進行了蠻力匹配,以進行實時跟蹤。 – Photon

回答

0

所以問題是logcat給了我錯誤的計時結果。滯後是由於後來在代碼中出現巨大的高斯模糊。我用System.currentTimeMillis代替了System.out.print,它向我展示了這個錯誤。