-1

I have to write a function in python that gets a PIL image and stretch it to be in a rectangle shape

I've tried running this code:

def stretch_image(im3D):
    width, height = im3D.size
    data = np.array(im3D, dtype=np.uint8)
    matrix = data.reshape(height, width)

    if not np.linalg.det(matrix):
        raise ValueError("The matrix is not invertible")
    invertible_matrix = np.linalg.inv(matrix)
    stretch3Dimg = matrix * invertible_matrix
    return stretch3Dimg

and I expect to get the stratch image

5
  • 1
    Why not using Image.resize? Commented Aug 2, 2023 at 9:58
  • None of this make any sense. An image is not a matrix (it is a 2d array, and so are matrix, that's all). It means nothing to invert an image (or it would a matrix that allows to compute what linear combination of columns from the image is equal to a given columns of pixels). Plus, only squared matrix can be inverted. Also, it is quite strange to reshape the data as you do. Either the shape is already this one (if this is a grayscale image). Or it is not (as your name "3d" suggest) because it is a color image. And then reshape would fail.
    – chrslg
    Commented Aug 2, 2023 at 10:27
  • ok, you are right that image is not a matrix but I want to use their common attribute in order to get the stretched image by multipling the matrix in her invertible matrix.
    – Ose Tov
    Commented Aug 2, 2023 at 11:40
  • and I can't use Image.resize() because it doesn't keep the image proportion
    – Ose Tov
    Commented Aug 2, 2023 at 11:41
  • if you have a better way to get the requested result, I will be very happy to see it.
    – Ose Tov
    Commented Aug 2, 2023 at 11:49

1 Answer 1

0

Ok, so the main problem is that you're trying to stretch the image using matrix multiplication between the original matrix and its inverse, which is not the correct approach for stretching an image. Simpler transformations like scaling rotating can be done with simple matrix multiplication, but when you're trying to stretch an image to fit a rectangle, it's not a simple matrix multiplication operation that's needed. This discussion on StackExchange might help you out with your approach.

An alternative to this would be using a simple interpolation-based approach. You can do this by creating a new blank image with the desired dimensions and then filling in the pixels using the original image.

Here is a modified version of your code to help you do this:

import numpy as np
from PIL import Image


def stretch_image(im):
    target_width = 400  # Set the desired width of the rectangle
    target_height = 300  # Set the desired height of the rectangle

    # Calculate the scaling factors
    width_ratio = target_width / im.width
    height_ratio = target_height / im.height

    # Create a new blank image with the target dimensions
    stretched_im = Image.new("RGB", (target_width, target_height))

    # Loop through the pixels of the new image and fill them with interpolated values
    for y in range(target_height):
        for x in range(target_width):
            source_x = int(x / width_ratio)
            source_y = int(y / height_ratio)
            stretched_im.putpixel((x, y), im.getpixel((source_x, source_y)))

    return stretched_im


# Load your original image using PIL
original_image = Image.open("original_image.png")

# Stretch the image
stretched_image = stretch_image(original_image)

# Display or save the stretched image as needed
stretched_image.show()
stretched_image.save("stretched_image.jpg")
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.