问题
I need to separate or translate or replace pixels in an image with python so as to all the shapes to share the same distance between each other and the limits of the canvas.
background is white, shapes are black.
IMPORTANT: Images are dynamic, all images have bars at different positions, that means i need to detect where a bar starts and where a bar ends to draw the final image!
This is an example INPUT image
This is an example OUTPUT image
I did this by hand, i don't know if all bars are separated by the same distance, it's just an example.
The resulting canvas size can change too but ideally i would like all canvas to have the same width and height after the bars have been respositioned.
All pixels in the images are BLACK or WHITE, that should make it much easier.
What i've tried so far kind of detects the shapes but some shapes are not detected correctly when they are too close of each other:
saut = 1
start_ab = 0
end_ab = 0
start_or = im2.size[1] - 1
end_or = 0
size = 0
shapes = []
for y in range(0, im2.size[0], saut): # slice across
for x in range(0, im2.size[1], 1): # slice down
pix = im2.getpixel((y, x))
if pix != 255:
start_or = min(start_or, x)
end_or = max(end_or, x)
inshape = True
if foundshape == False and inshape == True:
foundshape = True
start_ab = y
if foundshape == True and inshape == False:
foundshape = False
end_ab = y
size = max(size, end_ab)
shapes.append((start_ab, end_ab, start_or, end_or))
start_or = im2.size[1] - 1
end_or = 0
inshape = False
print shapes
# example shapes output NOT FROM THE EXAMPLE IMAGES PROVIDED but from other shapes [(54, 171, 72, 233), (216, 324, 108, 251), (342, 486, 0, 215), (513, 765, 18, 260), (792, 918, 90, 242)]
And still have to draw the new image, i don't know how to do that, also some images have shapes with "holes" in them, so that makes the "redraw" a little bit more complicated.
回答1:
And still have to draw the new image, i don't know how to do that, also some images have shapes with "holes" in them, so that makes the "redraw" a little bit more complicated.
Once you've established the bounds of a rectangle, you could use the Image.crop() function to extract a rectangle from the image (including those holes) and Image.paste() to paste them in the right position. The tutorial contains an example:
http://pillow.readthedocs.org/en/latest/handbook/tutorial.html#cutting-pasting-and-merging-images
回答2:
Code to calculate the distance between each shape. It assumes that the shapes have all the same width:
def calcDistanceBetweenShapes(nShapes, shapeWidth, totalWidth):
totalBlank = totalWidth-nShapes*shapeWidth
return totalBlank/nShapes
Code to shift a shape's abscissa (assumes a shape is stored as (start_ab, end_ab, start_or, end_or,empty_points)
):
def setNewAbscissa(shape, new_start_ab):
start_ab, end_ab = shape[0], shape[1]
shift = new_start_ab - start_ab
new_end_ab = end_ab + shift
new_empty_points = map(lambda pt: (pt[0]+shift,pt[1]),empty_points)
return (new_start_ab, new_end_ab,start_or, end_or, new_empty_points)
Now let's call d
the distance between shapes. The first shape will not be moved, so its coordinates stay the same. The second shape will have its start_ab
that will be previous_end_ab+d
where previous_end_ab
is the end_ab
of the first shape, etc. This gives an algorithm to calculate the coordinates of all the shapes.
def get_new_shapes(shapes, totalWidth):
shift = calcDistanceBetweenShapes(len(shapes), shapes[0][1] - shape[0][0], totalWidth)
res = [shapes[0]]
previous_shape = shapes[0]
for shape in shape[1:]:
new_start_ab = previous_shape[1] + shift
new_shape = setNewAbscissa(previous_shape,new_start_ab)
res.append(new_shape)
previous_shape = new_shape
来源:https://stackoverflow.com/questions/31966970/separate-reposition-translate-shapes-in-image-with-pillow-in-python