Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/214.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Opencv应用程序慢得令人痛苦,我该怎么办?_Android_Performance_Opencv - Fatal编程技术网

Android Opencv应用程序慢得令人痛苦,我该怎么办?

Android Opencv应用程序慢得令人痛苦,我该怎么办?,android,performance,opencv,Android,Performance,Opencv,我有一个人脸识别应用程序,它运行良好,在s6 egde上的速度为15+fps。现在,当我添加一些代码来确定眼睛中心时(特别是),速度降到了0.01 fps。我卡住了。Android Studio monitor表示cpu使用率约为15%,内存为20MB,分辨率约为400*300。 下面是我用来实现查找眼睛中心算法的代码(翻译自c++): public class TimmAlgorithm { Point unscalePoint(Point p, Rect origSize) {

我有一个人脸识别应用程序,它运行良好,在s6 egde上的速度为15+fps。现在,当我添加一些代码来确定眼睛中心时(特别是),速度降到了0.01 fps。我卡住了。Android Studio monitor表示cpu使用率约为15%,内存为20MB,分辨率约为400*300。 下面是我用来实现查找眼睛中心算法的代码(翻译自c++):

  public class TimmAlgorithm {
  Point unscalePoint(Point p, Rect origSize) {
    float ratio = (((float) kFastEyeWidth)/origSize.width);
    int x = (int)Math.round(p.x / ratio);
    int y = (int)Math.round(p.y / ratio);
    return new Point(x,y);
}

Mat scaleToFastSize( Mat src,Mat dst) {

    Imgproc.resize(src, dst, new Size(kFastEyeWidth,(((float)kFastEyeWidth)/src.size().width) * src.size().height));
    return dst;
}

Mat computeMatXGradient(Mat mat) {
    Mat out=new Mat(mat.size(), CvType.CV_64F);

    for (int y = 0; y < mat.size().height; ++y) {


        out.put(y,0, (mat.get(y,1)[0]-mat.get(y,0)[0]));
        for (int x = 1; x < mat.size().width - 1; ++x) {


            out.put(y,x,mat.get(y,x+1)[0]-(mat.get(y,x-1)[0]/2));

        }


        out.put(y,(int)mat.size().width-1,mat.get(y,(int)mat.size().width-1)[0]-mat.get(y,(int)mat.size().width-2)[0]);
    }

    return out;
}



Mat testPossibleCentersFormula(int x, int y, Mat weight,double gx, double gy, Mat out) {
    // for all possible centers

    for (int cy = 0; cy < out.size().height; ++cy) {


        for (int cx = 0; cx < out.size().width; ++cx) {
            if (x == cx && y == cy) {
                continue;
            }
            // create a vector from the possible center to the gradient origin
            double dx = x - cx;
            double dy = y - cy;
            // normalize d
            double magnitude = Math.sqrt((dx * dx) + (dy * dy));
            dx = dx / magnitude;
            dy = dy / magnitude;
            double dotProduct = dx*gx + dy*gy;
            dotProduct = Math.max(0.0,dotProduct);
            // square and multiply by the weight
            if (kEnableWeight) {


                out.put(cy,cx,out.get(cy,cx)[0] +  dotProduct * dotProduct * (weight.get(cy,cx)[0]/kWeightDivisor));
            } else {


                out.put(cy,cx,out.get(cy,cx)[0]+dotProduct * dotProduct);
            }
        }
    }
    return out;
}

Point findEyeCenter(Mat face, Rect eye,Mat debugwindow) {
   // Mat eyeROIUnscaled = face.submat(eye);
    Mat eyeROI = face.submat(eye);
  //  Mat eyeROI=new Mat();
   // eyeROI=scaleToFastSize(eyeROIUnscaled, eyeROI);

    // draw eye region
    Imgproc.rectangle(face,eye.tl(),eye.br(),new Scalar(255, 0, 0, 255), 2);
    //-- Find the gradient
    Mat gradientX = computeMatXGradient(eyeROI);
    Mat gradientY = computeMatXGradient(eyeROI.t()).t();
    //-- Normalize and threshold the gradient
    // compute all the magnitudes
    Mat mags = matrixMagnitude(gradientX, gradientY);
    //compute the threshold
    double gradientThresh = computeDynamicThreshold(mags, kGradientThreshold);
    //double gradientThresh = kGradientThreshold;
    //double gradientThresh = 0;
    //normalize


    for (int y = 0; y < eyeROI.size().height; ++y) {


        for (int x = 0; x < eyeROI.size().width; ++x) {



            double gX = gradientX.get(y,x)[0];

            double gY = gradientY.get(y,x)[0];

            double magnitude = mags.get(y,x)[0];

            if (magnitude > gradientThresh) {

                gradientX.put(y,x,gX/magnitude);
                gradientY.put(y,x,gY/magnitude);
            } else {

                gradientX.put(y,x,0.0);
                gradientY.put(y,x,0.0);
            }
        }
    }

    //-- Create a blurred and inverted image for weighting
    Mat weight=new Mat();
    Imgproc.GaussianBlur( eyeROI, weight, new Size( kWeightBlurSize, kWeightBlurSize ), 0, 0 );

    for (int y = 0; y < weight.size().height; ++y) {

        for (int x = 0; x < weight.size().width; ++x) {

            weight.put(y,x,255 - weight.get(y,x)[0]);
        }
    }
    //imshow(debugWindow,weight);
    //-- Run the algorithm!
    Mat outSum = Mat.zeros(eyeROI.size(),CvType.CV_64F);
    // for each possible gradient location
    // Note: these loops are reversed from the way the paper does them
    // it evaluates every possible center for each gradient location instead of
    // every possible gradient location for every center.
  //  printf("Eye Size: %ix%i\n",outSum.cols,outSum.rows);

    for (int y = 0; y < weight.size().height; ++y) {

        for (int x = 0; x < weight.size().width; ++x) {


            double gX = gradientX.get(y,x)[0];

            double gY = gradientY.get(y,x)[0];
            if (gX == 0.0 && gY == 0.0) {
                continue;
            }
            outSum=testPossibleCentersFormula(x, y, weight, gX, gY, outSum);
        }
    }
    // scale all the values down, basically averaging them
    double numGradients = (weight.size().height*weight.size().width);
    Mat out=new Mat();
    outSum.convertTo(out, CvType.CV_32F,1.0/numGradients);
    //imshow(debugWindow,out);
    //-- Find the maximum point


    Core.MinMaxLocResult minmaxResult=Core.minMaxLoc(out);
    Point maxP=minmaxResult.maxLoc;
    double maxVal=minmaxResult.maxVal;

    //-- Flood fill the edges
    if(kEnablePostProcess) {
        Mat floodClone=new Mat();
        //double floodThresh = computeDynamicThreshold(out, 1.5);
        double floodThresh = maxVal * kPostProcessThreshold;
        Imgproc.threshold(out, floodClone, floodThresh, 0.0f, Imgproc.THRESH_TOZERO);
        if(kPlotVectorField) {
            //plotVecField(gradientX, gradientY, floodClone);
        //    imwrite("eyeFrame.png",eyeROIUnscaled);
        }
        Mat mask = floodKillEdges(floodClone);
        //imshow(debugWindow + " Mask",mask);
        out.copyTo(debugwindow);
        //imshow(debugWindow,out);
        // redo max

         minmaxResult=Core.minMaxLoc(out,mask);
         maxP=minmaxResult.maxLoc;
         maxVal=minmaxResult.maxVal;
    }
    return maxP;
    // return unscalePoint(maxP,eye);
}



boolean floodShouldPushPoint(Point np, Mat mat) {
    return inMat(np, (int)mat.size().height, (int)mat.size().width);
}


Mat floodKillEdges(Mat mat) {
    Imgproc.rectangle(mat,new Point(0,0),new Point(mat.size().width,mat.size().height),new Scalar(255));

    Mat mask=new Mat(mat.size(), CvType.CV_8U, new Scalar(255));
    ArrayDeque<Point> toDo=new ArrayDeque();
    toDo.add(new Point(0,0));
    while (!toDo.isEmpty()) {
        Point p = toDo.poll();

        if ( mat.get((int)p.x,(int)p.y)[0]==0.0f) {
            continue;
        }
        // add in every direction
        Point np=new Point(p.x + 1, p.y); // right
        if (floodShouldPushPoint(np, mat)) toDo.push(np);
        np.x = p.x - 1; np.y = p.y; // left
        if (floodShouldPushPoint(np, mat)) toDo.push(np);
        np.x = p.x; np.y = p.y + 1; // down
        if (floodShouldPushPoint(np, mat)) toDo.push(np);
        np.x = p.x; np.y = p.y - 1; // up
        if (floodShouldPushPoint(np, mat)) toDo.push(np);
        // kill it

        mat.put((int)p.x,(int)p.y,0.0f);

        mask.put((int)p.x,(int)p.y,0);
    }
    return mask;
}
boolean rectInImage(Rect rect, Mat image) {
    return rect.x > 0 && rect.y > 0 && rect.x+rect.width < image.size().width &&
            rect.y+rect.height < image.size().height;
}

boolean inMat(Point p,int rows,int cols) {
    return p.x >= 0 && p.x < cols && p.y >= 0 && p.y < rows;
}

Mat matrixMagnitude(Mat matX, Mat matY) {
    Mat mags=new Mat(matX.size(),CvType.CV_64F);
    for (int y = 0; y < matX.size().height; ++y) {

        for (int x = 0; x < matX.size().width; ++x) {

            double gX = matX.get(y,x)[0];
            double gY = matY.get(y,x)[0];
            double magnitude = Math.sqrt((gX * gX) + (gY * gY));

            mags.put(y,x,magnitude);
        }
    }
    return mags;
}

double computeDynamicThreshold(Mat mat, double stdDevFactor) {
    MatOfDouble stdMagnGrad=new MatOfDouble();
    MatOfDouble meanMagnGrad=new MatOfDouble();
    Core.meanStdDev(mat, meanMagnGrad, stdMagnGrad);

    double stdDev = stdMagnGrad.get(0,0)[0] / Math.sqrt(mat.size().height*mat.size().width);
    return stdDevFactor * stdDev + meanMagnGrad.get(0,0)[0];
}
公共类TimmAlgorithm{
点未缩放点(点p,矩形原点){
浮动比率=((浮动)kFasteyWidth)/origSize.width);
整数x=(整数)数学四舍五入(p.x/比率);
整数y=(整数)数学四舍五入(p.y/比率);
返回新点(x,y);
}
垫板尺寸(垫板src、垫板dst){
Imgproc.resize(src,dst,新大小(kFastEyeWidth,((float)kFastEyeWidth)/src.Size().width)*src.Size().height);
返回dst;
}
Mat计算梯度(Mat Mat){
Mat out=新的Mat(Mat.size(),CvType.CV_64F);
对于(int y=0;y梯度阈值){
梯度x.put(y,x,gX/量级);
梯度放置(y,x,gY/量级);
}否则{
梯度x.put(y,x,0.0);
梯度放置(y,x,0.0);
}
}
}
//--创建模糊和反转图像以进行加权
垫重=新垫();
Imgproc.GaussianBlur(眼睛ROI,重量,新尺寸(kWeightBlurSize,kWeightBlurSize),0,0);
对于(int y=0;y