【发布时间】:2019-10-20 18:45:33
【问题描述】:
我在 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,那也很棒。
【问题讨论】:
-
不,你不能只在 Android 上运行 python。为此,您必须编写相关的 Java 代码。
-
@ZdaR 甚至不使用 Jython for Android 或 Qpython 吗?
-
和无关的:坚持 java 命名约定。 Java 方法名应该是 camelCase()。另请注意,Java 没有“真正的”多维数组,因此在性能方面会出现(负面)惊喜。用 java 编写高性能的“计算代码”是可能的,但这就像它自己的科学。
-
@ZdaR 您知道如何在特定情况下执行此操作吗?我对 python 有点陌生,在 Java 方面不是最好的
-
@Corentin Jython 代码工作。但是不要忘记,像 numpy 这样的库从所有核心计算的东西……都用 C 实现的事实中汲取了它们的性能。所以,当你找到一种方法来为 Android 编译该库时,你也许有机会与 jython ;-)
标签: java android python arrays opencv