1 | initial version |
Your issue doesn't depends from compiler flags but comes from hidden cast.
cv::operator/
do the operation using src.type for result than cast the result to destination Mat. In your case src is uchar so it will becomes result = float(uchar(uchar/float))
. You should use cv::multiply
or Mat::convertTo
to performs what you need. Check the code below... I'm using 1 channel vector for pretty print
Mat src(1,4, CV_8UC1);
src.at<uchar>(0,0) = 64;
src.at<uchar>(0, 1) = 127;
src.at<uchar>(0, 2) = 200;
src.at<uchar>(0, 3) = 255;
clog << "src= " << endl << " " << src << endl;
src= [ 64, 127, 200, 255]
Mat1f src_float = src / 255.f;
clog << "src_float= " << endl << " " << src_float << endl << endl;
src_float= [0, 0, 1, 1] as you see 64/255 becomes 0 while 200/255 becomes 1 due to cast !!
Mat src_multiply(src.size(), CV_32FC1);
cv::multiply(src, 1./255,src_multiply, 1,src_multiply.type());
clog << "src_multiply= " << endl << " " << src_multiply << endl << endl;
src_multiply= [0.25098041, 0.49803922, 0.78431374, 1] it's ok now !
Mat src_convert(src.size(), CV_32FC1);
src.convertTo(src_convert, src_convert.type(), 1. / 255);
clog << "src_convert= " << endl << " " << src_convert << endl << endl;
src_convert= [0.25098041, 0.49803925, 0.7843138, 1] it's ok too !
2 | No.2 Revision |
Your issue doesn't depends from compiler flags but comes from hidden cast.
cv::operator/
do the operation using src.type for result than cast the result to destination Mat. In your case src is uchar so it will becomes result = float(uchar(uchar/float))
. You should use To performs what you cv::multiply
or Mat::convertTo
to need. need you have to use additional explicit Mat()
or Mat_<T>()
constructor calls or use cv::multiply
or Mat::convertTo
. Check the code below...
As source I'm using 1 channel vector for pretty print
print:
Mat src(1,4, CV_8UC1);
src.at<uchar>(0,0) = 64;
src.at<uchar>(0, 1) = 127;
src.at<uchar>(0, 2) = 200;
src.at<uchar>(0, 3) = 255;
clog << "src= " << endl << " " << src << endl;
src= //src= [ 64, 127, 200, 255]
255]
Your code:
Mat1f src_float = src / 255.f;
clog << "src_float= " << endl << " " << src_float << endl << endl;
src_float= //src_float= [0, 0, 1, 1] as you see 64/255 becomes 0 while 200/255 becomes 1 due to cast !!
!!
Use explicit matrix cast constructor (this will create a temporary float Mat src_multiply= src_multiply(src.size(), CV_32FC1);
cv::multiply(src, 1./255,src_multiply, 1,src_multiply.type());
clog << "src_multiply= " << endl << " " << src_multiply << endl << endl;
to convert src to float)
Mat1f src_float_cast = Mat_<float>(src) / 255;
clog << "src_float_cast= " << endl << " " << src_float_cast << endl << endl;
//src_float_cast= [0.25098041, 0.49803922, 0.78431374, 1] it's ok now !
!
Use cv::multiply:
Mat src_multiply(src.size(), CV_32FC1);
cv::multiply(src, 1./255,src_multiply, 1,src_multiply.type());
clog << "src_multiply= " << endl << " " << src_multiply << endl << endl;
//src_multiply= [0.25098041, 0.49803922, 0.78431374, 1] it's ok now !
Use Mat::convertTo:
Mat src_convert(src.size(), CV_32FC1);
src.convertTo(src_convert, src_convert.type(), 1. / 255);
clog << "src_convert= " << endl << " " << src_convert << endl << endl;
src_convert= //src_convert= [0.25098041, 0.49803925, 0.7843138, 1] it's ok too !
3 | No.3 Revision |
Your issue doesn't depends from compiler flags but comes from hidden cast.
cv::operator/
do the operation using src.type for result than cast the result to destination Mat. In your case src is uchar so it will becomes result = float(uchar(uchar/float))
. To performs what you need you have to use additional explicit Mat()
or Mat_<T>()
constructor calls or use cv::multiply
or Mat::convertTo
. Check the code below...
As EDIT:As source I'm using 1 3 channel vector for pretty print:clear understand Mat_<T>
constructor:
Mat src(1,4, CV_8UC1);
src.at<uchar>(0,0) src(1, 4, CV_8UC3);
src.at<Vec3b>(0, 0) = 64;
src.at<uchar>(0, src.at<Vec3b>(0, 1) = 127;
src.at<uchar>(0, src.at<Vec3b>(0, 2) = 200;
src.at<uchar>(0, src.at<Vec3b>(0, 3) = 255;
clog << "src= " << endl << " " << src << endl;
//src= [ 64, //src = [64, 0, 0, 127, 0, 0, 200, 255]
0, 0, 255, 0, 0]
Your code:code :
Mat1f Mat3f src_float = src / 255.f;
clog << "src_float= " << endl << " " << src_float << endl << endl;
//src_float= //src_float = [0, 0, 0, 0, 0, 0, 1, 1] as you see 64/255 becomes 0 while 200/255 becomes 1 due to cast !!
0, 0, 1, 0, 0]
Use explicit matrix cast constructor (this constructor(this will create a temporary float Mat to convert src to float)float). The type used for Mat_<T>
refers to the destination pixel type:
Mat1f //Mat1f src_float_cast = Mat_<float>(src) / 255;
255; // 1 channel float pixel
//Mat src_float_cast = Mat_<uchar>(src) / 255; // 1 channel byte pixel
Mat3f src_float_cast = Mat_<Vec3f>(src) / 255; // 3 channel float pixel
clog << "src_float_cast= " << endl << " " << src_float_cast << endl << endl;
//src_float_cast= [0.25098041, 0.49803922, 0.78431374, 1] it's ok now !
Use cv::multiply:
Mat src_multiply(src.size(), CV_32FC1);
CV_32FC3);
cv::multiply(src, 1./255,src_multiply, 1,src_multiply.type());
1. / 255, src_multiply, 1, src_multiply.type());
clog << "src_multiply= " << endl << " " << src_multiply << endl << endl;
//src_multiply= [0.25098041, 0, 0, 0.49803922, 0, 0, 0.78431374, 1] it's ok now !
0, 0, 1, 0, 0]
Use Mat::convertTo:
Mat src_convert(src.size(), CV_32FC1);
CV_32FC3);
src.convertTo(src_convert, src_convert.type(), 1. / 255);
clog << "src_convert= " << endl << " " << src_convert << endl << endl;
//src_convert= //src_convert = [0.25098041, 0, 0, 0.49803925, 0, 0, 0.7843138, 1] it's ok too !
0, 0, 1, 0, 0]
4 | No.4 Revision |
Your issue doesn't depends from compiler flags but comes from hidden cast.
cv::operator/
do the operation using src.type for result than cast the result to destination Mat. In your case src is uchar so it will becomes result = float(uchar(uchar/float))
. To performs what you need you have to use additional explicit Mat()
or Mat_<T>()
constructor calls or use cv::multiply
or Mat::convertTo
. Check the code below...
EDIT:As source I'm using 3 channel vector for clear understand Mat_<T>
constructor:
Mat src(1, 4, CV_8UC3);
src.at<Vec3b>(0, 0) = 64;
src.at<Vec3b>(0, 1) = 127;
src.at<Vec3b>(0, 2) = 200;
src.at<Vec3b>(0, 3) = 255;
clog << "src= " << endl << " " << src << endl;
//src = [64, 0, 0, 127, 0, 0, 200, 0, 0, 255, 0, 0]
Your code :
Mat3f src_float = src / 255.f;
clog << "src_float= " << endl << " " << src_float << endl << endl;
//src_float = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0]
0] as you can see 64/255 = 0 and 200/255=1 due to cast ?!?!
Use explicit matrix cast constructor(this will create a temporary float Mat to convert src to float). The type used for Mat_<T>
refers to the destination pixel type:
//Mat1f src_float_cast = Mat_<float>(src) / 255; // 1 channel float pixel
//Mat src_float_cast = Mat_<uchar>(src) / 255; // 1 channel byte pixel
Mat3f src_float_cast = Mat_<Vec3f>(src) / 255; // 3 channel float pixel
clog << "src_float_cast= " << endl << " " << src_float_cast << endl << endl;
//src_float_cast= [0.25098041, 0.49803922, 0.78431374, 1] //[0.25098041, 0, 0, 0.49803925, 0, 0, 0.7843138, 0, 0, 1, 0, 0] it's ok now !
Use cv::multiply:
Mat src_multiply(src.size(), CV_32FC3);
cv::multiply(src, 1. / 255, src_multiply, 1, src_multiply.type());
clog << "src_multiply= " << endl << " " << src_multiply << endl << endl;
//src_multiply= [0.25098041, 0, 0, 0.49803922, 0, 0, 0.78431374, 0, 0, 1, 0, 0]
Use Mat::convertTo:
Mat src_convert(src.size(), CV_32FC3);
src.convertTo(src_convert, src_convert.type(), 1. / 255);
clog << "src_convert= " << endl << " " << src_convert << endl << endl;
//src_convert = [0.25098041, 0, 0, 0.49803925, 0, 0, 0.7843138, 0, 0, 1, 0, 0]