SimpleCV blob жесткая обрезка

У меня есть изображение большого количества эллиптических объектов на темном фоне. Объекты ориентированы во многих разных направлениях. Мне нужно извлечь их так, чтобы они все были ориентированы в одном направлении (то есть горизонтально), чтобы их можно было сильно обрезать.

Я успешно использовал findBlobs() и crop для извлечения отдельных объектов, но обрезанные изображения сохраняют свою ориентацию в исходном изображении. Я также успешно повернул отдельные объекты так, что они расположены горизонтально, но это обычно отрубает концы объектов.

Поскольку я знаю координаты и угол, который большая ось составляет с осью x исходного изображения, я попытался пройтись по углу каждого объекта, а затем использовать findBlobs(), чтобы обрезать только те объекты, которые имеют угол =0.

Я мог бы сделать это более трудным, чем это должно быть. Поэтому мне нужен совет.

Вот код: из SimpleCV import * из оператора 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://stackru.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

1 ответ

Я успешно выяснил, как обрезать несколько случайно ориентированных эллипсов, чтобы они были горизонтально ориентированы и равномерно обрезаны. Это, вероятно, не самый элегантный подход, но он работает. Я впервые обнаружил максимальную длину и угол капли

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 и сохранил изображения.

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")

Это обеспечило набор изображений, которые были пригодны для классификации. Я надеюсь, что это помогает кому-то.

Другие вопросы по тегам