Ask Your Question
1

Fast element access macro in C++ API

asked 2016-03-10 03:34:14 -0600

strann gravatar image

updated 2016-03-10 03:44:40 -0600

Is there any reason I should not use a macro for fast element access in C++ API (like CV_MAT_ELEM_PTR_FAST in C API)? Here's my implementation

 #define MY_MAT_ELEM_PTR_FAST( mat, row, col, elemtype )  \
(assert( (unsigned)(row) < (unsigned)(mat).rows &&   \
         (unsigned)(col) < (unsigned)(mat).cols ),   \
   (* (elemtype*) ( (mat).data + (mat).step*(row) + (sizeof(elemtype)*(col)) ) ) )
edit retag flag offensive close merge delete

Comments

can you show us, what you're actually trying ?

berak gravatar imageberak ( 2016-03-10 03:39:57 -0600 )edit
1

I've edited question

strann gravatar imagestrann ( 2016-03-10 03:43:49 -0600 )edit

3 answers

Sort by ยป oldest newest most voted
4

answered 2016-03-10 03:53:45 -0600

kbarni gravatar image

updated 2016-03-10 04:05:43 -0600

Yes, there is: The image is not always continuous in the memory; so mat.data+(y*width+x)*sizeof(elemtype) won't give you the pixel (x,y). Check if the matrix is continuous with mat.isContinuous().

You can use mat.ptr() of mat.ptr(row) instead mat.data (that you can cast directly to another type).

So the last line of the macro could look like (for a more general application):

(elemtype*) (mat.ptr(row)) + col

I also think (but I might be wrong) that the line pointers are precomputed, so this can save you a multiplication.

To access an element directly you can use the standard mat.at<elemtype>(y,x), it's also fast.

edit flag offensive delete link more

Comments

1

Just use the method the author of the test suggests (especially if you don't need random element access).

Then, replace the first for loop with a parallel_for (from the TBB library). It will fly :)

kbarni gravatar imagekbarni ( 2016-03-10 04:14:49 -0600 )edit

thank you! I will try using parallel_for

p.s. I've accidentally deleted my previous comment :( here's the performance test I've found on the web (maybe someone will find it useful) http://longstryder.com/2014/07/which-...

strann gravatar imagestrann ( 2016-03-10 04:37:56 -0600 )edit
4

answered 2016-03-10 04:01:53 -0600

berak gravatar image

yes, there are a lot of arguments against your approach:

  • premature optimization (look it up)
  • you should not mess with cv::Mat's internal structure at all
  • your code is slower that Mat ::at()
  • this is not C, and your macro is messy

in general:

  • avoid per-pixel operations at all cost, in 90% cases, there's a high-level, optimized function for this already in opencv

  • get a row ptr(), and access the desired type directly, like explained here

  • don't try to be smart. don't try to be smarter than the devs.

edit flag offensive delete link more

Comments

Thank you for the complete answer! I've been using the method described in documentation as the efficient way. I just found the macro and became curious.

strann gravatar imagestrann ( 2016-03-10 04:33:36 -0600 )edit
1

answered 2016-03-10 04:17:22 -0600

essamzaky gravatar image

updated 2016-03-10 04:26:52 -0600

There are 3 methods , to access MAT elements
1-Pointer method (effecint in time , but risky in handling piointers errors)
2-Iterator method (the safe mode)
3-On the fly method
also there is LUT which give best time because Opencv optmization for multithreading and multicore
you can find examples for every method in the following link [link text](http://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html)

link text

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-03-10 03:34:14 -0600

Seen: 1,470 times

Last updated: Mar 10 '16