You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

79 lines
2.4 KiB

from PIL import Image, ImageDraw
import numpy as np
def find_coeffs(source_coords, target_coords):
"""
Calculate coefficients for perspective transformation.
"""
matrix = []
for s, t in zip(source_coords, target_coords):
matrix.extend([
[s[0], s[1], 1, 0, 0, 0, -t[0] * s[0], -t[0] * s[1]],
[0, 0, 0, s[0], s[1], 1, -t[1] * s[0], -t[1] * s[1]]
])
A = np.matrix(matrix, dtype=np.float64)
B = np.array(target_coords).reshape(8)
try:
res = np.linalg.solve(A, B)
return tuple(np.array(res).flatten())
except np.linalg.LinAlgError:
print("Error: Could not solve transformation matrix.")
return None
def main():
# Load the input image
try:
image = Image.open("img4.png").convert("RGBA")
except FileNotFoundError:
print("Error: img1.png not found")
return
# Create an empty output image (transparent background)
output_size = (800, 600)
output_image = Image.new("RGBA", output_size, (0, 0, 0, 0))
# Define the target quadrilateral (very small area in the output image)
target_quad = [(50, 50), (100, 60), (120, 100), (45, 90)]
# Define the source coordinates (entire input image)
width, height = image.size
source_quad = [(0, 0), (width, 0), (width, height), (0, height)]
# Calculate the transformation coefficients
coeffs = find_coeffs(source_quad, target_quad)
if not coeffs:
return
# Calculate the bounding box of the target quadrilateral
min_x = min(p[0] for p in target_quad)
min_y = min(p[1] for p in target_quad)
max_x = max(p[0] for p in target_quad)
max_y = max(p[1] for p in target_quad)
# Create a polygon mask to ensure transparency outside the target area
mask = Image.new("L", output_size, 0)
draw = ImageDraw.Draw(mask)
draw.polygon(target_quad, fill=255)
# Apply the transformation to the entire input image
transformed = image.transform(
output_size,
Image.PERSPECTIVE,
coeffs,
Image.BILINEAR
)
# Apply the mask to keep only the transformed area within the target quadrilateral
transformed.putalpha(mask)
# Paste the transformed image onto the output image
output_image.paste(transformed, (0, 0), transformed)
# Save the result
output_image.save("outImage.png")
print("Image transformed and saved as outImage.png")
if __name__ == "__main__":
main()