AngleSum += np.arctan2(x2 - x1, y2 - y1) NumberOfLines += 1 Lines.append([x2, y1, x2, y2]) # get the mean angle AngleSum /= NumberOfLines # convert to degrees AngleSum = (AngleSum / (np.pi * 2)) * 360 RotationArray.append([ImageName, AngleSum]) for Object in RotationArray: print "rotate", Object[0], "by", Object[1], "degrees" ToRotate = Image.open("Processed/" + Object[0]) # draw some lines on it # Drawing = ImageDraw.Draw(ToRotate) # for points in Lines: # Drawing.line((points[0], points[1], points[2], points[3]), fill=128) # rotate it ToRotate = ToRotate.convert('RGBA').rotate(-Object[1] + 90, expand=1) Final = Image.new('RGBA', ToRotate.size, (255, 255, 255, 255)) Final = Image.composite(ToRotate, Final, ToRotate) # crop the image so that there's no white space showing at the edges Final = Array.CropImageAroundBlack(Final) Final.convert('L').save('Rotated/' + Object[0])
def CropImage(): global Positions, OriginalImagePixels, OriginalImage, Multiplier, root, UnprocessedImagePixels # multiply all of the positions by the scale that we used to resize the image for i in range(0, len(Positions)): for p in [0, 1]: Positions[i][p] = math.floor(Positions[i][p] / Multiplier) # create a new image of the proper size PartiallyCroppedImage = Image.new('L', OriginalImage.size, 255) PartiallyCroppedImagePixels = PartiallyCroppedImage.load() CroppedImage = Image.new('L', OriginalImage.size, 255) CroppedImagePixels = CroppedImage.load() def YBounding(): SlopeOne = (Positions[0][1] - Positions[1][1]) / (Positions[0][0] - Positions[1][0]) YIntOne = Positions[0][1] - Positions[0][0] * SlopeOne SlopeTwo = (Positions[2][1] - Positions[3][1]) / (Positions[2][0] - Positions[3][0]) YIntTwo = Positions[3][1] - Positions[3][0] * SlopeTwo XLower = sorted(Positions, key = itemgetter(0))[0][0] XUpper = sorted(Positions, key = itemgetter(0), reverse = True)[0][0] for x in range(int(XLower), int(XUpper)): YLower = SlopeOne * x + YIntOne YUpper = SlopeTwo * x + YIntTwo for y in range(int(YLower), int(YUpper)): PartiallyCroppedImagePixels[x, y] = UnprocessedImagePixels[x, y] def XBounding(): # initialize all of the varaibles SlopeOne, SlopeTwo, YIntOne, YIntTwo, XUpper, XLower = 0, 0, 0, 0, 0, 0 OneVertical, TwoVertical = False, False # if the slope is undefined, bound differently try: SlopeOne = (Positions[1][1] - Positions[2][1]) / (Positions[1][0] - Positions[2][0]) YIntOne = Positions[1][1] - Positions[1][0] * SlopeOne except ZeroDivisionError: OneVertical = True try: SlopeTwo = (Positions[0][1] - Positions[3][1]) / (Positions[0][0] - Positions[3][0]) YIntTwo = Positions[3][1] - Positions[3][0] * SlopeTwo except ZeroDivisionError: TwoVertical = True YLower = sorted(Positions, key = itemgetter(1))[0][1] YUpper = sorted(Positions, key = itemgetter(1), reverse = True)[0][1] for y in range(int(YLower), int(YUpper)): # if the special vertical bound is enabled if OneVertical: XUpper = Positions[1][0] else: XUpper = (y - YIntOne) / SlopeOne # if the special vertical bound is enabled if TwoVertical: XLower = Positions[0][0] else: XLower = (y - YIntTwo) / SlopeTwo for x in range(int(XLower), int(XUpper)): CroppedImagePixels[x, y] = PartiallyCroppedImagePixels[x, y] print Positions # these need to happen in this order YBounding() XBounding() # crop the image so that there isn't extra white space CroppedImage = Array.CropImageAroundBlack(CroppedImage) CroppedImage.save("Processed/" + FullFilename) print "Image successfully cropped and saved." root.destroy()