Ask Your Question
0

opencv mat object thread safety

asked 2016-01-14 10:06:47 -0600

carl82 gravatar image

There is some ambiguity about this issue. Some answers here and at stackoverflow say that mat object has some thread safety, while others say that it's not thread safe. Most of those questions about threading are in write context. As in simultaneously modifying mat object. I'm interested in reading different mat objects from different threads. My code is too complex to post here, so I'll do some overview.

Mat objects(basically images) are stored in a Vector. When vector's size reaches a predefined number, I stop adding to the vector and start processing the vector in different threads. So, first mat object in the vector gets assigned to thread 0 (threads are created with c++11 thread), second to thread 1 and so on. No modification to the vector occurs. This is strictly just reading.

Mat processing function is extremely simple, it's just:

Mat& I = image; //image comes from vector
for (int i = 0; i < I.rows; i++){
for (int t = 0; t < I.cols; t++){
    ColorValue = GetColorVal(I.at<Vec3b>(i, t)[0], I.at<Vec3b>(i, t)[1], I.at<Vec3b>(i, t)[2]);
  //do some other stuff here

The problem is results from GetColorVal function is incomplete. It doesn't matter if I use mutex.locks, or limit thread count to 1, it's always incomplete. I'm not modifying anything at all, just reading. It doesn't process the whole image as far as I can tell. If I disable threading, same code gives correct results.

My plan is to at this point, separate image processing code to a smaller app and use tcp or some other process communication library(like nanomsg) to move and process the images. I plan to run 7-8 of these smaller apps.

But before I do all that work, I wanted to be sure that even in read context, opencv mat, is not thread safe.

edit retag flag offensive close merge delete

Comments

Have you used decode for decoding from vector?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2016-01-14 10:10:08 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-01-14 10:29:45 -0600

Kellerspeicher gravatar image

If I is a reference to an entry of the vector<> you will always get trouble if the vector<> is reallocating e.g. if getting bigger. I do not think that this has got something to do with the thread safety of the Mat methods. If you protect your vector<> by mutex and take a deep copy of Mat (e.g. by clone() or copyTo()) it works like a charm. I use something very similar to distribute the processing of video frames to a bunch of threads without problems.

edit flag offensive delete link more

Comments

By the time threads process vector, the vector is essentially read only. Could you tell me why I should clone the mat object? I read it somewhere else too, but from a performance standpoint, shouldn't it be better if I just work with the one in the vector?

carl82 gravatar imagecarl82 ( 2016-01-14 15:10:49 -0600 )edit
1

What do you mean by essentially read only? If it is not completely read only you have changes and these might interfere with your threads. That is why I pointed to the typical problem of pointers or references to vector elements if reallocation occurs. Read only shall be forced by const declaration e.g. in your first line const Mat& I. If you "read it somewhere else too" both usages shall be const. Otherwise you do not know what changes take place without being obvious.

Kellerspeicher gravatar imageKellerspeicher ( 2016-01-14 16:28:19 -0600 )edit
1

It is difficult to evaluate such things from a single code fragment without a "Minimal, Complete, and Verifiable example". If your program runs with one thread and didn't run with more, you have interference in between. Taking a copy is one way to prevent these. By the way, if you plan to transfer by TCP why worrying about local copy time effort?

Kellerspeicher gravatar imageKellerspeicher ( 2016-01-14 16:30:11 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-01-14 10:06:47 -0600

Seen: 3,934 times

Last updated: Jan 14 '16