如何在不使用numpy的情况下将Python代码转换为Java

2024-09-28 05:18:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中有一个方法,它使用OpenCV从图像中移除背景。我希望android版本的OpenCV也能使用相同的功能,但我似乎无法完全理解数组的工作原理以及如何处理它们。在

这是我到目前为止在Java中所看到的:

private Bitmap GetForeground(Bitmap source){
        source = scale(source,300,300);
        Mat mask = Mat.zeros(source.getHeight(),source.getWidth(),CvType.CV_8U);
        Mat bgModel = Mat.zeros(1,65,CvType.CV_64F);
        Mat ftModel = Mat.zeros(1,65,CvType.CV_64F);
        int x = (int)Math.round(source.getWidth()*0.1);
        int y = (int)Math.round(source.getHeight()*0.1);
        int width = (int)Math.round(source.getWidth()*0.8);
        int height = (int)Math.round(source.getHeight()*0.8);
        Rect rect = new Rect(x,y, width,height);
        Mat sourceMat = new Mat();
        Utils.bitmapToMat(source, sourceMat);
        Imgproc.grabCut(sourceMat, mask, rect, bgModel, ftModel, 5, Imgproc.GC_INIT_WITH_RECT);

        int frameSize=sourceMat.rows()*sourceMat.cols();
        byte[] buffer= new byte[frameSize];
        mask.get(0,0,buffer);
        for (int i = 0; i < frameSize; i++) {
            if (buffer[i] == 2 || buffer[i] == 0){
                buffer[i] = 0;
            }else{
                buffer[i] = 1 ;
            }
        }

        byte[][] sourceArray = getMultiChannelArray(sourceMat);
        byte[][][] reshapedMask = ReshapeArray(buffer, sourceMat.rows(), sourceMat.cols());
        return source;
    }

    private byte[][][] ReshapeArray(byte[] arr, int rows, int cols){
        byte[][][] out = new byte[cols][rows][1];
        int index=0;

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                out[i][j][0] = arr[index];
                index++;
            }
        }
        return out;
    }

    public static byte[][] getMultiChannelArray(Mat m) {
        //first index is pixel, second index is channel
        int numChannels=m.channels();//is 3 for 8UC3 (e.g. RGB)
        int frameSize=m.rows()*m.cols();
        byte[] byteBuffer= new byte[frameSize*numChannels];
        m.get(0,0,byteBuffer);

        //write to separate R,G,B arrays
        byte[][] out=new byte[frameSize][numChannels];
        for (int p=0,i = 0; p < frameSize; p++) {
            for (int n = 0; n < numChannels; n++,i++) {
                out[p][n]=byteBuffer[i];
            }
        }
        return out;
    }

我要重新创建的python代码:

^{pr2}$

我不知道如何转换python代码的最后两行。如果有一种方法可以在我自己的项目中在android设备上运行python clean,那也太棒了。在


Tags: sourcenewforindexbuffermathbyteout
2条回答

现在,您应该考虑一下SL4A项目,它允许您通过java应用程序在Android上运行Python代码。在

以下是有趣的链接:

  1. https://github.com/damonkohler/sl4a

  2. https://norwied.wordpress.com/2012/04/11/run-sl4a-python-script-from-within-android-app/

  3. http://jokar-johnk.blogspot.com/2011/02/how-to-make-android-app-with-sl4a.html

让我们看看这两个命令并尝试将它们转换为javaapi调用。它可能不是简单的2行代码。在

mask = np.where((mask==2) | (mask == 0),0,1).astype('uint8')

在上面的命令中,我们正在创建一个新的图像mask,它具有uint数据类型的像素值。新的mask矩阵的值为0,其中前一个mask的值为2或{},否则为{}。让我们用一个例子来说明这一点:

mask = [
[0, 1, 1, 2],
[1, 0, 1, 3],
[0, 1, 1, 2],
[2, 3, 1, 0],
]

此操作后,输出将为:

^{pr2}$

所以上面的命令只是生成一个只有0和1值的二进制掩码。这可以在Java中使用Core.compare()方法进行复制,如下所示:

// Get a mask for all `1` values in matrix.
Mat mask1vals;
Core.compare(mask, new Scalar(1), mask1vals, Core.CMP_EQ);

// Get a mask for all `3` values in matrix.
Mat mask3vals;
Core.compare(mask, new Scalar(3), mask3vals, Core.CMP_EQ);

// Create a combined mask
Mat foregroundMask;
Core.max(mask1vals, mask3vals, foregroundMask)

现在需要将前景遮罩与输入图像相乘,以获得最终的抓取图像:

// First convert the single channel mat to 3 channel mat
Imgproc.cvtColor(foregroundMask, foregroundMask, Imgproc.COLOR_GRAY2BGR);
// Now simply take min operation
Mat out;
Core.min(foregroundMask, image, out);

相关问题 更多 >

    热门问题