Converting bitmap to IplImage

511 views
Skip to first unread message

Conor G

unread,
Nov 19, 2014, 6:15:27 PM11/19/14
to jav...@googlegroups.com
Forgive my ignorance, I've only been introduced to JavaCV a few days now and I'm trying to get to grips with it for Android.
I need video overlaying for an app I'm working on and I spent days burning myself out from trying to build NDK libraries with a lot of failures!



Basically what I'm trying to do is re-encode a video that was recorded with the android device. 
I want to overlay a bitmap on each frame and save the file. 

When I use the sample class for recording I can put my own bit of code in the onPreviewframe, I can (somewhat) get this to work by doing the following:

// Adding data to buffered image
yuvIplimage.getByteBuffer().put(data);


// Getting byte buffer
bitmap.copyPixelsFromBuffer(yuvIplimage.getByteBuffer());


//Using android default icon as convenient example 
Bitmap overlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

Canvas canvas = new Canvas(bitmap);

canvas.drawBitmap(overlayBitmap, 20, 20, null);


bitmap.copyPixelsToBuffer(yuvIplimage.getByteBuffer());

then recorder.record(yuvIplimage);

This works, but just gives me the outline of the bitmap with just a white filling. I presume I have to manually do something for the other color channels?

Anyways, what I'm really stuck on now is trying to do the same thing, only take a video already recorded to the device, use the FrameGrabber to grab each frame, convert it to bitmap, overlay another small bitmap on top, then convert back to frame and to the recorder. My attempted code:

// Prepping Grabber and Recorder
FrameGrabber frameGrabber = new FFmpegFrameGrabber(videoPath);
FrameRecoder recorder = FFmpegFrameRecorder.createDefault(outputPath, imageWidth, imageHeight);


IplImage captured_frame = IplImage.create(imageWidth, imageHeight, IPL_DEPTH_8U, 4);

captured_frame = frameGrabber.grab();

Bitmap bitmap = Bitmap.createBitmap(captured_frame.width(), captured_frame.height(), Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(captured_frame.getByteBuffer()); // This results in Buffer not big enough for pixels

Here are the settings:
private int imageWidth = 320;
private int imageHeight = 240;
private int frameRate = 30;
recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
recorder.setFormat("mp4");
recorder.setVideoBitrate(10 * 1040 * 1040);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
recorder.setSampleRate(sampleAudioRateInHz);
recorder.setFrameRate(frameRate);


I just want to be able to get a bitmap of the frame, modify it, then convert it back to IplImage and record id.

I could be doing things completely wrong, I've been exhausting my Google / stackoverflow searching abilities for days now, if somebody can point me in the direction of a good sample of an Android app re-encoding a video using JavaCV I would be very grateful!
 


Mihael Francekovic

unread,
Nov 20, 2014, 2:14:50 AM11/20/14
to jav...@googlegroups.com
Hi Conor,

I was doing similar thing,
I would advise you not to convert each frame (iplImage) to Bitmap to overlay another bitmap and then back to iplImage to record it.
That is painfully slow an android devices.

JavaCv has functions to overlay one image over another.
Just load bitmap that you want to overlay as IplImage and use javaCv functions to accomplish your task.

I hope this helps a little bit, atm I am in hurry but
I can update you with method names and more info after 5-6 hours.. 

Mihael


--

---
You received this message because you are subscribed to the Google Groups "javacv" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacv+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Samuel Audet

unread,
Nov 24, 2014, 5:49:08 AM11/24/14
to jav...@googlegroups.com
On 11/20/2014 08:15 AM, Conor G wrote:
> IplImage captured_frame = IplImage.create(imageWidth, imageHeight, IPL_DEPTH_8U, 4);
>
> captured_frame = frameGrabber.grab();
>
> Bitmap bitmap = Bitmap.createBitmap(captured_frame.width(), captured_frame.height(), Config.ARGB_8888);

What we need to do actually is something like this:

IplImage bgr = frameGrabber.grab();
IplImage rgba = IplImage.create(imageWidth, imageHeight, IPL_DEPTH_8U, 4);
cvCvtColor(bgr rgba, CV_BGR2RGBA)
Bitmap bitmap = Bitmap.createBitmap(imageWidth, imageHeight,
Config.ARGB_8888);

But like Mihael said (Thanks Mihael!), this is pretty slow, so if you
can do everything you need to with functions from OpenCV, that would
probably be better.

Samuel
Reply all
Reply to author
Forward
0 new messages