将OpenCV代码从c++转换为Java

Converting OpenCV code from C++ to Java

本文关键字:转换 Java c++ OpenCV 代码      更新时间:2023-10-16

我目前正在尝试将一些遗留代码从iPhone迁移到Android。这段代码使用OpenCV库进行一些图像处理。总的来说,它运行得很好,但是我被困在一行代码上,我不知道如何转换成Java代码:

Scalar dMean;
Scalar scalar;
std::vector<Mat> channels;
split(mat, channels);
for(int i=0; i<3; ++i) {
   channels[i] += dMean[i];
}

问题是-在Java代码中应该使用什么而不是+=操作符来将标量对象添加到Mat?

注意:对这个答案持保留态度,我还没有完全测试过;)

OPTION1:

最直接的方法,如果你只打算处理几个像素,是通过使用your_mat。put(row, col, data) and your_mat。(行,坳)

由于put()方法不接受Scalar对象作为数据参数,您必须将Scalar转换为put()接受的对象。

所以如果你的Scalar是(1,2,3)也许一个int数组int[] scalar = {1,2,3};应该可以解决这个问题。

int[] scalar = ... // convert from Scalar object
// assuming the result of get() is an int[], sum both arrays:
int[] data = your_mat.get(row, col) + scalar // <- pseudo-code alert :D
your_mat.put(row, col, data);

OPTION2:

但是,对于大量的像素处理,推荐的方法是首先将Mat转换为Java原语,处理原语,然后将其转换回Mat。这是为了避免太多的JNI调用,这个方法执行2个JNI调用,而前一个方法每个put/get调用一次。

对应的Java原语数组类型取决于Mat类型:

CV_8U and CV_8S -> byte[];
CV_16U and CV_16S -> short[];
CV_32S -> int[];
CV_32F -> float[];
CV_64F-> double[];

那么代码将是这样的:

// assuming Mat it's of CV_32S type
int buff[] = new int[your_mat.total() * your_mat.channels()];
your_mat.get(0, 0, buff);
// buff is now Mat converted to int[]
your_mat.put(0, 0, buff); // after processing buff, convert it back to Mat type

选项3:

好了,这些解决方案都很难看,这个不是最有效的,但从Java的角度来看,它没那么难看:

List<Integer> scalarList = ... // your conversion from a Scalar to a List
List<Integer> channelsList = new ArrayList<Integer>();
Converters.Mat_to_vector_int(channels, channelsList); // this is an existing OpenCV4Android converter
// process channelsList and scalarList, store in channelsList
channels = Converters.vector_int_to_Mat(channelsList); // after processing, convert it back to Mat type

现在我想到它选项3选项2非常相似,如果OpenCV的Converters内部工作类似于选项2转换。