【问题标题】:Converting OpenCV code from C++ to Java将 OpenCV 代码从 C++ 转换为 Java
【发布时间】:2012-01-28 00:21:03
【问题描述】:

我目前正在尝试将一些遗留代码从 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 中?

【问题讨论】:

  • 你能告诉我们你有什么,你到底在哪里(在 Java 中)卡住了?
  • += 是基元可接受的运算符,但不适用于对象。您可能必须编写一个方法来为对象添加。
  • C++ 代码将标量添加到 Mat 对象。在 Java 中,我创建了 Scalar 和 Mat 对象,但找不到将 Scalar 添加到 Mat 的方法。 JavaCV中的Core类包含一个静态方法add(Mat, Mat, Mat),但是它只允许你添加两个Mat的
  • @Binyamin Sharet 我已经指出了我遇到问题的确切行 - 包含 += 运算符的行
  • 您可以用c++编写该方法,并使用同一作者的javacpp库从您的代码中调用它。应该快得多。我很确定java中还没有相应的操作。

标签: java android c++ opencv


【解决方案1】:

注意:对此答案持保留态度,我尚未对此进行全面测试;)

选项1:

最直接的方法是使用 your_mat.put(row, col, data)your_mat.get(row, col).

由于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);

选项2:

但是对于很多像素处理,推荐的方法是首先将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 转换。

【讨论】:

  • 虽然这个答案不再相关,但我会接受它,因为它似乎是正确和完整的
  • 是的,我后来注意到这个问题有点老了。但是对于新的 opencv 用户来说,这个问题今天仍然很常见。 AFAIK 这些选项目前是在 java 中遍历像素的最佳选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 2014-05-27
相关资源
最近更新 更多