GIVEN:
The following code fragment:
#include <opencv2/core.hpp>
#include <iostream>
int
main(int argc, char** argv)
{
cv::Mat a = (cv::Mat_<double>(3,1) << 1, 2, 3);
cv::Mat b;
std::cout << "a(before): " << cv::typeToString(a.type()) << std::endl;
std::cout << "b(before): " << cv::typeToString(b.type()) << std::endl;
std::cout << std::endl;
std::cout << "Convert 'a' --> 'b' with type CV_64FC4" << std::endl;
std::cout << std::endl;
a.convertTo(b, CV_64FC4);
std::cout << "a(after): " << cv::typeToString(a.type()) << std::endl;
std::cout << "b(after): " << cv::typeToString(b.type()) << std::endl;
return 0;
}
EXPECTATION:
Should produce, in my understanding, the following output:
a(before): CV_64FC1
b(before): CV_8UC1
Convert 'a' --> 'b' with type CV_64FC4
a(after): CV_64FC1
b(after): CV_64FC4
OUTPUT:
Instead, the output is as follows:
a(before): CV_64FC1
b(before): CV_8UC1
Convert 'a' --> 'b' with type CV_64FC4
a(after): CV_64FC1
b(after): CV_64FC1
QUESTION:
What is going on here? How can I actually convert to the specified target type?
Short answer:
cv::Mat::convertTodoes not support changing the number of channels.Longer answer:
As you can see in the documentation regarding the
rtypeparemeter ofcv::Mat::convertTo(the one you passCV_64FC4to):I.e.
convertTodoes not handle the case of changing the number of channels (only the bit depth of each channel).Although it is not documented explicitly, I guess
cv::Mat::convertToextracts the bit depth fromrtypeand ignores the number of channels.In your example:
ahas a single channels, and therefore so isbafter the conversion.In order to see the effect of
convertTo, you can pass e.g.CV_32FC1in order to convert 64 bitdoubles to 32 bitfloats.Update:
According to the OP's request (in the comments below), here are examples of changing the number of channels using
cv::mixChannels: