2015-05-29 43 views
0

我在黑暗的背景下有大量椭圆形物体的图像。这些物体的方向是多方面的。我需要将它们提取出来,使它们都朝向相同的方向(即水平方向),以便它们可以紧密裁剪。SimpleCV blob紧身裁剪

我已经成功地使用findBlobs()和裁剪来提取单个对象,但裁剪后的图像在原始图像中保留其方向。我也成功地旋转了单个物体,使它们是水平的,但是这通常会剔除物体的末端。因为我知道长轴与原始图像的x轴形成的坐标和角度,所以我试图逐步遍历每个对象的角度,然后使用findBlobs()仅裁剪那些角度为0的斑点。

我可能会让它变得更加困难。所以我需要一些建议。

下面是代码: 从SimpleCV进口* 从运营商进口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 
+0

我成功地想出了如何使用以下方法裁剪大量随机定向的椭圆: – thiirane

回答

0

我成功地找到了如何裁剪一些随机取向的椭圆形,使他们都水平方向并统一裁剪。这可能不是最优雅的方法,但它的工作原理。我首先发现斑点的最大长度和角度

blobs=Ellipses.findBlobs() 
k=0 
x=[b for b in blobs] 
y=[b for b in blobs] 
r=[b for b in blobs] 
bl=[b for b in blobs] 
#bl[k]=b.length()+.2*b.length() 
#set crop to the largest blob 

bl[k]=b.length() 
if [x[k],y[k]]==[blobs[-1].x,blobs[-1].y]: 
    #print ("the largest blob has length =", bl[k]) 
    bigX=x[k] 
    bigY=y[k] 
    bigR=r[k] 
    bigL=bl[k] 


ar[k]=b.aspectRatio() 
bw[k]=bl[k]*ar[k] 

#print ("angle=",round(r[k],0),"and coordinates=",  
x[k],y[k],"length=",bl[k],"width=",bw[k]) 
k+=1bw=[b for b in blobs] 
ar=[b for b in blobs] 
#largest Blob is 
biggest=blobs[-1] 
print ("the largest blob has length =", biggest) 
for b in blobs: 
    r[k]=round(b.angle(),0) 
    [x[k],y[k]]=b.coordinates() 

,然后根据最大斑点确定一个正方形裁剪的大小。

Ak=0 
for b in blobs: 
    #print "number of blobs=",len(blobs) 
    angleset=r[Ak] 

    Ellipses1=Image(FN) 
    #rotate whole image to make target blob horizontal 
    #print "blob length=",bl[Ak],"blob width=",bw[Ak] 
    #print "blob aspect Ratio=",ar[Ak], "width=",bl[Ak]*ar[Ak] 
    #print "blobs coordinates=", x[Ak],y[Ak],"b1 angle=",angleset 
    #crops the individual blobs and saves to disk 
Ellipses1.crop(x[Ak],y[Ak],bigL,bigL,centered=True).save("cropped"+str(angleset)+".png") 
    #reads individual cropped blobs from disk 
    Ellipses1c=Image("cropped"+str(angleset)+".png") 
    [L,W]=Ellipses1c.size() 

#print ("Ellipse1c Image Length =", L, "Width=",W) 
#rotate the individual images so they are horizontal (co-linear with x axis), then saves to disk 
Ellipses1c.rotate(angleset,point=(L/2,L/2)).save("rotated_cropped"+str(angleset)+".png") 

Ak +=1 

接下来我使用blob.angle旋转blob并保存图像。

for i in range(0,len(r)): 
angleset=r[i] 
Ellipses2c=Image("rotated_cropped"+str(angleset)+".png") 
[L,W]=Ellipses2c.size() 
print ("Ellipse2c Image Length =", L, "Width=",W) 
blobs2=Ellipses2c.findBlobs() 
for b in blobs2: 
    Ellipses2c.crop(b).save("final_"+FN_prefix+str(angleset)+".png") 

这提供了一组适合分类的图像。我希望这可以帮助别人。