我在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代码:
image = cv2.imread('Images/handheld.jpg')
image = imutils.resize(image, height = 300)
mask = np.zeros(image.shape[:2],np.uint8)
bgModel = np.zeros((1,65),np.float64)
frModel = np.zeros((1,65),np.float64)
height, width, d = np.array(image).shape
rect = (int(width*0.1),int(height*0.1),int(width*0.8),int(height*0.8))
cv2.grabCut(image, mask, rect, bgModel,frModel, 5,cv2.GC_INIT_WITH_RECT)
mask = np.where((mask==2) | (mask == 0),0,1).astype('uint8')
image = image*mask[:,:,np.newaxis]
我不知道如何转换python代码的最后两行。如果有一种方法可以在我自己的项目中的android设备上运行python clean,那也很棒。
答案 0 :(得分:0)
此时,您应该考虑与SL4A项目进行一下交流,这将使您可以通过Java应用程序在Android上运行Python代码。
以下是有趣的链接:
答案 1 :(得分:0)
让我们看一下这两个命令,并尝试将它们转换为Java API调用。这可能不是简单的两行代码。
object Form1: TForm1
...
object PanelDialogo1: TPanelDialogo
...
object PanelDialogo1_Label2: TLabel
Caption = 'Another label right here'
end
object PanelDialogo1_Label1: TLabel
Caption = 'A label in the top of the panel'
end
object PanelDialogo1_Edit1: TEdit
Text = 'Write something here...'
end
object PanelDialogo1_Panel1: TPanel
object PanelDialogo1_Button1: TButton
Caption = 'OK'
end
end
object PanelDialogo1_Label3: TLabel
Caption = 'Some label just here'
end
end
end
在上述命令中,我们正在创建一个新图像mask = np.where((mask==2) | (mask == 0),0,1).astype('uint8')
,该图像的像素值的数据类型为mask
。对于新的uint
矩阵,对于每个位置,其中先前的mask
的值为0
或mask
,否则为2
,其值将为0
。让我们用一个例子来证明这一点:
1
此操作后的输出为:
mask = [
[0, 1, 1, 2],
[1, 0, 1, 3],
[0, 1, 1, 2],
[2, 3, 1, 0],
]
因此,以上命令只是生成仅包含0和1值的二进制掩码。可以使用mask = [
[0, 1, 1, 0],
[1, 0, 1, 1],
[0, 1, 1, 0],
[0, 1, 1, 0],
]
方法在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)