Как увеличить FPS Android Opencv камеры? - PullRequest
2 голосов
/ 11 марта 2019

Я занимаюсь разработкой приложения для Android и обрабатываю кадры с использованием Opencv в режиме реального времени.

Обработка изображений тяжелая, поскольку я обнаруживаю самый большой контур, поворачиваю и обрезаю его и применяю какое-тосегментация на обрезанном Mat объекте.

Проблема в том, что FPS начинается со значения 3 и падает до 1.

Я не делаю несколько тяжелыхтакие операции, как matToBitmap, и я еще не делаю нативные вызовы.

Это мой первый большой проект, и у меня нет большого опыта работы с Opencv.Что я могу сделать, чтобы увеличить свой FPS?

Вот мой код:

  long e1 = Core.getTickCount();

    Mat mGray = new Mat();

    MatOfDouble mu = new MatOfDouble();

    MatOfDouble stddev = new MatOfDouble();

    Imgproc.cvtColor(origMat, origMat, Imgproc.COLOR_BGRA2BGR);

    Imgproc.cvtColor(origMat, mGray, Imgproc.COLOR_BGR2GRAY);

    Core.meanStdDev(mGray, mu, stddev);

    Imgproc.GaussianBlur(mGray, mGray, new Size(5, 5), 5);

    Imgproc.Canny(mGray, mGray, (mu.get(0, 0)[0]) * 0.66, (mu.get(0, 0)[0]) * 1.33, 3, false);

    Mat kernell = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9, 9));

    Imgproc.morphologyEx(mGray, mGray, Imgproc.MORPH_CLOSE, kernell);

    Imgproc.dilate(mGray, mGray, Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(3, 3)));

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

    Mat hierarchy = new Mat();

    Imgproc.findContours(mGray, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    double largest_area = 0;

    Rect rect = new Rect();
    int largest_idx = 0;

    for (int idx = 0; idx < contours.size(); idx++) {

        double a = Imgproc.contourArea(contours.get(idx));  //Find the area of contour

        if (a > largest_area) {

            largest_area = a;

            largest_idx = idx;
        }
    }

    if (contours.size() > 0) {

        MatOfPoint2f new_mat = new MatOfPoint2f(contours.get(largest_idx).toArray());

        RotatedRect rbox = Imgproc.minAreaRect(new_mat);

        Point vertices[] = new Point[4];

        rbox.points(vertices);

        List<MatOfPoint> boxContours = new ArrayList<>();

        boxContours.add(new MatOfPoint(vertices));

        for (int i = 0; i < 4; ++i) {
            Imgproc.line(origMat, vertices[i], vertices[(i + 1) % 4], new Scalar(255, 0, 0));
        }

        double rect_angle = rbox.angle - 90.0f;
        Size rect_size = rbox.size;

        double d = rect_size.width;
        rect_size.width = rect_size.height;
        rect_size.height = d;


        M = Imgproc.getRotationMatrix2D(rbox.center, rect_angle, 1.0);


        Imgproc.warpAffine(origMat, rotated, M, origMat.size());


        if (rect_size.width > 70 && rect_size.height > 70)
            Imgproc.getRectSubPix(rotated, new Size(rect_size.width - 70, rect_size.height - 70), rbox.center, rotated);


        Imgproc.resize(rotated, rotated, origMat.size());



        Mat orr = rotated.clone();

        Imgproc.cvtColor(orr, orr, Imgproc.COLOR_RGB2HSV);

        Core.split(orr, channels);

        orr = channels.get(2);

        CLAHE clahe = Imgproc.createCLAHE();

        clahe.setClipLimit(1);

        clahe.apply(orr, orr);

        Imgproc.GaussianBlur(orr, orr, new Size(5, 5), 5);

        Core.meanStdDev(mGray, mu, stddev);

        Imgproc.Canny(orr, orr, (mu.get(0, 0)[0]) * 0.66, (mu.get(0, 0)[0]) * 1.33, 3, false);

        Imgproc.morphologyEx(orr, orr, Imgproc.MORPH_CLOSE, kernell);

        Imgproc.dilate(orr, orr, Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(3, 3)));

        Imgproc.findContours(orr, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        for (int i = contours.size() - 1; i >= 0; i--) {
            double area = Imgproc.contourArea(contours.get(i), false);  //  Find the area of contour
            if (area < min_area)
                contours.remove(i);
        }

        if (contours.size() > 0) {
            MatOfPoint2f approxCurve = new MatOfPoint2f();
            rectList.clear();
            for (int idx = 0; idx < contours.size(); idx++) {
                //Convert contours(i) from MatOfPoint to MatOfPoint2f
                MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(idx).toArray());
                //Processing on mMOP2f1 which is in type MatOfPoint2f
                double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;
                Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);

                //Convert back to MatOfPoint
                MatOfPoint points = new MatOfPoint(approxCurve.toArray());

                // Get bounding rect of contour
                Rect rectt = Imgproc.boundingRect(points);
                rectList.add(rect);
                Mat miniature = new Mat(orr, new Rect(rectt.tl(), rectt.br()));
                mats.add(miniature);

                // draw enclosing rectangle (all same color, but you could use variable i to make them unique)
                Imgproc.rectangle(rotated, rectt.tl(), rectt.br(), new Scalar(255, 0, 0));
            }
        }

        long e2 = Core.getTickCount();
        long e = e2 - e1;
        double time = e / Core.getTickFrequency();

        Log.d("timeTAG", "" + time);

        return orr;
    }
    return rotated;
...