Ask Your Question
0

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

asked 2019-02-13 02:00:50 -0600

BAHRAMUDIN ADIL gravatar image

updated 2019-02-13 03:00:06 -0600

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 flag offensive close merge delete

Comments

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

LBerger gravatar imageLBerger ( 2019-02-13 02:11:38 -0600 )edit

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

BAHRAMUDIN ADIL gravatar imageBAHRAMUDIN ADIL ( 2019-02-13 02:56:36 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2019-02-13 03:12:21 -0600

LBerger gravatar image

updated 2019-02-13 04:36:50 -0600

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...

edit flag offensive delete link more

Comments

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

BAHRAMUDIN ADIL gravatar imageBAHRAMUDIN ADIL ( 2019-02-13 19:37:48 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-02-13 02:00:50 -0600

Seen: 6,750 times

Last updated: Feb 13 '19