Why imread is reallocating data buffer
Hello!
I recently ask an other question similar to this one. Here I don't have any CUDA dependencies :
I create a Mat using a pre-allocated data buffer. Here's a code example :
#include <iostream>
#include <experimental/filesystem>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
namespace fs = std::experimental::filesystem;
int main(int argc, char const *argv[])
{
// ---- get arguments ----
if (argc < 2) {
std::cout << "number of arguments invalid" << std::endl;
std::cout << "1 - Input Folder" << std::endl;
std::cout << "2 - Output Folder" << std::endl;
exit(1);
}
std::string input_folder = argv[1];
std::string output_folder = argv[2];
int cols = 5344, rows = 4016; //your image size
cv::Vec3b *src_ptr = (cv::Vec3b *)malloc(rows*cols*sizeof(cv::Vec3b));
cv::Mat src(rows, cols, CV_8UC3, src_ptr);
std::cout << src_ptr << " " << src.ptr<cv::Vec3b>() << " " << src.size() << std::endl;
for (const auto& entry : fs::directory_iterator(input_folder))
{
src = cv::imread(entry.path());
std::cout << src_ptr << " " << src.ptr<cv::Vec3b>() << " " << src.size() << std::endl;
}
return 0;
}
I have an input folder with a set of images, and I am printing the address of the buffer alongside the current address of the data of Mat src. (Also with the size to prove that it is the same).
When running it, the address of src data change, and if you have more than one image, you can see that imread reallocate data at the same address every two images. Imread is supposed to call Mat::create : it should not reallocate if it is the same size!
I tried another test :
cv::Mat temp;
In the for loop :
temp = cv::imread(entry.path());
temp.copyTo(src);
Here the right pre-allocated address is used.
I'm looking to avoid this copy and directly use imread. Why does it behave like this?
Thanks in advance for any answers!!!
When you do
you are performing an assignment of the result of imread() to src. As a result you are overwriting what ever was in src. I guess you want a version like the below (which unfortunately doesn't exist)
which you can pass src to by reference?
Alternatively you could use cudacodec which allows you to pass the GpuMat in but this will depend on you use case.
You're right, i didn't even think of the assignment. With the reference that would be wonderful but still it doesn't exist. I searched for a gpu version of imread in the documentation of cudacodecs but didn't find anything relevant. What were you thinking of ? Thanks for your comment
There is no GPU version of imread you need to use
which is fine if you are already performing processing on the GPU.
Ok I'm going to look at that! thank you.