# OpenCV, how can we normalize a Mat min to max and max to min?

I want to normalize a Mat to the min value goes to 255 and max goes to 0 (normalize the Mat between 0~255).

For example, if we have an array like [0.02, 0.002, 0.0002] after normalization I want to get a result like this: [3, 26, 255], but now when I am using NORM_MINMAX I got [255, 26, 3].

But I did not find any function to do the inverted operation of the NORM_MINMAX.

Code used:

cv::Mat mat(10, 10, CV_64F);
mat.setTo(0);
mat.row(0) = 0.02;
mat.row(1) = 0.002;
mat.row(2) = 0.0002;
cv::normalize(mat, mat, 255, 0, cv::NORM_MINMAX);
mat.convertTo(mat, CV_8UC1);
std::cout << mat << std::endl;


Result is:

[255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
26,  26,  26,  26,  26,  26,  26,  26,  26,  26;
3,   3,   3,   3,   3,   3,   3,   3,   3,   3;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0]


But I want the inverse of the above result.

When I subtract 255 from the mat like:

cv::subtract(255, mat, mat, mat); // the last mat acts as mask
std::cout << mat << std::endl;


Result is:

[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
229, 229, 229, 229, 229, 229, 229, 229, 229, 229;
252, 252, 252, 252, 252, 252, 252, 252, 252, 252;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
0,   0,   0,   0,   0,   0,   0,   0,   0,   0]

edit retag close merge delete

That's not possible with a linear operation a*[0.02 .002 .0002]+b =[- 7.2117117 138.32883 152.88288] (a=-8085 b=154.5). You must define exactly what you want

may be you can inverse data : a*[0.02 .002 .0002].^(-1)+b = 3.045045 25.95045 255.0045

try to inverse your data and use normalize

( 2019-02-13 02:11:38 -0500 )edit

How exactly inverse a Mat, question also updated. You can take a look. Thanks!

( 2019-02-13 02:56:36 -0500 )edit

Sort by ยป oldest newest most voted

No idea how to get 3 as minimum. My answer is :

[0.02, 0.0020000001, 0.00019999999]
[50, 499.99997, 5000]
[0, 23.181816, 254.99998]


with this code

int main(int argc, char* argv[])
{
Mat imgTest = (Mat_<float>(1, 3) << 0.02,0.002,0.0002);
cout << imgTest << "\n";
imgTest.forEach<float>([](float &p, const int * /*position*/) -> void {

p = 1/p;
});
cout << imgTest << "\n";
Mat dstTest;
normalize(imgTest, dstTest, 255, 0, NORM_MINMAX);
cout << dstTest << "\n";

return 0;
}


I think you can create a vector of indices of a sorted vector too

Mat imgTest = (Mat_<float>(2,3) << 0.0002,0.02,0.00250,0.0005,.002,0.01);
normalize(imgTest, imgTest, 255, 0, NORM_MINMAX);

std::vector<int> y(static_cast<int>(imgTest.total()));
std::size_t n(0);
std::generate(std::begin(y), std::end(y), [&] { return n++; });
if (imgTest.isContinuous())
std::sort(std::begin(y),
std::end(y),
[&](int i1, int i2) { return imgTest.ptr<float>(0)[i1] < imgTest.ptr<float>(0)[i2]; });
else
{
cout << "cannot do that";
return 0;
}

Mat dstTest(imgTest.size(),imgTest.type());
for (int i = 0; i < imgTest.total(); i++)
dstTest.ptr<float>(0)[i] = imgTest.ptr<float>(0)[y[i]];

cout << dstTest << "\n";


https://stackoverflow.com/questions/2...

more

Thank you, bro! I finally found a solution on how to calculate.

( 2019-02-13 19:37:48 -0500 )edit

Official site

GitHub

Wiki

Documentation