首页 > 解决方案 > 如何在我的 android 应用程序中使 K-mean 图像处理算法更快

问题描述

我希望有一种更快的方法将 k-mean 应用于图像并显示在屏幕上。我想要一个用于 android 解决方案的 opencv。我的代码在智能手机上运行时间为 30 秒。我想运行它大约 1 或 2 秒。

我已经有了 K-mean 的代码,并使用 opencv 显示在屏幕上。但我需要它更快。我认为它标记图像和显示的方式花费了很多时间。

public void k_Mean(){
        Mat rgba = new Mat();
        Mat mHSV = new Mat();

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),images[current_image]);
        Bitmap outputBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.RGB_565);
        Utils.bitmapToMat(bitmap,rgba);

        //must convert to 3 channel image
        Imgproc.cvtColor(rgba, mHSV, Imgproc.COLOR_RGBA2RGB,3);
        Imgproc.cvtColor(rgba, mHSV, Imgproc.COLOR_RGB2HSV,3);
        Mat clusters = cluster(mHSV, 3).get(0);
        Utils.matToBitmap(clusters,outputBitmap);

        imageView.setImageBitmap(outputBitmap);
    }


    public  List<Mat> cluster(Mat cutout, int k) {
        Mat samples = cutout.reshape(1, cutout.cols() * cutout.rows());
        Mat samples32f = new Mat();
        samples.convertTo(samples32f, CvType.CV_32F, 1.0 / 255.0);

        Mat labels = new Mat();
        //criteria means the maximum loop
        TermCriteria criteria = new TermCriteria(TermCriteria.COUNT, 20, 1);
        Mat centers = new Mat();
        Core.kmeans(samples32f, k, labels, criteria, 1, Core.KMEANS_PP_CENTERS, centers);

        return showClusters(cutout, labels, centers);
    }

    private static List<Mat> showClusters (Mat cutout, Mat labels, Mat centers) {
        centers.convertTo(centers, CvType.CV_8UC1, 255.0);
        centers.reshape(3);

        System.out.println(labels + "labels");

        List<Mat> clusters = new ArrayList<Mat>();
        for(int i = 0; i < centers.rows(); i++) {
            clusters.add(Mat.zeros(cutout.size(), cutout.type()));
        }

        Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
        for(int i = 0; i < centers.rows(); i++) counts.put(i, 0);

        int rows = 0;
        for(int y = 0; y < cutout.rows(); y++) {
            for(int x = 0; x < cutout.cols(); x++) {
                int label = (int)labels.get(rows, 0)[0];
                int r = (int)centers.get(label, 2)[0];
                int g = (int)centers.get(label, 1)[0];
                int b = (int)centers.get(label, 0)[0];
                counts.put(label, counts.get(label) + 1);
                clusters.get(label).put(y, x, b, g, r);
                rows++;
            }
        }

        System.out.println(counts);
        return clusters;
    }

我的输出是正确的。如果有更快的方法可以做到这一点,我会徘徊。我的其他图像处理算法运行时间不到 1s。

标签: javaandroidopencvoptimizationk-means

解决方案


推荐阅读