Last active
November 12, 2024 05:36
-
-
Save mathandy/389ddbad48810d188bdc997c3a1dab0c to your computer and use it in GitHub Desktop.
Use OpenCV to draw grid lines on an image.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Draw grid lines on an image. | |
Usage: | |
# To draw a 3x4 grid on an image | |
$ python draw_grid_lines.py <path/to/image> <num_rows> <num_cols> -o <output/dir-or-path> | |
$ python draw_grid_lines.py image.png 3 4 -o output.png | |
# for more options, see | |
$ python draw_grid_lines.py --help | |
""" | |
import cv2 as cv # tested with version 4.5.3.56 (pip install opencv-python) | |
import numpy as np | |
from pathlib import Path | |
def draw_grid(img, grid_shape, color=(0, 255, 0), thickness=1): | |
h, w, _ = img.shape | |
rows, cols = grid_shape | |
dy, dx = h / rows, w / cols | |
# draw vertical lines | |
for x in np.linspace(start=dx, stop=w-dx, num=cols-1): | |
x = int(round(x)) | |
cv.line(img, (x, 0), (x, h), color=color, thickness=thickness) | |
# draw horizontal lines | |
for y in np.linspace(start=dy, stop=h-dy, num=rows-1): | |
y = int(round(y)) | |
cv.line(img, (0, y), (w, y), color=color, thickness=thickness) | |
return img | |
def main(args): | |
img = cv.imread(str(args.input_image_path)) | |
img = draw_grid(img=img, | |
grid_shape=(args.rows, args.cols), | |
color=args.color, | |
thickness=args.thickness) | |
cv.imwrite(str(args.output_image_path), img) | |
def get_user_args(): | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
'input_image_path', type=Path, help='Path to image.' | |
) | |
parser.add_argument( | |
'rows', type=int, default=None, help='Number of grid rows.' | |
) | |
parser.add_argument( | |
'cols', type=int, default=None, help='Number of grid columns.' | |
) | |
parser.add_argument( | |
'--output_image_path', '-o', type=Path, default=None, help='Where to store output image (full path or directory).' | |
) | |
parser.add_argument( | |
'--overwrite_ok', '-f', action='store_true', help='Allow overwriting existing output path.' | |
) | |
parser.add_argument( | |
'--color', '-c', default=(0, 255, 0), nargs=3, type=int, help='Line color as BGR triplet.' | |
) | |
parser.add_argument( | |
'--thickness', '-t', default=1, type=int, help='Line thickness.' | |
) | |
args = parser.parse_args() | |
# parse output path | |
input_image_dir = args.input_image_path.resolve().parent | |
if args.output_image_path is None: | |
# set default output path to same dir as original, with filename prefix | |
args.output_image_path = \ | |
input_image_dir / f"{args.rows}x{args.cols}_grid_{args.input_image_path.name}" | |
elif args.output_image_path.is_dir(): | |
# set output path filename to "<output_dir>/<original_filename>" | |
args.output_image_path = args.output_image_path / args.input_image_path.name | |
if not args.overwrite_ok: | |
assert not args.output_image_path.exists() | |
return args | |
if __name__ == '__main__': | |
main(get_user_args()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment