Created
January 11, 2021 19:46
-
-
Save crackwitz/413bbb458b88772f5912d8af978b0b53 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env python3 | |
import os | |
import sys | |
import argparse | |
import numpy as np | |
import cv2 as cv | |
def draw_pattern(a, grain=1, tiled=False): | |
global ix, iy, gx, gy | |
h,w = a.shape[:2] | |
#ix = np.arange(w) | |
#iy = np.arange(h) | |
#gx, gy = np.meshgrid(ix, iy, indexing="xy") | |
(gy, gx) = np.indices((h,w)) | |
if not tiled: | |
K = 2*grain | |
K = 2 | |
gx //= grain | |
gy //= grain | |
gx %= 2 | |
gy %= 2 | |
a[:,:] = (gx ^ gy) * 255 | |
else: | |
tx = (gx // tiled) & 1 | |
ty = (gy // tiled) & 1 | |
tt = ty*2 + tx | |
gx //= grain | |
gy //= grain | |
gx %= 2 | |
gy %= 2 | |
#a[tx != ty] = (255 * gx)[tx != ty] | |
#a[tx == ty] = (255 * gy)[tx == ty] | |
a[tt == 0] = (255 * (gx ^ gy))[tt == 0] | |
a[tt == 1] = (255 * gx)[tt == 1] | |
a[tt == 2] = (255 * gy)[tt == 2] | |
a[tt == 3] = 255 * 0.5**(1/2.2) | |
# https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse | |
def str2bool(v): | |
if isinstance(v, bool): | |
return v | |
if v.lower() in ('yes', 'true', 't', 'y', '1'): | |
return True | |
elif v.lower() in ('no', 'false', 'f', 'n', '0'): | |
return False | |
else: | |
raise argparse.ArgumentTypeError('Boolean value expected.') | |
# or whatever is hardcoded in window_w32.cpp | |
parser = argparse.ArgumentParser(description="let's test imshow's gutter and resampling method") | |
parser.add_argument("--size", metavar="WxH", type=str, default="2560x1440", | |
help="assumed resolution") | |
#parser.set_defaults(size="1920x1080") | |
parser.add_argument("--fullscreen", metavar="Y/N", type=str2bool, default=True, | |
help="fullscreen or resizable window") | |
parser.add_argument("--gutter", metavar="PIXELS", type=int, default=0, | |
help="subtracted from picture size to compensate for imshow() gutter") | |
parser.add_argument("--opengl", metavar="Y/N", type=str2bool, default=True, | |
help="OpenGL uses linear interpolation, \"native\" may be nearest neighbor") | |
parser.add_argument("--grain", metavar="N", type=int, default=1, | |
help="size of checker fields") | |
parser.add_argument("--tiled", metavar="N", type=int, default=0, | |
help="show tiles of gray, horizontal, vertical, and checkered tiles") | |
args = parser.parse_args() | |
# pick your display's resolution | |
# (someone should test this with Windows' DPI scaling because I'm at 100%) | |
width, height = map(int, args.size.split('x')) | |
#width, height = 2560, 1440 | |
#width, height = 1920, 1080 | |
print(f"size: {width} x {height}") | |
#(width, height) = (width + 2*gutter, height + 2*gutter) # (approximately) simulate gutter when no gutter | |
(width, height) = (width - 2*args.gutter, height - 2*args.gutter) # simulate no gutter when gutter | |
print(f"size: {width} x {height} adjusted for gutter of {args.gutter} pixels") | |
checkers = np.zeros((height, width), np.uint8) | |
draw_pattern(checkers, grain=args.grain, tiled=args.tiled) | |
cv.imwrite("checkers.png", checkers) | |
# possible outputs: | |
# - pixel perfect checker pattern | |
# - same but cropped (border) | |
# - resampled nearest neighbor (pixel pattern but with breaks in it, may be hard to see) | |
# - resampled linearly, blurry but uniform brightness (gamma-aware) | |
# - resampled linearly, blurry and varying brightness (gamma-oblivious) | |
windowname = "press a key, any key" | |
print("namedWindow() with", ("WINDOW_OPENGL" if args.opengl else "WINDOW_NORMAL")) | |
cv.namedWindow(windowname, | |
flags=(cv.WINDOW_OPENGL if args.opengl else cv.WINDOW_NORMAL) | |
# flags=cv.WINDOW_NORMAL # WINDOW_NORMAL does nearest neighbor | |
# flags=cv.WINDOW_OPENGL # WINDOW_OPENGL does bilinear | |
) | |
if args.fullscreen: | |
print("setWindowProperty(..., WND_PROP_FULLSCREEN, True)") | |
cv.setWindowProperty(windowname, | |
prop_id=cv.WND_PROP_FULLSCREEN, | |
prop_value=cv.WINDOW_FULLSCREEN) # value is basically "true", is only member of WindowFlags for convenience | |
else: | |
print(f"resizeWindow(..., {width}, {height})") | |
cv.resizeWindow(windowname, width, height) | |
cv.imshow(windowname, checkers) | |
# 0 should stand for 0 milliseconds (polling), infinity should be strictly < 0 | |
# that's currently not the case... | |
cv.waitKey(-1) | |
cv.destroyWindow(windowname) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment