如何打开CV :: Android中VideoWriter [英] How to open cv::VideoWriter in Android

查看:1064
本文介绍了如何打开CV :: Android中VideoWriter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用JNI使用OpenCV的2.4.8 Android中。

我打开与VideoCapture相机,我想记录下来。我有图像中的CV ::垫,它出现在屏幕上正确。

但是,当我尝试打开VideoCapture,它总是返回假。

  //摄像头分辨率为640x480和罚款。
       _camera_resolution = calc_optimal_camera_resolution(u.name,640,480);        //存储在SD卡,我在AndroidManifest.xml许可
        为const char * videoName =/sdcard/videoTest.avi;             //分段故障11!在Android的这个方法不起作用?所以评论
            // const int的EX =的static_cast< INT>(_ reader.get(CV_CAP_PROP_FOURCC));            //分段故障11!太!!!所以评论
            // const的双FPS = _reader.get(CV_CAP_PROP_FPS);            //尝试打开
            _isRecording = _writer.open(videoName,-1,30,_camera_resolution,真正的);
            //返回FALSE始终
            如果(!_ writer.isOpened())
            {
                LOGE(REC - 错误打开视频作家);
            }
            其他
            {
                LOGD(REC - 视频作家的startRecording开);
            }

我曾尝试为FOURCC使用方法:

CV_FOURCC(M,J,P,G)和CV_FOURCC(M,P,4,V)//它不工作<!/ p>

我曾尝试与不同的FPS比率,15.0,30.0 ...

照相机的分辨率似乎工作,因为当我打印的值是正确的。

为什么没有被正确打开?


解决方案

据我所知OpenCV4adnroid并不支持视频阅读和写作。
试着用一间codeR选项重建opencv的:
(例如:WITH_FFMPEG = YES或WITH_VFW = YES)

或尝试保存的图像序列,然后连接code从java的code这个序列的视频
我想下一个命题(<一个href=\"http://stackoverflow.com/questions/14337091/video-en$c$c-from-sequence-of-images-from-java-android\">ref)

 公共无效imageToMP4(BufferedImage的BI){
    //转换来的RGB转换为YUV色彩空间
    RgbToYuv420变换=新RgbToYuv420(0,0);    //将持有源图像中YUV色彩空间第j codeC本地图片
    图片TOEN code = Picture.create(bi.getWidth(),bi.getHeight(),ColorSpace.YUV420);    //执行转换
    transform.transform(AWTUtil.fromBufferedImage(BI),YUV);    //创建MP4合并器
    MP4Muxer复用器=新MP4Muxer(水槽,Brand.MP4);    //添加一个视频轨道
    COM pressedTrack outTrack = muxer.addTrackForCom pressed(TrackType.VIDEO,25);    //创建H.264连接codeR
    H264En codeR EN codeR =新H264En codeR(RC);    //分配将持有一间codeD帧缓冲区
    ByteBuffer的_out = ByteBuffer.allocate(ine.getWidth()* ine.getHeight()* 6);    //为分配SPS / PPS存储,他们需要在MP4文件的一个特殊的地方分开存放
    清单&LT;&ByteBuffer中的GT; spsList =新的ArrayList&LT;&ByteBuffer中的GT;();
    清单&LT;&ByteBuffer中的GT; ppsList =新的ArrayList&LT;&ByteBuffer中的GT;();    // EN code图像到H.264架,结果存储在'_out'缓冲区
    ByteBuffer的结果= EN coder.en codeFrame(_out,TOEN code);    //基于上面形成正确的MP4包在框架上
    H264Utils.en codeMOVPacket(结果,spsList,ppsList);    //添加分组视频轨道
    outTrack.addFrame(新MP4Packet(结果,0,25,1,0,true,则空,0,0));    //保存推SPS / PPS在MP4一种特殊的存储
    outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList,ppsList));    //将MP4头和录制完成
    muxer.writeHeader();
}

您可以从项目网站或通过Maven的下载ĴcodeC库,这下面的代码片段添加到您的pom.xml:

 &LT;&依赖性GT;
    &LT;&的groupId GT; org.j codeC&LT; /的groupId&GT;
    &LT;&的artifactId GT;ĴcodeC&LT; / artifactId的&GT;
    &LT;&版GT; 0.1.3&LT; /版本&GT;
&LT; /依赖性&GT;

Android版本:
Android用户可以使用类似下面到Android位图对象转换到J codeC本地格式:

 公共静态图片fromBitmap(位图SRC){
    图片DST = Picture.create((INT)src.getWidth(),(INT)src.getHeight(),RGB);
    fromBitmap(SRC,DST);
    返回DST;
}公共静态无效fromBitmap(位图SRC,DST图片){
    INT [] dstData = dst.getPlaneData(0);
    INT [] =包装新INT [src.getWidth()* src.getHeight()];    src.getPixels(填充,0,src.getWidth(),0,0,src.getWidth(),src.getHeight());    的for(int i = 0,srcoff到= 0,量dstOff = 0; I&LT; src.getHeight();我++){
        对于(INT J = 0; J&LT; src.getWidth(); J ++,++ srcoff到,量dstOff + = 3){
            INT RGB =挤满[srcoff到]
            dstData [量dstOff] =(RGB&GT;&GT; 16)及0xFF的;
            dstData [量dstOff + 1] =(RGB&GT;→8)及0xFF的;
            dstData [量dstOff + 2] = RGB和放大器; 0xFF的;
        }
    }
}

I'm using OpenCV 2.4.8 in Android using JNI.

I opening the camera with VideoCapture and I want to record it. I have the image in a cv::Mat, it appear in the screen correctly.

But, when I try to open VideoCapture, it returns false always.

       // Camera resolution is 640x480 and its fine.
       _camera_resolution = calc_optimal_camera_resolution(u.name, 640, 480);  

        // Store in sdcard, I have permission in AndroidManifest.xml
        const char * videoName = "/sdcard/videoTest.avi"; 

             // Segmentation fault 11! this method doesnt work in Android?  so commented
            //const int ex = static_cast<int>(_reader.get(CV_CAP_PROP_FOURCC)); 

            // Segmentation fault 11! too!!! so commented
            //const double fps = _reader.get(CV_CAP_PROP_FPS);      

            // Try to open
            _isRecording = _writer.open(videoName, -1, 30, _camera_resolution, true); 
            // Return FALSE always
            if(!_writer.isOpened())
            {
                LOGE("rec - Error opening video writer");
            }
            else
            {
                LOGD("rec - Video writer opened in startRecording");
            }

I have tried to use as FOURCC:

CV_FOURCC('M', 'J', 'P', 'G') and CV_FOURCC('M', 'P', '4', 'V') // It doesn't works!

I have tried with different fps ratios, 15.0, 30.0...

Camera resolution seems work because when I print the value is correct.

Why is not opening correctly?

解决方案

As I know OpenCV4adnroid doesn’t support video reading and writing. Try to rebuild your Opencv with an encoder option: (such: WITH_FFMPEG=YES or WITH_VFW=YES )

OR try save a sequence of images then encode a video from this sequence from java code I tried next proposition (ref)

public void imageToMP4(BufferedImage bi) {
    // A transform to convert RGB to YUV colorspace
    RgbToYuv420 transform = new RgbToYuv420(0, 0);

    // A JCodec native picture that would hold source image in YUV colorspace
    Picture toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420);

    // Perform conversion
    transform.transform(AWTUtil.fromBufferedImage(bi), yuv);

    // Create MP4 muxer
    MP4Muxer muxer = new MP4Muxer(sink, Brand.MP4);

    // Add a video track
    CompressedTrack outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25);

    // Create H.264 encoder
    H264Encoder encoder = new H264Encoder(rc);

    // Allocate a buffer that would hold an encoded frame
    ByteBuffer _out = ByteBuffer.allocate(ine.getWidth() * ine.getHeight() * 6);

    // Allocate storage for SPS/PPS, they need to be stored separately in a special place of MP4 file
    List<ByteBuffer> spsList = new ArrayList<ByteBuffer>();
    List<ByteBuffer> ppsList = new ArrayList<ByteBuffer>();

    // Encode image into H.264 frame, the result is stored in '_out' buffer
    ByteBuffer result = encoder.encodeFrame(_out, toEncode);

    // Based on the frame above form correct MP4 packet
    H264Utils.encodeMOVPacket(result, spsList, ppsList);

    // Add packet to video track
    outTrack.addFrame(new MP4Packet(result, 0, 25, 1, 0, true, null, 0, 0));

    // Push saved SPS/PPS to a special storage in MP4
    outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList));

    // Write MP4 header and finalize recording
    muxer.writeHeader();
}

You can download JCodec library from a project web site or via Maven, for this add the below snippet to your pom.xml:

<dependency>
    <groupId>org.jcodec</groupId>
    <artifactId>jcodec</artifactId>
    <version>0.1.3</version>
</dependency>

Android: Android users can use something like below to convert Android Bitmap object to JCodec native format:

public static Picture fromBitmap(Bitmap src) {
    Picture dst = Picture.create((int)src.getWidth(), (int)src.getHeight(), RGB);
    fromBitmap(src, dst);
    return dst;
}

public static void fromBitmap(Bitmap src, Picture dst) {
    int[] dstData = dst.getPlaneData(0);
    int[] packed = new int[src.getWidth() * src.getHeight()];

    src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight());

    for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) {
        for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) {
            int rgb = packed[srcOff];
            dstData[dstOff]     = (rgb >> 16) & 0xff;
            dstData[dstOff + 1] = (rgb >> 8) & 0xff;
            dstData[dstOff + 2] = rgb & 0xff;
        }
    }
}

这篇关于如何打开CV :: Android中VideoWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