toarray method with Android

asked 2015-05-18 15:49:20 -0500

MiloOdin gravatar image

Hi All,

I am developing a mobile app and have run into a problem on android.

I have a function that captures a face using opencv (Unity wrapper asset) whcih calls ToArray().

This works perfectly fine on PC/Mac, getting 300fps and fine on iphone6 around 40fps but for some reason all my android devices even the pretty powerful htc one m8 are getting 10fps, with 150ms to do this one Ienumerator.

Has anyone experienced problems with opencv and Android speciifcally, and is there a better way to run the function on android?

Most of the code is currently commented out to find the culprit, which seems to be the rects = _faces.ToArray() call which is converting _faces matirx to and array.

// Update is called once per frame void Update () { //Make sure we've initialised. if ((_initDone) && (!_capturingFace)) { StartCoroutine ("CaptureFace"); } }

private IEnumerator CaptureFace() {
    _capturingFace = true;

    // Make sure that the texture has been correctly formated, if not we'll have to come back later.
    if (_webCamTexture.width > 16 && _webCamTexture.height > 16) {

        // Pass the web cam texture to a OpenCV matrix
        Utils.webCamTextureToMat (_webCamTexture, _rgbaMat, _colors);

        // iPhones buggering about with mirroring again...
        #if UNITY_IPHONE && !UNITY_EDITOR
        // Flip if neccessary
        if (_webCamTexture.videoVerticallyMirrored){
            if(isFrontFacing){
                Core.flip (_rgbaMat, _rgbaMat, 1);
            }else{
                Core.flip (_rgbaMat, _rgbaMat, 0);
            }
        }else{
            if(isFrontFacing){
                Core.flip (_rgbaMat, _rgbaMat, -1);
            }
        }
        #endif

        // Convert the rgb web texture matrix to gray
        Imgproc.cvtColor (_rgbaMat, _grayMat, Imgproc.COLOR_RGBA2GRAY);

        // Adjust the contrast - this can impact performance, try without for faster performance
        Imgproc.equalizeHist (_grayMat, _grayMat);

        // Set the cascade to detect different sized targets
        if (_cascadeFace != null)
            _cascadeFace.detectMultiScale (_grayMat, _faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                                           new Size (_webCamTexture.width * 0.15, _webCamTexture.width * 0.15), new Size ());

        //.Reset();
        sw.Start();
        Debug.Log("0 "+sw.ElapsedMilliseconds);
        AddToDebug ("0 "+sw.ElapsedMilliseconds);
        // Create an array of OpenCV rectangles from the array of faces.
        rects = _faces.toArray ();
        Debug.Log("1 "+sw.ElapsedMilliseconds);
        AddToDebug ("1 "+sw.ElapsedMilliseconds);
        // Find a mouth in each face each face.
        _faceFound = false;

        Debug.Log ("rects length "+rects.Length);
edit retag flag offensive close merge delete

Comments

After further testing using sw after each call it is the detectmultiscale that is taking the largest cpu time. Anyone know of a different function to use that is quicker?

MiloOdin gravatar imageMiloOdin ( 2015-05-19 05:44:40 -0500 )edit