Ant*_*ton 6 c++ java android opencv
我目前正在尝试将一些遗留代码从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];
}
Run Code Online (Sandbox Code Playgroud)
问题是 - 在Java代码中应该使用什么代替+ =运算符来将Scalar对象添加到Mat?
注意:这个答案带着一点点盐,我还没有完全测试过这个;)
选项1:
最直接的方法是,如果你只处理一些像素,则使用your_mat.put(row,col,data)和your_mat.get(row,col).
由于该put()
方法不接受Scalar
对象的数据参数,您必须将转换Scalar
的东西,put()
接受.
所以,如果你Scalar
的(1,2,3)可能是一个int数组int []标量= {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);
Run Code Online (Sandbox Code Playgroud)
选项2:
但对于大量像素处理,推荐的方法是首先将a转换Mat
为Java原语,处理原语然后将其转换回原语Mat
.这是为了避免过多的JNI调用,此方法执行2次JNI调用,而前者每次调用/获取一次.
相应的Java原始数组类型取决于Mat类型:
CV_8U and CV_8S -> byte[];
CV_16U and CV_16S -> short[];
CV_32S -> int[];
CV_32F -> float[];
CV_64F-> double[];
Run Code Online (Sandbox Code Playgroud)
所以代码将是这样的:
// 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
Run Code Online (Sandbox Code Playgroud)
方案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
Run Code Online (Sandbox Code Playgroud)
现在我认为它选项3与选项2非常相似,如果OpenCV的Converters
内部工作类似于选项2转换.