0

I have two single channel imagesMat I1; and Mat I2;. I don't have information about their datatype (i.e. uchar or float).

Task: I want to merge them into an image Mat mergedImage which should have 2 channels so that I1 and I2 can be merged into it.

Problem: Before merging the images into Mat mergedImage , i must create that image using mergedImage.create( I1.size() , ...... );

What should i fill at the place of ...... ? I just know that it should be of 2-channels so, how do i extract the datatype of I1

PS: Please don't say to use I1.type() because I1 is of single channel only.

skm
  • 5,015
  • 8
  • 43
  • 104
user2756695
  • 676
  • 1
  • 7
  • 22
  • 1
    you can query the type() in the same way you're using size() already – berak Feb 27 '14 at 20:27
  • @berak: i think that it will return the whole information i.e. `bit / datatype / channels`. But it just need to know the datatype i.e. uchar/float. Have a look at this question – skm Feb 27 '14 at 20:31
  • true. just trying to populate the idea pool .. – berak Feb 27 '14 at 20:36

3 Answers3

2

Why without?

Working without knowing the type at all is not a good idea. You can do it in C++ with templated function, but how much fexibility are you going to achieve? And how the design of your software will be increased? How many non-controlled problem are you going to crash with?

Normally when you read code on image processing that changes behaviour with respect to the type you see some if or switch condition. Much more controlled enviroment, less error proning, and much more readable code and clean behaviour, and nice way to differentiate behaviours. Why don't you want to use it? It is so simple, remember Occam's razor.

For instance something like:

if(src.type() == CV_32F || src.type() == CV_32FC1) {
    ....
}

and differentiate the behaviour with a check on the type.

If you don't trust this open some random file in the opencv source code: it is full of type checking everywhere, and silently differentiate the strategy and the implementations based on that.

nkint
  • 11,513
  • 31
  • 103
  • 174
  • If the OP don't want to use `type()`, because it includes the number of channels, he can always use `depth()` which returns `CV_32F` or `CV_8U` independently of the number of channels ... – BConic Feb 28 '14 at 08:01
1

Another simple approach to the problem:

cv::Mat I1; // Unknown depth but 1 channel
cv::Mat I2; // Unknown depth but 1 channel

// Merge
cv::Mat channels[2]={I1,I2};
cv::Mat mergedImage;
cv::merge(channels,2,mergedImage);
BConic
  • 8,750
  • 2
  • 29
  • 55
  • Thanks but then i will get the merged image with `float` datatype which might not be the type of `I1` and `I2`. But i want to get the `mergedImage` with same datatype as of "I1" and "I2". – user2756695 Feb 28 '14 at 10:57
  • @user2756695 Well, all the channels of an image **must** have the same datatype. If I1 is `float` and I2 is `uchar`, what would you do ? Also, see my comment on nkint's answer. – BConic Feb 28 '14 at 11:23
  • `I1` and `I2` must be of the same type..that's for sure. But i need to create `mergedImage` with the datatype which both `I1` and `I2` have – user2756695 Feb 28 '14 at 11:36
  • Well then it's even easier :) See my edit. The two images have the same size right ? – BConic Feb 28 '14 at 11:40
0

Yet another way to achieve what you want, using the macro CV_MAKE_TYPE, which seems closer to your approach of the problem. CV_MAKE_TYPE(depth,channels) is an undocumented OpenCV macro which enables building the type you want if you specify independently the depth and the number of channels.

Hence, you can do the following:

mergedImage.create( I1.size(), CV_MAKE_TYPE(I1.depth(),2));

Here, I1.depth() returns the datatype independently of the number of channels, unlike I1.type().

BConic
  • 8,750
  • 2
  • 29
  • 55