0

私の状況は次のとおりです。さまざまなスレッドがソケットからバイトの形式で画像を受信し、それらをに格納し、処理を実行できるようにするために、それを使用してvector<char>を生成する必要があるマルチスレッド アプリケーションに取り組んでいます。 OpenCV . 複雑なのは主に、すべてのスレッドのプライベート データを他のスレッドから分離するために、すべてのスレッドが必要とする可能性のあるすべてのデータ構造で宣言したstructsの配列を使用したためです。したがって、その内部で とも宣言する必要があり、ベクトルがすべての画像バイトを受け取ったら、内部で適切に「ロード」する方法を見つける必要があります。cv::Matvector<char>cv::Matcv::Mat すべてのスレッドに予約されているメモリ空間が固定されているため、追加のものを作成する必要はありません。


私がこれまでに試したこと:

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); 
 }

1 つの画像を受け取った後の結果:

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

私が見ることができない簡単な解決策がおそらく存在すると感じているので、私はそれについて本当に助けが必要です.


いくつかの研究:

-OpenCVドキュメントのcv::Mat宣言内で、このトリックを実行できる関数を探し尽くしましたが、運がありませんでした。新しい Mat を作成せずに画像を取得する関数が見つかりません(ベクター、char*、またはファイルから)。マットドキュメンテーション

-これは私が必要とするものと同様の質問です(非常に不十分な回答があります):リンク

前もって感謝します。

4

1 に答える 1

0

そのままでは使えませんcallocthread_dataオブジェクトにメモリを割り当てるだけで、そのコンストラクターまたはそのサブオブジェクトのコンストラクターを呼び出しません。

以下を変更...

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

に...

thread_data *tdata = new thread_data();

std::unique_ptrの呼び出しを心配する必要がないように、などのスマート ポインターを使用することを強くお勧めしますdelete

std::unique_ptr<thread_data> tdata(new thread_data());
于 2013-08-04T16:11:06.350 に答える