2016-08-19 80 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,它向我展示了这个错误。