OpenCV Integer division in C ++ is not as expected

Given the following conclusion:

[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 expect 11233/256 to be 43 using integer division?

Is my assumption that C ++ always does integer gender division?

Update

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

+5
source share
3 answers

Separation is not really a whole division. Most features in OpenCV convert their input to Scalar, which is a container for 1, 2, 3, or 4 two-local ones. And other functions in OpenCV that perform similar operations (scaleAdd, addWeighted, convertTo, etc.) also work with doubles. In other words, your code divides by double and rounds the result. That's why you got 44 instead of 43.

Edit:

As for the "encode" function, you do not need to perform complex operations. A byte for your new matrix already exists. You just need to create a convenient way to access them:

 Mat temp(src.size(), CV_8UC4, src.data); 

This will create a new matrix header (i.e. no copy of the data) indicating src data. But instead of seeing the data as an integer matrix with one channel, it will be a 4-channel matrix without the char sign (with the same width and height). How can you do anything with a multi-channel matrix: split (), merge (), mixChannels (), etc.

+3
source

No, you're right, integer division is performed by gender in C ++. See [Expr.mul]:

For integral operands, the operator / gives an algebraic relation with any fractional part discarded; 81

81) This is often called truncation to zero.

+2
source

Here is a manual function to perform integer division on OpenCV based on your ideas. Hope this will be helpful.

 #include "opencv2\highgui.hpp" using cv::Mat; #include "opencv2\imgproc.hpp" using cv::threshold; void IntegerDivide(Mat& Input_Dividendo, int Input_Divisor, Mat& Output_Cociente, Mat& Output_Resto) { // Input_Dividendo is supposed to be CV_32S // Input_Dividendo = Input_Divisor * Output_Cociente + Output_Resto Mat candidato_Cociente=Input_Dividendo/Input_Divisor; Mat offset=Input_Dividendo-(candidato_Cociente*Input_Divisor); Mat error_en_candidato_Cociente; // Threshold // threshold( offset, error_en_candidato_Cociente, 0, 1,CV_THRESH_BINARY_INV); Mat aux_src; offset.convertTo(aux_src,CV_32F); Mat aux_dst; threshold( aux_src, aux_dst, 0, 1,CV_THRESH_BINARY_INV); aux_dst.convertTo(error_en_candidato_Cociente,CV_32S); // End threshold Output_Cociente=candidato_Cociente-error_en_candidato_Cociente; Output_Resto=Input_Dividendo-(Output_Cociente*Input_Divisor); } 
0
source

Source: https://habr.com/ru/post/1203114/


All Articles