Ask Your Question
0

Saving and retrieving Mat data

asked 2017-03-20 06:23:09 -0600

k_kaz gravatar image

updated 2017-03-20 06:42:47 -0600

I want to save Mat data to a float array, process them, and then save them back to Mat. I don't want to use .at function, cause processing code is already written and uses some temp arrays.

I have this piece of code:

cv::Mat test(cv::Mat original) {

    float * image_data = new float[original.rows * original.cols];

    //Save to array
    init_data_image_32(original, image_data);

    //process


    //Restore from array
    cv::Mat res(original.rows, original.cols, CV_32F, image_data, original.cols);

    cv::namedWindow("b", CV_WINDOW_NORMAL);
    cv::imshow("b", res);
    return res;
}

bool doublesEqual(double a, double b) {
    double margin_of_error = 0.0001;
    return abs(a - b) < margin_of_error;
}

void init_data_image_32(cv::Mat image, float * image_data) {
    for (int i = 0; i < image.rows; i++)
        for (int j = 0; j < image.cols; j++) {
            image_data[i*image.cols + j] = image.at<float>(i, j);
            if (!doublesEqual(image_data[i*image.cols + j], image.at<float>(i, j))) std::cout << image_data[i*image.cols + j] << " " << image.at<float>(i, j) << std::endl;
        }
}

The imshow of the resulting image in the imshow(b) has nothing to do with original, its this one: image description

Furthermore, the init_data_image_32 has some lines of output from the if clause:

nan nan
nan nan
nan nan
..

What am i doing wrong?

edit retag flag offensive close merge delete

Comments

what are you trying to achieve, that couldn't be done with a simple:

Mat res = original.clone();

? please do not use temp arrays, new, or iterate over pixel values, those are all clear antipatterns here (you also have a memleak there)

berak gravatar imageberak ( 2017-03-20 06:48:01 -0600 )edit
1

@berak Under the //process clause there is code for processing the image_data, that is written with c-like arrays. I could change that code so that every element access is done with .at but this code uses temp, old and new arrays so it would be complicated. So i want to initialize the initial c-like array from the original's data. I know about the memory leak.

k_kaz gravatar imagek_kaz ( 2017-03-20 06:52:04 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-03-20 07:00:44 -0600

berak gravatar image

please avoid copying single pixels, and manual memory management in general. rather:

// get pointer from Mat:
CV_Assert(original.isContinuous()); // e.g. not a ROI
CV_Assert(original.type() == CV_32F); // make sure, the type fits !
float * ptr = original.ptr<float>();
// process ptr

// set pointer:
float *image_data = ... // something from c
Mat res(original.size(), original.type(), image_data); //this will copy the *pointer*,not the data!
return res.clone(); // deep copy
edit flag offensive delete link more

Comments

Nice. Still unsure though why the nan values...

k_kaz gravatar imagek_kaz ( 2017-03-20 07:04:05 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-03-20 06:23:09 -0600

Seen: 1,698 times

Last updated: Mar 20 '17