下面的代码是检测图像中的对象。代码可以检测对象,计算检测到的对象的数量,绘制矩形以标记对象。有没有办法提取和保存每个检测到的对象?例如;如果在图像中检测到20个对象,我想单独提取并保存这20个对象。如有任何帮助,我将不胜感激。
from PIL import Image
class TheOutliner(object):
''' takes a dict of xy points and
draws a rectangle around them '''
def __init__(self):
self.outlineColor = 255, 0, 0
self.pic = None
self.picn = None
self.minX = 0
self.minY = 0
self.maxX = 0
self.maxY = 0
def doEverything(self, imgPath, dictPoints, theoutfile):
self.loadImage(imgPath)
self.loadBrightPoints(dictPoints)
self.drawBox()
self.saveImg(theoutfile)
def loadImage(self, imgPath):
self.pic = Image.open(imgPath)
self.picn = self.pic.load()
def loadBrightPoints(self, dictPoints):
'''iterate through all points and
gather max/min x/y '''
# an x from the pool (the max/min
# must be from dictPoints)
self.minX = dictPoints.keys()[0][0]
self.maxX = self.minX
self.minY = dictPoints.keys()[0][1]
self.maxY = self.minY
for point in dictPoints.keys():
if point[0] < self.minX:
self.minX = point[0]
elif point[0] > self.maxX:
self.maxX = point[0]
if point[1]< self.minY:
self.minY = point[1]
elif point[1] > self.maxY:
self.maxY = point[1]
def drawBox(self):
# drop box around bright points
for x in xrange(self.minX, self.maxX):
# top bar
self.picn[x, self.minY] = self.outlineColor
# bottom bar
self.picn[x, self.maxY] = self.outlineColor
for y in xrange(self.minY, self.maxY):
# left bar
self.picn[self.minX, y] = self.outlineColor
# right bar
self.picn[self.maxX, y] = self.outlineColor
def saveImg(self, theoutfile):
self.pic.save(theoutfile, "JPEG")
class ObjectDetector(object):
''' returns a list of dicts representing
all the objects in the image '''
def __init__(self):
self.detail = 4
self.objects = []
self.size = 1000
self.no = 255
self.close = 100
self.pic = None
self.picn = None
self.brightDict = {}
def loadImage(self, imgPath):
self.pic = Image.open(imgPath)
self.picn = self.pic.load()
self.picSize = self.pic.size
self.detail = (self.picSize[0] + self.picSize[1])/2000
self.size = (self.picSize[0] + self.picSize[1])/8
# each must be at least 1 -- and the larger
# the self.detail is the faster the analyzation will be
self.detail += 1
self.size += 1
def getSurroundingPoints(self, xy):
''' returns list of adjoining point '''
x = xy[0]
y = xy[1]
plist = (
(x-self.detail, y-self.detail), (x, y-self.detail),
(x+self.detail, y-self.detail),
(x-self.detail, y),(x+self.detail, y),
(x-self.detail, y+self.detail),(x, y+self.detail),
(x+self.detail,y+self.detail)
)
return (plist)
def getRGBFor(self, x, y):
try:
return self.picn[x,y]
except IndexError as e:
return 255,255,255
def readyToBeEvaluated(self, xy):
try:
r,g,b = self.picn[xy[0],xy[1]]
if r==255 and g==255 and b==255:
return False
except:
return False
return True
def markEvaluated(self, xy):
try:
self.picn[xy[0],xy[1]] = self.no, self.no, self.no
except:
pass
def collectAllObjectPoints(self):
for x in xrange(self.pic.size[0]):
if x % self.detail == 0:
for y in xrange(self.pic.size[1]):
if y % self.detail == 0:
r,g,b = self.picn[x,y]
if r == self.no and \
g == self.no and \
b == self.no:
# then no more
pass
else:
ol = {}
ol[x,y] = "go"
pp = []
pp.append((x,y))
stillLooking = True
while stillLooking:
if len(pp) > 0:
xe, ye = pp.pop()
# look for adjoining points
for p in
self.getSurroundingPoints((xe,ye)
if self.readyToBeEvaluated((p[0],
p[1])):
r2,g2,b2 = self.getRGBFor(p[0],
p[1])
if abs(r-r2) < self.close and \
abs(g-g2) < self.close and \
abs(b-b2) < self.close:
# then its close enough
ol[p[0],p[1]] = "go"
pp.append((p[0],p[1]))
self.markEvaluated((p[0],p[1]))
self.markEvaluated((xe,ye))
else:
# done expanding that point
stillLooking = False
if len(ol) > self.size:
self.objects.append(ol)
if __name__ == "__main__":
print "Start Process";
# assumes that the .jpg files are in
# working directory
theFile = "new2"
theOutFile = "new2.output"
import os
os.listdir('.')
for f in os.listdir('.'):
if f.find(".jpg") > 0:
theFile = f
print "working on " + theFile + "..."
theOutFile = theFile + ".out.jpg"
bbb = ObjectDetector()
bbb.loadImage(theFile)
print " analyzing.."
print " file dimensions: " + str(bbb.picSize)
print " this files object weight: " + str(bbb.size)
print " this files analyzation detail: " +
str(bbb.detail)
bbb.collectAllObjectPoints()
print " objects detected: " +str(len(bbb.objects))
drawer = TheOutliner()
print " loading and drawing rectangles.."
drawer.loadImage(theFile)
for o in bbb.objects:
drawer.loadBrightPoints(o)
drawer.drawBox()
print "saving image..."
drawer.saveImg(theOutFile)
print "Process complete"
答案 0 :(得分:2)
您可以使用crop()
方法:
在drawBox()
之后添加新方法:
def saveBox(self,filename):
# Create Box
box = (self.minX, self.minY, self.maxX, self.maxY)
# Crop Image
self.pic.crop(box).save(filename)
更改主要代码:
drawer.loadImage(theFile)
idBox=0
for o in bbb.objects:
drawer.loadBrightPoints(o)
drawer.drawBox()
idBox=idBox+1
drawer.saveBox("box_"+str(idBox)+"_"+theOutFile)
print "saving image..."
drawer.saveImg(theOutFile)