Given the following output:
[11233, 11345, 11434, 10897] [44, 44, 45, 43] [-31, 81, -86, -111]
from this code
std::cout << mat32sc1;
channels[1] = mat32sc1 / 256;
channels[0] = mat32sc1 - channels[1] * 256;
std::cout << channels[1];
std::cout << channels[0];
I would have expected 11233 / 256 to be 43, using integer division?
Is my assumption wronge that c++ always do integer division by flooring?
Here is my current encoding function.
void encode(cv::Mat & src, cv::Mat & dst)
{
cv::Mat_<int> mat32sc1;
src.convertTo(mat32sc1, CV_32SC1, 10, 11000);
std::vector<cv::Mat> channels;
channels.resize(3);
// bitwise_and(mat32sc1, cv::Scalar(255), channels[0]); // is this needed or will converTo truncate automaticly.
// channels[0].convertTo(channels[0], CV_8UC1);
// mat32sc1.convertTo(channels[1], CV_8UC1, 1.0 / (1 << 8));
channels[2] = cv::Mat::zeros(src.rows, src.cols, CV_8UC1);
int flag = 256;
// std::cout << mat32sc1;
channels[1] = mat32sc1 / flag;
channels[0] = mat32sc1 - channels[1] * flag;
cv::Mat_<int> off = (channels[0] < 0) / 255;
//std::cout << off;
channels[1] -= off;
channels[0] = mat32sc1 - channels[1] * flag;
//std::cout << channels[1];
//std::cout << channels[0];
channels[0].convertTo(channels[0], CV_8UC1);
channels[1].convertTo(channels[1], CV_8UC1);
cv::merge(channels, dst);
}
Any smarter way to get the same result
The division is indeed not an integer division. Most functions in OpenCV convert their input to Scalar, which is container for 1, 2, 3, or 4 doubles. And other functions in OpenCV that perform similar operations (scaleAdd, addWeighted, convertTo, etc...) all works with doubles as well. In other words, your code performing division by double and rounding of the result. This is why you got 44 instead of 43.
Edit:
As for the "encode" function you don't need to perform complex operations. The bytes for your new matrix are already there. You just need to create convenient way of accessing them:
Mat temp(src.size(), CV_8UC4, src.data);
This will create new matrix header (i.e. no copy of data) that point to the data of src. But instead of seeing the data as integer matrix with single channel, it will be 4-channel matrix of unsigned char (with same width and height). Than you can do anything with multi-channel matrix: split(), merge(), mixChannels(), etc...
No, you're right, integer division is performed by flooring in C++. See [expr.mul]:
For integral operands the / operator yields the algebraic quotient with any fractional part discarded; 81
81) This is often called truncation towards zero.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With