2

enter image description here

I'm detecting blobs on image using skimage.feature.blob_doh and 'm getting my blob areas in format:

A = array([[121, 271, 30], [123, 44, 23], [123, 205, 20], [124, 336, 20], [126, 101, 20], [126, 153, 20], [156, 302, 30], [185, 348, 30], [192, 212, 23], [193, 275, 23], [195, 100, 23], [197, 44, 20], [197, 153, 20], [260, 173, 30], [262, 243, 23], [265, 113, 23], [270, 363, 30]])

A : (n, 3) ndarray A 2d array with each row representing 3 values, (y,x,sigma) where (y,x) are coordinates of the blob and sigma is the standard deviation of the Gaussian kernel (it's approximatly just a radius of my area)

So the question is - how to select all these areas for further data processing (calculating average features, making some clustering and classification). Now I just draw them on plot, but can't migrate them to bitmap\array variables.

And I don't want use for this task OpenCV library, I have to do it using numpy/scipy/skimage and other libs.

 fig, ax = plt.subplots(1, 1)
    ax.set_title(title)
    ax.imshow(image, interpolation='nearest')
    for blob in blobs:
            y, x, r = blob
            c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)
            print c
            ax.add_patch(c)
    plt.show()

Thank you for any help!

UPD: got some code for cropping, but it's doing something strange... it crops well, but what is with coordinates?

def crop_and_save_blobs(image, blobs):
    image = np.asarray(image)
    for blob in blobs:
            y, x, radius = blob
            center = (x, y)
            mask = np.zeros((image.shape[0],image.shape[1]))
            for i in range(image.shape[0]):
                for j in range(image.shape[1]):
                    if (i-center[0])**2 + (j-center[0])**2 < radius**2:
                        mask[i,j] = 1

            # assemble new image (uint8: 0-255)
            newImArray = np.empty(image.shape,dtype='uint8')
            # colors (three first columns, RGB)
            newImArray[:,:,:3] = image[:,:,:3]
            # transparency (4th column)
            newImArray[:,:,3] = mask*255 
            newIm = Image.fromarray(newImArray, "RGBA")
            plt.imshow(newIm)
            plt.show() 
Rachnog
  • 353
  • 1
  • 7
  • 18
  • Can you easily upload the actual image with the circles on it, rather than a picture of it with axes and a border? – Mark Setchell Aug 13 '14 at 11:50
  • @MarkSetchell sorry, I am new to Python, I can't found example how to save image with circles, but I can upload whole code and image I'm working with – Rachnog Aug 13 '14 at 12:01
  • possible duplicate of [How to apply a disc shaped mask to a numpy array?](http://stackoverflow.com/questions/8647024/how-to-apply-a-disc-shaped-mask-to-a-numpy-array) – ali_m Aug 13 '14 at 14:07

1 Answers1

0

So, there is a way I did it.

def circleToSquare(x,y,r):
'''
    Получить 2 точки, по которым можно определить квадрат, 
    описанный вокруг круга с известным центром и радиусом
'''
temp = [x, y - r]
A = [temp[0] - r, temp[1]]
B = [A[0] + 2*r, A[1]]
C = [B[0], B[1] + 2*r]
return A[0], A[1], C[0], C[1]


def imgCrop(im, x, y, radius): 
    '''
        Обрезать круглую область по квадрату
    '''
    box = circleToSquare(x,y,radius)
    return im.crop(box)  


def separateBlobs(image, blobs):
    '''
        Выделить области, в которых потенциально может быть объект
    '''
    separate = []
    image = np.asarray(image)
    index = 0
    for blob in blobs:
            y, x, radius = blob
            center = y, x
            mask = np.zeros((image.shape[0],image.shape[1]))
            for i in range(image.shape[0]):
                for j in range(image.shape[1]):
                    if (i-center[0])**2 + (j-center[1])**2 < radius**2:
                        mask[i,j] = 1

        # assemble new image (uint8: 0-255)
        newImArray = np.empty(image.shape,dtype='uint8')
        # colors (three first columns, RGB)
        newImArray[:,:,:3] = image[:,:,:3]
        # transparency (4th column)
        newImArray[:,:,3] = mask*255 
        newIm = Image.fromarray(newImArray, "RGBA")
        newIm = imgCrop(newIm, x, y, radius)
        misc.imsave('image' + str(index) + ".png", newIm)
        separate.append(newIm)
        index += 1
return separate       

Three methods to crop these images and then run it so:

im = Image.open(path).convert("RGBA")    
separateB = separateBlobs(im, blobs)

I know, not perfect code, I have to work on it, but it does my task well.

Rachnog
  • 353
  • 1
  • 7
  • 18
  • 1
    You can vectorize the `mask` generation doing something like: `rows = np.arange(image.shape[0]); cols = np.arange(image.shape[1]); mask = ((rows-center[0])**2)[:, None] + (cols - center[1])**2 < radius**2` – Jaime Aug 13 '14 at 14:00