Ask Your Question
1

Change blobFromImage dimensions order

asked Oct 22 '0

st.matkov gravatar image

updated Oct 23 '0

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.

Preview: (hide)

Comments

1

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

berak gravatar imageberak (Oct 22 '0)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 (Oct 22 '0)edit

1 answer

Sort by » oldest newest most voted
1

answered Oct 22 '0

berak gravatar image

updated Oct 23 '0

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);
Preview: (hide)

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 (Oct 22 '0)edit
2

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

st.matkov gravatar imagest.matkov (Oct 22 '0)edit

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

berak gravatar imageberak (Oct 23 '0)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 (Oct 23 '0)edit
1

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

st.matkov gravatar imagest.matkov (Oct 23 '0)edit

Question Tools

1 follower

Stats

Asked: Oct 22 '0

Seen: 2,818 times

Last updated: Oct 23 '20