Skip to content

Instantly share code, notes, and snippets.

@robertknight
Last active March 2, 2024 09:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertknight/bf9df9f582b14fac1f80d4681859ec02 to your computer and use it in GitHub Desktop.
Save robertknight/bf9df9f582b14fac1f80d4681859ec02 to your computer and use it in GitHub Desktop.
Rectify a portion of an image using OpenCV
import cv2
import numpy as np
import argparse
def warp_quadrilateral(
input_path: str,
src_points: list[tuple[int, int]],
output_path: str,
output_size: tuple[int, int],
):
"""
Warps a quadrilateral from an input image to a rectangular output image.
:param input_path: Path to the input image.
:param src_points: Four coordinates specifying vertices of the quadrilateral in the input image.
Format: [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
:param output_path: Path where the output image will be saved.
:param output_size: Size of the output image (width, height).
"""
image = cv2.imread(input_path)
src = np.array(src_points, dtype="float32")
dst = np.array(
[
[0, 0],
[output_size[0] - 1, 0],
[output_size[0] - 1, output_size[1] - 1],
[0, output_size[1] - 1],
],
dtype="float32",
)
transform_matrix = cv2.getPerspectiveTransform(src, dst)
warped = cv2.warpPerspective(image, transform_matrix, output_size)
cv2.imwrite(output_path, warped)
def parse_coordinates(coordinate_string: str) -> list[tuple[int, int]]:
"""
Parses a coordinate string formatted as "x0,y0;x1,y1;x2,y2;x3,y3" into a list of tuples.
"""
return [tuple(map(int, point.split(","))) for point in coordinate_string.split(";")]
def main():
parser = argparse.ArgumentParser(
description="Warp a quadrilateral from an input image to a rectangular output image."
)
parser.add_argument("input_path", type=str, help="Path to the input image.")
parser.add_argument(
"output_path", type=str, help="Path where the output image will be saved."
)
parser.add_argument(
"coordinates",
type=str,
help="List of coordinates for the quadrilateral formatted as x0,y0;x1,y1;x2,y2;x3,y3.",
)
parser.add_argument(
"output_size", type=str, help="Output size as a (width,height) tuple"
)
args = parser.parse_args()
src_points = parse_coordinates(args.coordinates)
output_size = tuple(map(int, args.output_size.split(",")))
warp_quadrilateral(args.input_path, src_points, args.output_path, output_size)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment