我在Android中使用带有JNI的VideoWriter opencv类时遇到问题。
我的目标是简单地捕获相机帧并使用VideoWriter将它们写入文件。
以下是代码:
原生部分 - 为init编写器提供3个函数,编写一个框架并释放编写器。
JNIEXPORT void JNICALL Java_com_driveassist_drivingassistant_WorkActivity_InitWriter(JNIEnv *env, jobject, jstring path)
{
char const * new_path;
new_path = env->GetStringUTFChars(path , NULL ) ;
writer = VideoWriter();
stringstream ss;
ss << new_path;
ss << "//1.mp4";
string p;
ss >> p;
writer.open(p, CV_FOURCC('P', 'I', 'M', '1'), 24, Size(1024, 768));
}
JNIEXPORT void JNICALL Java_com_driveassist_drivingassistant_WorkActivity_WriteFrame(JNIEnv *, jobject, jlong frame)
{
Mat* im=(Mat*)frame;
Mat im_p = (*im).clone();
if(writer.isOpened())
{
resize(im_p, im_p, Size(1024, 768), 0, 0, INTER_AREA);
writer.write(im_p);
}
}
JNIEXPORT void JNICALL Java_com_driveassist_drivingassistant_WorkActivity_ReleaseWriter(JNIEnv *, jobject)
{
if(writer.isOpened())
{
writer.release();
}
}
Java部分:
我在opencv CameraBridgeViewBase中使用了一个活动:
public class WorkActivity extends Activity implements CvCameraViewListener {
private CameraBridgeViewBase mOpenCvCameraView;
private Mat mRgba;
private File mediaStorageDir;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
System.loadLibrary("driving_assistant");
mOpenCvCameraView.enableView();
InitWriter(mediaStorageDir.getPath());
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_work);
mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DriveAssistantCam");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("DrivingAssistant", "failed to create directory");
}
}
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.work_camera_surface_view);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onPause()
{
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
super.onPause();
// ReleaseWriter();
}
@Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
// OpenCVLoader.initDebug();
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
ReleaseWriter();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
}
public void onCameraViewStopped() {
mRgba.release();
ReleaseWriter();
}
public Mat onCameraFrame(Mat inputFrame) {
inputFrame.copyTo(mRgba);
WriteFrame(mRgba.getNativeObjAddr());
return mRgba;
}
代码运行没有例外,但视频文件没有出现。本机库正常加载,应用程序可以访问该目录(我尝试使用java.io.File创建一个文件)。
我的系统是Ubuntu 12.10,Eclipse Indigo。我在模拟器和galaxy tab 2上尝试过这段代码。
非常感谢!
答案 0 :(得分:4)
嗯,回答我自己的问题已成为一个很好的传统:)
OpenCV for adnroid还不支持视频阅读和写作。我在google group“Opencv4Android”中找到了这个:
Andrey Pavlenkoandrey.pavlenko@itseez.comчерезgooglegroups.com4 янв。 (5дн.зад)
кому:android-opencv不幸的是,Android OpenCV不支持 即使在后来的版本2.4.3.2中也可以进行视频读写。希望 它将在下一个版本中启用...
可能我必须使用ffmpeg或其他一些库。