I have an image of a large number of elliptical objects against a dark background. The objects are oriented in many different directions. I need to extract them so that they are all oriented in the same direction (i.e., horizontally ) so that they can be tightly cropped.
I have successfully used findBlobs() and crop to extract the individual objects but the cropped images preserves their orientation in the original image. I have also successfully rotated the individual objects so that are horizontal but this usually chops off the ends of the objects.
Because I know the coordinates and the angle the major axis makes with the x axis of the original image, I have tried to step through each object's angle then use findBlobs() to crop only those blobs that have an angle =0.
I might be making this more difficult than it has to be. So I need some advice.
Here is the code: from SimpleCV import * from operator import itemgetter, attrgetter, methodcaller
def rotatedRectWithMaxArea(w, h, angle):
"""
Given a rectangle of size wxh that has been rotated by 'angle' (in
radians), computes the width and height of the largest possible
axis-aligned rectangle (maximal area) within the rotated rectangle.
http://stackoverflow.com/questions/16702966/rotate-image-and-crop-out- black-borders
"""
if w <= 0 or h <= 0:
return 0,0
width_is_longer = w >= h
side_long, side_short = (w,h) if width_is_longer else (h,w)
# since the solutions for angle, -angle and 180-angle are all the same,
# if suffices to look at the first quadrant and the absolute values of sin,cos:
sin_a, cos_a = abs(math.sin(angle)), abs(math.cos(angle))
if side_short <= 2.*sin_a*cos_a*side_long:
# half constrained case: two crop corners touch the longer side,
# the other two corners are on the mid-line parallel to the longer line
x = 0.5*side_short
wr,hr = (x/sin_a,x/cos_a) if width_is_longer else (x/cos_a,x/sin_a)
else:
# fully constrained case: crop touches all 4 sides
cos_2a = cos_a*cos_a - sin_a*sin_a
wr,hr = (w*cos_a - h*sin_a)/cos_2a, (h*cos_a - w*sin_a)/cos_2a
return wr,hr
Ellipses=Image("Elliptical.jpg")
#now find the location and angle of the blobs
blobs=Ellipses.findBlobs()
for b in blobs:
r=round(b.angle(),0)
[x,y]=b.coordinates()
#now that we know the angles and coordinates of each blob rotate the original image and
#apply findBlobs iteratively
Ak=0
for angle in range (0,len(r)):
[L,W]=Ellipses.size()
print ("Ellipse Image Length =", L, "Width=",W)
Ellipses1=Image("Elliptical.jpg")
Ellipses1r=Ellipses1.rotate(angle)
[wr,lr]=rotatedRectWithMaxArea(W,L,angle)
print ("largest dimensions w, l = ",round(wr,0),round(lr,0))
Ellipses1r.crop(L/2,W/2,lr,wr,centered=True)
Ellipses1r.save("cropped_rotated"+str(Ak)+".png")
blobs1=Ellipses1.findBlobs()
Ak +=1