0

I am following this tutorial of Blob Detection for Text purpose and facing some issues, please check if anyone could help.

How to extract each detected blob in form of image. How i can draw a rectangle instead of circle.

from math import sqrt
from skimage import data
from skimage.feature import blob_dog, blob_log, blob_doh
from skimage.color import rgb2gray
import skimage.io as io
import matplotlib.pyplot as plt
import matplotlib.patches as patches
#from imread import imread_from_blob

image = io.imread('5.png')

#image = (data.hubble_deep_field()[0:500, 0:500])
image_gray = rgb2gray(image)

#blobs_log = blob_log(image_gray, max_sigma=30, num_sigma=10, threshold=.1)

# Compute radii in the 3rd column.
#blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)

blobs_dog = blob_dog(image_gray, max_sigma=30, threshold=.1)
#blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)

#blobs_doh = blob_doh(image_gray, max_sigma=30, threshold=.01)

blobs_list = [ blobs_dog]

colors = ['yellow']
titles = [ 'Difference of Gaussian']
sequence = zip(blobs_list, colors, titles)

fig, axes = plt.subplots(1, 3, figsize=(9, 3), sharex=True, sharey=True,
                         subplot_kw={'adjustable': 'box-forced'})
ax = axes.ravel()

for idx, (blobs, color, title) in enumerate(sequence):
    ax[idx].set_title(title)
    ax[idx].imshow(image, interpolation='nearest')
    for blob in blobs:
        y, x, r = blob
        c = patches.Rectangle((int(x - r),int(y - r)), int(2*r), int(2*r),linewidth=2,edgecolor=color,facecolor='none')

        ax[idx].add_patch(c)
    ax[idx].set_axis_off()
    croppedImage = image[int(x-r):int(x+r),int(y-r):int(y+r)]
    if croppedImage.shape[0] > 0 and croppedImage.shape[1] > 0:
        io.imsave('C:/Users/A/Projects/Image/Test/test.png', croppedImage)
plt.tight_layout()
plt.show()

http://scikit-image.org/docs/dev/auto_examples/features_detection/plot_blob.html

Munazza Ali
  • 97
  • 2
  • 9

2 Answers2

1

First, to draw a rectangle you need to put the following import statement on top:

import matplotlib.patches as patches
from skimage import io

next change the line that draws the circles:

c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)

to a line drawing rectangles:

c = patches.Rectangle((int(x - r),int(y - r)), int(2*r), int(2*r),linewidth=2,edgecolor=color,facecolor='none')

This will create a rectangle (actually a square) with top left vertex at (x - r,y - r) and of width and height of 2*r. here r is the standard deviation of the blur used while detecting the blob.

Now to extract the image within the blob:

croppedImage = image[int(x-r):int(x+r),int(y-r):int(y+r)]
if croppedImage.shape[0] > 0 and croppedImage.shape[1] > 0:
    io.imsave('letter_image.png', croppedImage)

Change first argument as any path (including desired image name).

  • Note I have not tested the above code so the crop could have reverse coordinates, also check the coordinates of the rectangle.

Full working code looks like below:

from math import sqrt
from skimage import data
from skimage.feature import blob_dog, blob_log, blob_doh
from skimage.color import rgb2gray
import skimage.io as io
import matplotlib.pyplot as plt
import matplotlib.patches as patches
#from imread import imread_from_blob

image = io.imread('5.png')

# image = (data.hubble_deep_field()[0:500, 0:500])
image_gray = rgb2gray(image)

# blobs_log = blob_log(image_gray, max_sigma=30, num_sigma=10, threshold=.1)

# Compute radii in the 3rd column.
#blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)

blobs_dog = blob_dog(image_gray, max_sigma=30, threshold=.1)
#blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)

#blobs_doh = blob_doh(image_gray, max_sigma=30, threshold=.01)

blobs_list = [ blobs_dog]

colors = ['yellow']
titles = [ 'Difference of Gaussian']
sequence = zip(blobs_list, colors, titles)

fig, axes = plt.subplots(1, 3, figsize=(9, 3), sharex=True, sharey=True,
                         subplot_kw={'adjustable': 'box-forced'})
ax = axes.ravel()

for idx, (blobs, color, title) in enumerate(sequence):
    ax[idx].set_title(title)
    ax[idx].imshow(image, interpolation='nearest')
    for i,blob in enumerate(blobs):
        y, x, r = blob
        c = patches.Rectangle((int(x - r),int(y - r)), int(2*r), int(2*r),linewidth=2,edgecolor=color,facecolor='none')
        croppedImage = image[int(x-r):int(x+r),int(y-r):int(y+r)]
        if croppedImage.shape[0] > 0 and croppedImage.shape[1] > 0:
            io.imsave('C:/Users/A/Projects/Image/Test/test'+str(i)+'.png', croppedImage)
