Ask Your Question
1

Problem creating Mat from camera buffers (edited)

asked 2013-02-21 20:50:56 -0600

samir22 gravatar image

updated 2013-02-22 02:53:08 -0600

Latest update

So I've made a few changes and would like to list them and the results.

The camera buffer is in 32 bit ARGB. I changed the type in the Mat initialization to CV_32FC4. When I call

cv::blur(src,dest,Size(5,5));

I am seeing a red screen - lending me to believe the ARGB format is not working with the Mat.

So I guess the question boils down to, how do I format ARGB to work with OpenCV Mat?

Original question

Hey guys,

So I'm creating a Mat from camera buffers that I'm receiving like so:

cv::Mat src = cv::Mat(cv::Size(img_height, img_width),CV_8UC4);
memcpy(src.ptr(), (void*) img_buffer,img_height * img_width * 4);

This works fine.

But when I try to do any operation on this, I get weird output.

For example,

cv::blur(src,src,Size(5,5));

results in the expected output (blurred) but divided into 5 "columns".

Similarly, if I try

cv::blur(src,src,Size(3,3));

I get 3 such columns.

Same with other operations - Gaussian blur, erode etc

Only other operation I have tested that works fine without a problem is clone().

Can anyone hazard a guess as to why this might be happening?

I'm working on a device which does not have a proper port of OpenCV so all OS related tasks(reading and writing images) are being done by hand.

=====UPDATE======

So I've been experimenting a little.

I can make calls such as

cv::medianBlur(inter,dest,3);

and there is output (albeit distorted as described above). But when I do something like

cv::cvtColor(inter, dest, COLOR_RGBA2RGB);

I'm getting segfault errors. Is there a fundamental difference in how these functions work that may be indicative of the problem?

edit retag flag offensive close merge delete

Comments

Post an image of your srsc before and after blurring (screencapture an imshow()). The problem seems to be the memory layout of your original buffer

sammy gravatar imagesammy ( 2013-02-22 00:39:28 -0600 )edit

Hey @sammy what is an srsc? Can you also see the update I've made, if that gives any clue?

The camera buffer that is coming in is 32 bit ARGB data. I thought OpenCV worked with RGB? The camera buffer can also come in in NV12. What would be better to handle?

samir22 gravatar imagesamir22 ( 2013-02-22 01:09:17 -0600 )edit

@samir22, i'm just curious, from what kind of device do you get 32 bit ARGB data ? cvtColor() can convert argb as well as yuv to bgr (not sure about nv12, but that's some kind of yuv, iirc)

berak gravatar imageberak ( 2013-02-22 03:28:09 -0600 )edit

@samir22 I wanted to write src - your source image.

sammy gravatar imagesammy ( 2013-02-22 04:26:04 -0600 )edit

@berak, I tried using cvtColor but it kept segfaulting. Please see the update to my question.

samir22 gravatar imagesamir22 ( 2013-02-22 05:12:27 -0600 )edit

@samir22, tried cv::cvtColor(inter, dest, COLOR_RGB2RGBA); and back, no problem here.

also blur() works fine on rgba data for me. no colums or such.

i think sammy is right, must be something with the memory layout of your original buffer.

since you said, you're doing most of the i/o stuff yourself, might be helpful, to show some bits of code related to that

berak gravatar imageberak ( 2013-02-22 05:58:13 -0600 )edit

Btw, you problem is here: CV_32FC4 is a matrix of floats. But you have probably integers, so CV_32UC4 is the way to go

sammy gravatar imagesammy ( 2013-04-04 01:30:29 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
0

answered 2013-04-04 01:55:16 -0600

Just to note, the answer to your adaptation is already in the first solution. Since you know how your data format extually is, ARGB, you can read it out and store the information into seperate channels.

When reading: bit 1 = A, bit 2 = R, bit 3 = G, bit 4 = B and so on.

Then when you have read in your data manually bit by bit, then first do a mix of the channels you retrieved towards the BGR color scheme that openCV uses. Then apply blur to that created image.

edit flag offensive delete link more
0

answered 2013-04-04 00:55:34 -0600

atduskgreg gravatar image

There don't seem to be any conversion options for ARGB. cvtColor raises an assertion if either the src or dst mat are 32S: "Assertion failed (depth == CV_8U || depth == CV_16U || depth == CV_32F)" Is your data in the Mat as floats or as signed ints? I'm guessing from your segfault that you've got CV_32S. You can use Mat convertTo() to turn your Mat into CV_32F depth and then you can successfully call cvtColor().

However, I've found that calling cvtColor() on an ARGB image with COLOR_RGBA2BGRA as the conversion type leads to wacky results like this. This leads me to believe that RGBA is not actually the same as ARGB and/or that signed/unsigned/float format conversions may be causing some truncation or other issues (I think the former is probably the real cause).

I noticed in your other thread that you mentioned the Android BitmapToMat conversion functions. I think something in the spirit of these are exactly what you need here (though in sounds like you're working in the C++ api so those won't be much help to you even with a bunch of hacking). I might try poking around the source for those function to see if there's some hints about what APIs they're calling that you could maybe use.

Other than that, there's always iterating through the Mat manually and reorganizing it.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2013-02-21 20:50:56 -0600

Seen: 3,219 times

Last updated: Apr 04 '13