Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take data from a circle in python

I am looking into how the intensity of a ring changes depending on angle. Here is an example of an image:

enter image description here

What I would like to do is take a circle of values from within the center of that doughnut and plot them vs angle. What I'm currently doing is using scipy.ndimage.interpolation.rotate and taking slices radially through the ring, and extracting the maximum of the two peaks and plotting those vs angle.

    crop = np.ones((width,width)) #this is my image
    slices = np.arange(0,width,1)
    stack = np.zeros((2*width,len(slices)))
    angles = np.linspace(0,2*np.pi,len(crop2))

    for j in range(len(slices2)): # take slices
           stack[:,j] = rotate(crop,slices[j],reshape=False)[:,width]

However I don't think this is doing what I'm actually looking for. I'm mostly struggling with how to extract the data I want. I have also tried applying a mask which looks like this;

enter image description here

to the image, but then I don't know how to get the values within that mask in the correct order (ie. in order of increasing angle 0 - 2pi)

Any other ideas would be of great help!

like image 508
arbitraryknowledge Avatar asked Apr 14 '16 13:04

arbitraryknowledge


1 Answers

I made a different input image to help verifying correctness:

import numpy as np
import scipy as sp
import scipy.interpolate
import matplotlib.pyplot as plt

# Mock up an image.
W = 100
x = np.arange(W)
y = np.arange(W)
xx,yy = np.meshgrid(x,y)

image = xx//5*5 + yy//5*5
image = image / np.max(image)  # scale into [0,1]

plt.imshow(image, interpolation='nearest', cmap='gray')
plt.show()

Alternate input image

To sample values from circular paths in the image, we first build an interpolator because we want to access arbitrary locations. We also vectorize it to be faster.
Then, we generate the coordinates of N points on the circle's circumference using the parametric definition of the circle x(t) = sin(t), y(t) = cos(t).
N should be at least twice the circumference (Nyquist–Shannon sampling theorem).

interp = sp.interpolate.interp2d(x, y, image)
vinterp = np.vectorize(interp)

for r in (15, 30, 45):    # radii for circles around image's center
    xcenter = len(x)/2
    ycenter = len(y)/2
    arclen = 2*np.pi*r
    angle = np.linspace(0, 2*np.pi, arclen*2, endpoint=False)
    value = vinterp(xcenter + r*np.sin(angle),
                    ycenter + r*np.cos(angle))
    plt.plot(angle, value, label='r={}'.format(r))

plt.legend()
plt.show()

Circles sampled from center.

like image 169
Norman Avatar answered Sep 19 '22 03:09

Norman