在我的“public void onPreviewFrame(byte []数据,Camera camera){....}”我想取bytearray“data”并将其传递给JNI并应用一些OpenCV过滤器,以便预览会更改,而不会返回。 最好的方法是什么?
目前我只传递像这样的bytearray:
JNIEXPORT jint JNICALL Java_example_jnitest_Lib_filterfunc
(JNIEnv * je, jclass jc, jbyteArray byteData){
try {
jbyte* _b_data= je->GetByteArrayElements(byteData, 0);
int height = base;
int width = base2;
Mat mdata(height, width, CV_8UC4, (unsigned char *)_b_data);
Mat myMat = imdecode(mdata,1);
je->ReleaseByteArrayElements(byteData, _b_data, 0);
return 1;
} catch(const exception& ex){
return 0;
}
}
在Java代码中:
public static native int filterfunc(byte[] byteData);
注意:目前返回值是1,所以我希望将bytearray转换为Mat Obejct正在运行。但这不会改变预览,因为我不会将其更改回bytearray。
答案 0 :(得分:1)
我想取bytearray“data”并将其传递给JNI并应用一些OpenCV过滤器,以便预览更改,而不返回它。
不幸的是,这是不可能的。传递给onPreviewFrame()
的字节数组只是预览框架的副本,您对其所做的任何更改都不会显示在预览中。您可以通过修改onPreviewFrame()
函数中的Java中的字节数组作为测试来自行测试,您将看不到任何效果。
如果要使用OpenCV更改预览帧数据并在预览窗口中查看结果,则需要将处理后的帧上传到OpenGL纹理,然后使用片段将其渲染为GLSurfaceView着色器将NV21 data转换为RGB或其他方法。简单地更改字节数组将不起作用。
有关详细信息,请参阅以下问题:
答案 1 :(得分:0)
您可以使用OpenCV实现访问摄像头。
以下是使用OpenCV4android的示例代码。
public class SampleCameraFrameAccessActivity extends Activity implements CvCameraViewListener2, OnTouchListener{
private static final String TAG = "SampleCameraFrameAccessActivity";
protected CameraBridgeViewBase cameraPreview;
protected Mat mRgba;
protected BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
// mOpenCvCameraView.enableView();
// mOpenCvCameraView.setOnTouchListener(ColorRegionDetectionActivity.this);
cameraPreview.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_sample_layout);
cameraPreview = (CameraBridgeViewBase) findViewById(R.id.sample_test_camera_view);
cameraPreview.setCvCameraViewListener(this);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(cameraPreview != null){
cameraPreview.disableView();
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}
@Override
public void onCameraViewStarted(int width, int height) {
// TODO Auto-generated method stub
mRgba = new Mat(height, width, CvType.CV_8UC4);
}
@Override
public void onCameraViewStopped() {
// TODO Auto-generated method stub
mRgba.release();
}
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
// TODO Auto-generated method stub
mRgba = inputFrame.rgba();
return mRgba;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
}
XML Layout文件是:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/sample_test_layout" >
<org.opencv.android.JavaCameraView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/sample_test_camera_view" />
</RelativeLayout>
在onCameraFrame方法中,您可以从相机的帧缓冲区访问每一帧。如果你想应用opencv过滤器,你可以简单地将帧缓冲区传递给jni或使用opencv4android包装器来完成它。