Skip to content

Instantly share code, notes, and snippets.

@mathandy
Last active November 12, 2024 05:36
Show Gist options
  • Save mathandy/389ddbad48810d188bdc997c3a1dab0c to your computer and use it in GitHub Desktop.
Save mathandy/389ddbad48810d188bdc997c3a1dab0c to your computer and use it in GitHub Desktop.
Use OpenCV to draw grid lines on an image.
"""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