title: Is there a faster way for finding the circumference of a shape?
body: <p>I have an image showing some objects, where one object is always inside the other.
  The background is always black.</p>
  
  <p><a href="https://i.stack.imgur.com/706g8.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/706g8.png" alt="enter image description here"></a></p>
  
  <p>I want to know the circumference of both objects and got to a solution.
  I use a filterkernel to get the 4-neighborhood of each pixel. Then I count the number of zero pixels around the pixel. This gives me the length in pixel units of the shape. I count only in the case, if the center pixel is the desired color.</p>
  
  <pre><code>from scipy import misc, ndimage
  import numpy as np
  import time
  
  def get_circumference(arr, only=50, repl=50):
      def c_length(values):
          # 3rd value is the pixel
          if values[2] == only:
              return sum([x == 0 or (repl == 0 and x != only) for x in values[[0,1,3,4]]])
          return 0
  
      fp = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])
      res = ndimage.generic_filter(arr, c_length, footprint=fp)
  
      return np.sum(res, axis=None)
  
  x = ndimage.imread("image.png", mode='L')
  
  tic = time.time()
  inner = get_circumference(x, only=255, repl=0)
  outer = get_circumference(x, only=128, repl=128)
  print("Inner object: {}, outer object: {}, took: {}".format(inner, outer, time.time() - tic))
  </code></pre>
  
  <p>gives me:</p>
  
  <pre><code>Inner object: 510, outer object: 1054, took: 0.8387038707733154
  </code></pre>
  
  <p>It works quite fine. But it is very slow.
  It takes about 500 to 1000 ms for a single image.
  As I need to do this for several thousand images, it will take too much time.</p>
  
  <p>Is there any way to speed this up? I know, that the images will always contain three colors and that the inner section will always fully enclosed by the outer one. Also there will never be the case of an shape crossing image boundaries.</p>
  
  <p>Of course there are different methods to actually calculate the circumference.
  Given just a single pixel, there are two possible solutions: 1 or 4.
  The first method just counts the number of pixels, i.e. a single pixel counts as a single unit of circumfernece. In the latter case, the actual edges of the pixel are counted.
  In my solution I used the latter method to count the circumfernece.
  If you count just by edge detection and histogram, you will get the first solution.</p>
  
  <p>Here is another example, where this difference can actually be caculated by hand as well:
  <a href="https://i.stack.imgur.com/I9M2h.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/I9M2h.png" alt="extreme case example"></a></p>
  
  <p>It consists of 8 grey pixels and one white pixel.
  The outer circumfernece is therefore 3+3+3+3 = 12 and the inner is 4.
  Pixel counting by histogram would give instead 8 for the outer and 1 for the inner.</p>