regionprops Very slow on centroid identification

Juan Nunez-Iglesias jni.soma at gmail.com
Fri Nov 14 22:29:03 EST 2014


Hi Jeff,

Firstly, what's with all the trailing underscores? Makes my brain hurt. =)

Second, this is *somewhat* of a known issue. See:
https://github.com/scikit-image/scikit-image/issues/1092

(Including the notebook link from that issue.)

As you can see, PR 1096
<https://github.com/scikit-image/scikit-image/pull/1096> made some
improvements, but I suspect not enough to solve your problem. Are you on
master or on 0.10?

Additionally, regionprops works through a "cached-property" pattern, which
means that each value is computed once, and then stored for later
retrieval. So your second region[0] call is probably hitting the cached
value, hence the massive speedup!

As to the specific problem of why your calculation is so much faster, my
guess right now is that it's because of Python function call overhead:
while you are computing everything directly, have a look at the regionprops
code
<https://github.com/scikit-image/scikit-image/blob/master/skimage/measure/_regionprops.py>:
first, you have to go through the cached-property pattern (1 call), check
whether the cache is active (2 calls), check whether it's been computed
before (3 calls), decide to compute it (4 calls), compute the bbox (another
travel through cached-property), then compute the "local" centroid
(relative to current bbox), within that compute the moments (another
cached-property), and *finally* compute the actual centroid.

We're not doing any computations differently, but that is a *heck* of a lot
of overhead for such a simple computation. I'd never followed this full
path before, so thanks for pointing it out! A PR to improve this situation
would be most welcome! (Bonus points for improving 3D support in the
process.)

Probably not quite the quick fix you were hoping for, but I hope this helps
nonetheless!

Juan.

On Sat, Nov 15, 2014 at 2:27 AM, jeff witz <witzjean at gmail.com> wrote:

> Hello.
>
> I'm developing a video extensometer based on the identification of center
> of mass of circular white mark on  a black rubber specimen.
>
> In order to deal with data in real time I have to be fast (over 100 fps).
> So I first identify the Zones Of Interests using this example :
> http://scikit-image.org/docs/dev/auto_examples/plot_label.html
>
> Then I compute the center of mass on each ZOI.
>
> As I have a fast camera the ZOI between two successive images doesn't
> change much. So if I extend the bounding box of my current ZOI I could be
> pretty confident in the fact that given circular mark in the next picture
> will be in the extended ZOI and the recompute an updated extened ZOI for
> the next image.
>
> So this is the big picture.
>
> You will find bellow the function I use in order to get it  :
> def barycenter(image_,minx_,miny_,maxx_,maxy_,thresh_,border_):
>   bw_=image_[minx_:maxx_+1,miny_:maxy_+1]>thresh_
>   [Y,X]=np.meshgrid(range(miny_,maxy_+1),range(minx_,maxx_+1))
>   region=regionprops(bw_)
>   minx,miny,maxx,maxy=region[0].bbox
>   Px_=(X*bw_).sum().astype(float)/bw_.sum()
>   Py_=(Y*bw_).sum().astype(float)/bw_.sum()
>   minx_=X[minx,miny]-border_
>   miny_=Y[minx,miny]-border_
>   maxx_=X[maxx,maxy]+border_
>   maxy_=Y[maxx,maxy]+border_
>   return Px_,Py_,minx_,miny_,maxx_,maxy_
>
> As you can see I don't use region[0].centroid. I compute the moment myself
>
> if I time my function on a 141x108 ZOI I get 504 µs
>
> If I time this function :
>
> def barycenter2(image_,minx_,miny_,maxx_,maxy_,thresh_,border_):
>   bw_=image_[minx_:maxx_+1,miny_:maxy_+1]>thresh_
>   [Y,X]=np.meshgrid(range(miny_,maxy_+1),range(minx_,maxx_+1))
>   region=regionprops(bw_)
>   Px_,Py_=region[0].centroid
>   Px_+=minx_
>   Py_+=miny_
>   minx,miny,maxx,maxy=region[0].bbox
>   minx_=X[minx,miny]-border_
>   miny_=Y[minx,miny]-border_
>   maxx_=X[maxx,maxy]+border_
>   maxy_=Y[maxx,maxy]+border_
>   return Px_,Py_,minx_,miny_,maxx_,maxy_
>
>
> I get 10ms per loop !
>
> What is really strange is if I time :
>
> %timeit region[0].centroid
>  I get 58.6 ns per loop !
>
> So I don't really understand why this time explose when I use it in a
> function ?
>
> If someone have some insight it will be very helpfull. Even If I can use
> my first function, it's a pity to have to use less optimized functions.
>
> Best regards.
>
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "scikit-image" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scikit-image+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scikit-image/attachments/20141115/1d331e1e/attachment.html>


More information about the scikit-image mailing list