Ask Your Question

Revision history [back]

click to hide/show revision 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 !

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 To performs what you 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.size(), CV_32FC1); cv::multiply(src, 1./255,src_multiply, 1,src_multiply.type()); clog << "src_multiply= " << endl << " " << src_multiply << endl << endl;

src_multiply= 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 !

!

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]

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]