Skip to content
Advertisement

Python, crop an image to extract a single side of it

I have an image and the vertexs of each sides of it, meaning that, if we see each side as a segment (A,B) i have both the A and B point coordinates.

Now i would like to crop the image so that i have only one segment of the image (which is the side), for example That’s just one side of the original image

For now i tried to do it in opencv with binary masking creating a line (fromt he vertexes i have) and using it to crop the image so that i have the pixels corresponding to that side. The problem with this approach is that the resulting image is of the same size of the orginal one but everything that is cropped is now a [0,0,0,0] (rgba) pixel

Instead, what i want is the following: if for example the side i want to extract is 20px long, the resulting image should be of shape (1,20,4) 1 height, 20 width and 4 channels (rgba)

I tried to do it with slicing but I don’t know how to account to the fact that the sides can also be oblique lines.

Example image: Example image Corresponding vertexes: [[[107, 32], [95, 30]], [[95, 30], [26, 103]], [[26, 103], [28, 119]], [[28, 119], [103, 109]], [[103, 109], [122, 64]], [[122, 64], [107, 32]]] Each of these vertex is needed so i can extract, for every 2 vertex, a line from the image. In the previuos example i have 12 vertexes, so it will be 6 lines that i have to extract

Advertisement

Answer

If you don’t need use numpy obligatorily, you can use Image from PIL

from PIL import Image

img1 = Image.open(r"image_name.png")

img1 = img1.crop((cord_x, cord_y, width, height))

img1.save("name_saved.png")

UPDATE: The another code, help for rectangle shapes, here is a more generic code for any array of polygon cords

import numpy
from PIL import Image, ImageDraw

im = Image.open("image_name").convert("RGBA") #only convert if is necesary
image_array = numpy.asarray(im)

#Create mask
polygon = [(107, 32), (95, 30), (26, 103), (28, 119), (103, 109), (122, 64)] #this cords is from your example
mi = Image.new('L', (image_array.shape[1], image_array.shape[0]), 0)
ImageDraw.Draw(mi).polygon(polygon, outline=1, fill=1)
mask = numpy.array(mi)

new_image_array = numpy.empty(image_array.shape,dtype='uint8')
new_image_array[:,:,:3] = image_array[:,:,:3]
new_image_array[:,:,3] = mask*255

#Convert numpy array to image
image_output = Image.fromarray(new_image_array, "RGBA")
image_output.save("file_output_name")
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement