Ask Your Question
1

Change blobFromImage dimensions order

asked 2020-10-22 03:44:42 -0600

st.matkov gravatar image

updated 2020-10-23 09:56:05 -0600

Hello everyone,

I faced a problem with C++ blobFromImage function. I trained a CNN-network in Keras which takes a 4-d blob as input (common practice, nothing special). The problem is that my blob order is NHWC (where Channle size is always 6) but blobFromImage returns only NCHW. There is no any trouble to reshape numpy-blob in python but I haven't found any solution for C++.

Is there any way to create blob of NHWC in C++ or reshape blobFromImage result to NHWC?

EDIT:

After spending whole day solving the problem I finally got correct result. It turned out that my input images were CV_8U but my blob held CV_32F, so I simply converted inputs to CV_32F and it worked! Thanks @berak for help.

edit retag flag offensive close merge delete

Comments

1

what does the input data for this look like ? how do you acquire it ?

berak gravatar imageberak ( 2020-10-22 04:09:51 -0600 )edit
2

Input data is two 3-channel images stitched together (at channel axis) in one blob. For example, if images resolution is 1280x720 than blob shape will be (1, 720, 1280, 6)

st.matkov gravatar imagest.matkov ( 2020-10-22 04:24:50 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2020-10-22 04:41:10 -0600

berak gravatar image

updated 2020-10-23 02:21:06 -0600

assuming, you have 2 (float) images A and B of equal size, 3 channels each, you could first merge them like this:

vector<Mat> v = {A,B};
Mat C;
merge(v, C);

now C has 6 interleaved channels, and we need to add the "batch" dimension:

int sz[] = {1, A.rows, A.cols, 6};
Mat blob(4, sz, CV_32F, C.data);

but careful ! your blob does NOT hold a deep copy of the data, so C has to be kept alive during the processing !

EDIT: due to public demand, here's the reverse operation ;)

// extract 2d, 6chan Mat
Mat c2(blob.size[2], blob.size[3], CV_32FC(6), blob.ptr(0));

// split into channels
vector<Mat> v2;
split(c2,v2);

// merge back into 2 images
Mat a,b;
merge(vector<Mat>(v2.begin(),   v2.begin()+3), a);
merge(vector<Mat>(v2.begin()+3, v2.end()),     b);
edit flag offensive delete link more

Comments

2

Thank you for your reply. I wrote this code by your comments and it seems it works fine but I can't check whether images store right. Could you explain how can I retrieve images from blob?

st.matkov gravatar imagest.matkov ( 2020-10-22 07:24:56 -0600 )edit
2

It doesn't retrieve image properly :( I left an "edit" section in question's body.

st.matkov gravatar imagest.matkov ( 2020-10-22 08:24:58 -0600 )edit

well, if you wanted to retrieve images from the output blob, you need different input size, see edit

berak gravatar imageberak ( 2020-10-23 02:22:15 -0600 )edit
1

No, I tried retrieval on the input blob. Moreover, output size remains the same, except channel equal 1: (1, 720, 1280. 6) -> (1, 720, 1280, 1)

st.matkov gravatar imagest.matkov ( 2020-10-23 03:14:26 -0600 )edit
1

It works! It happend to be incorrect input type. Had to convert input to CV_32F

st.matkov gravatar imagest.matkov ( 2020-10-23 09:59:45 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2020-10-22 03:44:42 -0600

Seen: 2,632 times

Last updated: Oct 23 '20