Srinivas V
  • 93
  • 7
  • y, x, r = blob c = patches.Rectangle((x - r,y - r), 2*r, 2*r,linewidth=2,edgecolor=color,facecolor='none') ax[idx].add_patch(c) ax[idx].set_axis_off() croppedImage = image[x-r:x+r,y-r:y+r] #return crop.save("C:/Users/A/Projects/Image/test/", png) plt.tight_layout() plt.show() Display error(slice indices must be integers or None or have an __index__ method) – Munazza Ali Nov 01 '17 at 10:13
  • ok, I have converted everything to integers, please try to run it now. – Srinivas V Nov 01 '17 at 10:23
  • c = patches.Rectangle((int(x - r),int(y - r)), int(2*r), int(2*r),linewidth=2,edgecolor=color,facecolor='none') ax[idx].add_patch(c) ax[idx].set_axis_off() plt.tight_layout() plt.show() croppedImage = image[int(x-r):int(x+r),int(y-r):int(y+r)] path="C:/Users/A/Projects/Imag/test/test.png" return crop.save(path, "png") Please check crop and save function i want to save each crop separately as image in separate folder – Munazza Ali Nov 01 '17 at 10:33
  • Ok, so basically you are saying the code has no errors, but you want to additionally save the image as a png in a separate folder, right? – Srinivas V Nov 01 '17 at 10:43
  • Yes no errors now the above code solved indices issue but now i want to save each detected blob as an image in folder. – Munazza Ali Nov 01 '17 at 10:46
  • Edited to add a save code. in imsave 1st argument sould be the path including image file name. – Srinivas V Nov 01 '17 at 10:49
  • y, x, r = blob c = patches.Rectangle((int(x - r),int(y - r)), int(2*r), int(2*r),linewidth=2,edgecolor=color,facecolor='none') croppedImage = image[int(x-r):int(x+r),int(y-r):int(y+r)] io.imsave('C:/Users/A/Projects/Image/test/test.png', croppedImage) ax[idx].add_patch(c) ax[idx].set_axis_off() plt.tight_layout() plt.show() Error (cannot do a non-empty take from an empty axes.) – Munazza Ali Nov 01 '17 at 10:55
  • I think that error is because the cropped images have one axis 0, I have added conditions to check this before saving as 0 sized blobs are of no use any way. Now the code should work provided you indent according to the rest of your code. – Srinivas V Nov 01 '17 at 11:35
  • imsave does save images, but when it is run in a loop I also find that it is not saving all images, let me see what is wrong and try to edit the code appropriately. – Srinivas V Nov 01 '17 at 15:52
  • No, the code works perfectly for me I had just made an error before. Can you edit the question to post your code that does not work? – Srinivas V Nov 01 '17 at 16:04
  • croppedImage,imsave code should be within the for loop (of the blobs) otherwise you will get only one saved image in the path, also for each iteration that name of the saved image must be different (eg. add index to the end of the name). I will post the full working code in 5-6 hrs. But I suggest you try out the changes I suggest till then – Srinivas V Nov 02 '17 at 08:32
  • It worked but i am using blob for cursive script and this function is retrieving only patches of words not an entire word is there any way that it segment word patch. – Munazza Ali Nov 02 '17 at 18:59
  • I am not sure about that but I remember seeing a section on it in Andrew ng's machine learning course on coursera. You could check that out, or ask a new question on stack overflow, I am sure someone will help you. Also check out pytessaract if you want ready made ocr in your code. – Srinivas V Nov 03 '17 at 04:56
  • I need small help r u available i need to crop out connected components in separate images just like above, i have code but i dont know how to crop i used the above method but not working.https://stackoverflow.com/questions/47137259/connected-component-crop-labels – Munazza Ali Nov 06 '17 at 15:05
  • The code you posted for the question is not complete, Please post the complete code that you used to crop the image. – Srinivas V Nov 06 '17 at 16:43
  • Kindly check the post i edit it :https://stackoverflow.com/questions/47137259/connected-component-crop-labels – Munazza Ali Nov 07 '17 at 12:16
  • I am just too lazy to go to the git repo to find the code, please give me the library you used to represent the images, then I can tell you how to crop and save the images. – Srinivas V Nov 07 '17 at 15:30
  • code is given the output is in form of single image where connected components are represented by different colors i need each component as different image. https://stackoverflow.com/questions/47137259/connected-component-crop-labels – Munazza Ali Nov 07 '17 at 16:04
0

Instead of

c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)

You will need to do a little more complicated routine using patches, here is a complete example of drawing a rectangle on an image. The specific line in here you are interested in is:

rect = patches.Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

Complete Example, taken from here:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np

im = np.array(Image.open('stinkbug.png'), dtype=np.uint8)

# Create figure and axes
fig,ax = plt.subplots(1)

# Display the image
ax.imshow(im)

# Create a Rectangle patch
rect = patches.Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

plt.show()
GPPK
  • 6,546
  • 4
  • 32
  • 57
  • y, x, r = blob c = patches.Rectangle((x - r,y - r), 2*r, 2*r,linewidth=2,edgecolor=color,facecolor='none') ax[idx].add_patch(c) ax[idx].set_axis_off() croppedImage = image[x-r:x+r,y-r:y+r] path="C:/Users/A/Projects/Image/test/test.png" plt.tight_layout() plt.show() return crop.save(path, "png") Display error(slice indices must be integers or None or have an index method) – Munazza Ali Nov 01 '17 at 10:20