opencv - Fast method to retrieve contour mask from a binary mask in Python -


i want make realtime application, involves finding edges of binary mask. need fast, without gpu if possible, runs below 0.0005 secs per image, size (1000,1000). using following example of binary image ,with size (1000,1000).

(code replicate:)

import numpy np im=np.zeros((1000,1000),dtype=np.uint8) im[400:600,400:600]=255 

image

the first logical way things fast use opencv library:

import cv2 timeit.timeit(lambda:cv2.laplacian(im,cv2.cv_8u),number=100)/100 0.0011617112159729003 

which expected resulted in: laplacian

i found way time consuming. after tried findcontours:

 def usingcontours(im):     points=np.transpose(cv2.findcontours(im,cv2.retr_tree,cv2.chain_approx_none)[1][0])     tmp=np.zeros_like(im)     tmp[tuple(points)]=255     return tmp  timeit.timeit(lambda:usingcontours(im),number=100)/100 0.0009052801132202148 

which gave same result above. better, still not like. moved on usage of numpy, approximate laplacian using gradient, last resort, although knew worse:

def usinggradient(im):     tmp=np.gradient(im)     return ((tmp[0]+tmp[1])>0).astype(np.uint8) timeit.timeit(lambda:usinggradient(im),number=100)/100 0.018681130409240722 

so, has further idea on how can accelerate algorithm? emphasize want algorithm used binary images, guess there must better implementation.

i picked fastest 1 cv2.findcontours speed up. in it, replace expensive transpose , converting tuple parts simple slicing, -

idx = cv2.findcontours(im,cv2.retr_tree,cv2.chain_approx_none)[1][0] out = np.zeros_like(im) out[idx[:,0,0],idx[:,0,1]] = 255 

runtime test -

in [114]: # inputs      ...: im=np.zeros((1000,1000),dtype=np.uint8)      ...: im[400:600,400:600]=255      ...: idx = cv2.findcontours(im,cv2.retr_tree,cv2.chain_approx_none)[1][0]      ...:   in [115]: def original_app(im, idx):      ...:     points=np.transpose(idx)      ...:     tmp=np.zeros_like(im)      ...:     tmp[tuple(points)]=255      ...:     return tmp      ...:       ...: def proposed_app(im, idx):      ...:     out = np.zeros_like(im)      ...:     out[idx[:,0,0],idx[:,0,1]] = 255      ...:     return out      ...:   in [120]: %timeit original_app(im, idx) 10000 loops, best of 3: 108 µs per loop  in [121]: %timeit proposed_app(im, idx) 10000 loops, best of 3: 101 µs per loop  in [122]: %timeit cv2.findcontours(im,cv2.retr_tree,cv2.chain_approx_none) 1000 loops, best of 3: 1.55 ms per loop 

so, there's marginal improvement there proposed method, seems negligible compared contour-finding itself.

i looked scikit-image's version , ran quick test , seems it's slower opencv version.


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -