我在深色背景下有大量椭圆形物体的图像。物体朝向许多不同的方向。我需要提取它们,使它们都朝向相同的方向(即水平方向),以便它们可以被紧密裁剪。
我已成功使用findBlobs()和crop来提取单个对象,但裁剪后的图像会保留其在原始图像中的方向。我还成功地旋转了各个对象,使其处于水平状态,但这通常会切断对象的末端。
因为我知道主轴与原始图像的x轴的坐标和角度,所以我试图逐步浏览每个对象的角度然后使用findBlobs()来仅裁剪那些具有angle = 0。
我可能会让它变得更加艰难。所以我需要一些建议。
这是代码: 来自SimpleCV import * 来自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
答案 0 :(得分: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")
这提供了一组适合分类的图像。我希望这有助于某人。