简体   繁体   English

创建垫子后,根据字节向量将图像加载到垫子上

[英]Loading an image on a mat from a vector of bytes after the mat is created

My situation is the next: I'm working on a multi-threaded application in which differents threads receive images in the form of bytes from sockets, store them in a vector<char> and should generate a cv::Mat with it in order to be able to do the processing with OpenCV . 下一个问题是我的情况:我正在一个多线程应用程序中,其中不同线程从套接字接收字节形式的图像,将它们存储在vector<char>并应cv::Mat顺序生成cv::Mat能够使用OpenCV进行处理。 Well, the complications are mainly because in order to separate the private data of every thread from the one of the others I used an array of structs , which I declared with all the data structures that every thread may need. 好吧,复杂性主要是因为为了将每个线程私有数据与另一个线程分开,我使用了一个struct数组 ,并声明了每个线程可能需要的所有数据结构。 Thus I also have to declare the vector<char> and the cv::Mat inside of it, and once the vector has received all the image bytes I have to find a way to 'load them' appropriately inside the cv::Mat without creating any additional one , because the memory space reserved to every thread is fixed. 因此,我还必须在其中声明vector<char>cv::Mat ,一旦向量接收到所有图像字节,我就必须找到一种方法将其适当地“加载”到cv::Mat 而无需创建任何其他线程,因为为每个线程保留的内存空间是固定的。


What I've tried so far: 到目前为止,我已经尝试过:

struct thread_data {                   //private data for threads
     std::vector<char> buf_img;
     Mat img_scene;
     Mat img_temp;
     //...

     thread_data() { 
          buf_img.reserve(65000),      // initialization with enough space
      img_scene.create(700,500, CV_8U),
      img_temp.create(700,500, CV_8U);
          }
    };


thread_data *tdata;
// declare array of structs
tdata = (thread_data * ) calloc(nthreads, sizeof(thread_data));

//...

// And the thread function, once received the image:

private_tm->img_temp = cv::Mat(private_tm->buf_img,true).clone(); //from vector to Mat

if( !private_tm->img_temp.data ) { 
      std::cout<< " --(!) Image could not be read " << std::endl; 
      private_tm->answer = "error";
}
else {
    // decode image and call the function passing the pointer to the struct:
    private_tm->img_scene = cv::Mat(cv::imdecode(private_tm->temp,1)).clone();
private_tm->answer = OCV_func((void*)private_tm); 
 }

Result after receiving one single image: 收到一张图像后的结果:

> Thread 2:
> ==12142== Invalid write of size 4
> ==12142==    at 0x804B869: cv::Mat::release() (mat.hpp:369)
> ==12142==    by 0x804EEDD: cv::Mat::operator=(cv::Mat const&) (mat.hpp:287)
> ==12142==    by 0x804E8A2: thread_main(void*) (threads.cpp:408)
> ==12142==    by 0x45A4D4B: start_thread (pthread_create.c:308)
> ==12142==    by 0x46A7DDD: clone (clone.S:130)
> ==12142==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
> ==12142== 
> ==12142== 
> ==12142== Process terminating with default action of signal 11 (SIGSEGV)
> ==12142==  Access not within mapped region at address 0x0
> ==12142==    at 0x804B869: cv::Mat::release() (mat.hpp:369)
> ==12142==    by 0x804EEDD: cv::Mat::operator=(cv::Mat const&) (mat.hpp:287)
> ==12142==    by 0x804E8A2: thread_main(void*) (threads.cpp:408)
> ==12142==    by 0x45A4D4B: start_thread (pthread_create.c:308)
> ==12142==    by 0x46A7DDD: clone (clone.S:130)

I really need help about it because I feel that probably exists an easy solution that I am not being able to see. 我确实需要帮助,因为我觉得可能存在一个我看不到的简单解决方案。


Some research: 有些研究:

-I searched until exhaustion inside the cv::Mat declaration in OpenCV documentation for a function that could do the trick but I had no luck. -我一直搜索直到OpenCV文档中的cv :: Mat声明用尽为止,该函数可以完成上述任务,但我没有运气。 I can't find a function that without creating a new Mat might get the image (from a vector, char* or file). 我找不到一个没有创建新Mat就能获得图像(从矢量,char *或文件)的函数。 mat documentation 垫文件

-Here is a similar question to what I need (with very unsatisfactory answers): link -这是我需要的类似问题(答案非常不满意): 链接

Thanks in advance. 提前致谢。

You cannot use calloc in the way you are. 您不能以自己的方式使用calloc It will only allocate memory for the thread_data object but will not call its constructor or the constructors of its subobjects. 它只会为thread_data对象分配内存,而不会调用其构造函数或其子对象的构造函数。

Change the following... 更改以下内容...

thread_data *tdata;
// declare array of structs
tdata = (thread_data * ) calloc(nthreads, sizeof(thread_data));

to... 至...

thread_data *tdata = new thread_data();

I highly recommend using smart pointers such as std::unique_ptr so that you do not have to worry about calling delete . 我强烈建议您使用诸如std::unique_ptr类的智能指针,这样您就不必担心调用delete

std::unique_ptr<thread_data> tdata(new thread_data());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM