Xamarin.Android.OpenCV icon indicating copy to clipboard operation
Xamarin.Android.OpenCV copied to clipboard

OpenCVLoader.InitAsync on Class. how to implement it?

Open MarcoSal opened this issue 7 years ago • 0 comments

I'm creating a solution (visual studio 2017) to perform Feature Matching. I use Xamarin.forms and then I use the dependent service under android to use the OpenCV Binding. I do not know how to write the 'OpenCVLoader.InitAsync' tool. The code seems to work well even without it ... The code is:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Graphics;

using OpenCV.Features2d;
using OpenCV.ImgCodecs;
using OpenCV.Core;
using OpenCV.Android;
using OpenCV.ImgProc;
using OpenCV.Utils;

using SmartRoadInventory.Droid;
using Xamarin.Forms;

[assembly: Dependency(typeof(dsImageMatch))]

namespace SmartRoadInventory.Droid
{
    class dsImageMatch : IPictureMatch
    {

        public async Task<List<Int32>> MatchImages(Stream strm)
        {
            // Define the Intent for getting images
            long matchTime;

            if (!OpenCVLoader.InitDebug())
            {
                Android.Util.Log.Debug("Image Match", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
                //OpenCVLoader.InitAsync(OpenCVLoader.OpencvVersion310, this, this);
            }
            else
            {
                Android.Util.Log.Debug("Image Match", "OpenCV library found inside package. Using it!");
                //mLoaderCallback.OnManagerConnected(LoaderCallbackInterface.Success);
            }

            Mat img_scene = Imgcodecs.Imread("/storage/emulated/0/Download/Z_image_scene_3.jpg", Imgcodecs.ImreadGrayscale);
            Mat img_object = Imgcodecs.Imread("/storage/emulated/0/Download/Z_image_to_find8.png", Imgcodecs.ImreadGrayscale);
            Mat result = Draw(img_scene, img_object, out matchTime);

            // Return Task object
            List<Int32> array = new List<Int32>();
            array.Add(9);
            //string f = Android.Net.Uri.Parse("android.resource://com.companyname.SmartRoadInventory/" + Resource.Drawable.camera100).Path;

            return array;

        }

        public static Mat Draw(Mat observedImage, Mat modelImage, out long matchTime)
        {
            //Mat homography;
            //MatOfKeyPoint modelKeyPoints;
            //MatOfKeyPoint observedKeyPoints;

            //https://ceciliavision.wordpress.com/2014/12/16/feature-matching-in-android/
            //https://medium.com/@akshikawijesundara/object-recognition-with-opencv-on-android-6435277ab285
            Stopwatch watch;
            watch = Stopwatch.StartNew();

            //https://stackoverflow.com/questions/31835114/feature-detection-with-patent-free-descriptors
            FeatureDetector Orbdetector = FeatureDetector.Create(FeatureDetector.Orb);
            DescriptorExtractor OrbExtractor = DescriptorExtractor.Create(DescriptorExtractor.Orb);
            DescriptorMatcher matcher = DescriptorMatcher.Create(DescriptorMatcher.BruteforceHamming);//BruteforceHamming

            Mat descriptors_object = new Mat();
            MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
            Orbdetector.Detect(modelImage, keypoints_object);
            OrbExtractor.Compute(modelImage, keypoints_object, descriptors_object);

            Mat descriptors_scene = new Mat();
            MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();
            Orbdetector.Detect(observedImage, keypoints_scene);
            OrbExtractor.Compute(observedImage, keypoints_scene, descriptors_scene);

            MatOfDMatch matches = new MatOfDMatch();
            matcher.Match(descriptors_object, descriptors_scene, matches);// to use knnMatch https://stackoverflow.com/questions/35428440/java-opencv-extracting-good-matches-from-knnmatch
            JavaList<DMatch> matchesList = (JavaList<DMatch>)matches.ToList();

            //List<MatOfDMatch> knnmatches = new List<MatOfDMatch>();
            //matcher.KnnMatch(descriptors_object, descriptors_scene, knnmatches, 2);
            //List<MatOfDMatch> matchesList = (List<MatOfDMatch>)knnmatches.ToList();
            List<DMatch> newList = matchesList.OrderByDescending(x => x.Distance).Reverse().ToList();
            double media = 0;
            Int32 n = Math.Min(10, newList.Count);
            for (int i = 0; i < n; i++)
            {
                media += (double)newList[i].Distance;

            }
            media = media / n;

            Double max_dist = 0.0;
            Double min_dist = 100000000.0;

            for (int i = 0; i < descriptors_object.Rows(); i++)
            {
                Double dist = (double)matchesList[i].Distance;
                if (dist < min_dist)
                    min_dist = dist;
                if (dist > max_dist)
                    max_dist = dist;
            }
            //gm.FromList(good_matches);

            List<DMatch> good_matches = new List<DMatch>();//determina i punti buoni. più sono, meglio è, comparati ad altre elaborazioni
            List<DMatch> good_matches2 = new List<DMatch>();//determina i punti buoni. più sono, meglio è, comparati ad altre elaborazioni
            for (int i = 0; i < matchesList.Count; i++)
            {
                if (matchesList[i].Distance <= 60) //(min_dist + (max_dist - min_dist) / 3)) //(2 * min_dist)) nei test sembra che la soglia da considerare sia pari a 40
                    good_matches.Add(matchesList[i]);
                if (matchesList[i].Distance <= (min_dist + (max_dist - min_dist) / 3)) //(2 * min_dist)) nei test sembra che la soglia da considerare sia pari a 40
                    good_matches2.Add(matchesList[i]);

            }

            MatOfDMatch matches_final_mat = new MatOfDMatch();
            matches_final_mat.FromList(good_matches);//trasforma la lista in matrice necessaria alla funzione drawmatches


            //https://huningxin.github.io/opencv_docs/d1/de0/tutorial_py_feature_homography.html
            //https://docs.opencv.org/3.1.0/d7/dff/tutorial_feature_homography.html
            //LinkedList<Core.Point> objList = new LinkedList<Core.Point>();
            //LinkedList<Core.Point> sceneList = new LinkedList<Core.Point>();
            //foreach (DMatch gm in good_matches)
            //{
            //    objList.AddLast(keypoints2.Row(gm.TrainIdx).pt);
            //    sceneList.AddLast(keypoints1.Get(gm.QueryIdx).pt);
            //}

            //https://stackoverflow.com/questions/15544158/error-matching-with-orb-in-android
            Scalar RED = new Scalar(255, 0, 0);
            Scalar GREEN = new Scalar(0, 255, 0);
            //output image
            Mat outputImg = new Mat();
            MatOfByte drawnMatches = new MatOfByte();
            //this will draw all matches, works fine
            Features2d.DrawMatches(modelImage, keypoints_object, observedImage, keypoints_scene, matches_final_mat,
            outputImg, GREEN, RED, drawnMatches, Features2d.NotDrawSinglePoints);

            Mat featuredImg = new Mat();
            Scalar kpColor = new Scalar(255, 159, 10);//this will be color of keypoints
                                                      //featuredImg will be the output of first image
            if (keypoints_object.Rows()>=1) Features2d.DrawKeypoints(observedImage, keypoints_object, featuredImg, kpColor, 0);
            //featuredImg will be the output of first image
            if (keypoints_scene.Rows() >= 1) Features2d.DrawKeypoints(observedImage, keypoints_scene, featuredImg, kpColor, 0);

            watch.Stop();
            matchTime = watch.ElapsedMilliseconds;

            return outputImg;
        }

    }
}

What should I insert in place of 'This, This' to make the statement active:OpenCVLoader.InitAsync(OpenCVLoader.OpencvVersion310, this, this);

Thanks

MarcoSal avatar Jul 09 '18 09:07 MarcoSal