Scale an image

This commit is contained in:
Matt McWilliams 2023-02-22 15:17:03 -05:00
parent a51a4b6a23
commit 478e88e7ea
1 changed files with 97 additions and 7 deletions

View File

@ -4,7 +4,7 @@ import cv2
import numpy as np import numpy as np
from os.path import exists, basename from os.path import exists, basename
from json import dumps from json import dumps
from common import display, draw_text from common import display, draw_text, read_json
IN=25.4 IN=25.4
DPI=600 DPI=600
@ -30,43 +30,97 @@ def create_blank(width, height):
return image return image
def generate (args) : def generate (args) :
if args.output is None:
print(f'Please include an -o/--output image')
exit(1)
print('generate') print('generate')
print('--------') print('--------')
dpi = DPI dpi = DPI
if args.dpi is not None : if args.dpi is not None :
dpi = args.dpi dpi = args.dpi
dpmm = dpi / IN dpmm = dpi / IN
print(f'DPI:{dpi}') print(f'DPI:{dpi}')
print(f'DPMM:{dpmm}') print(f'DPMM:{dpmm}')
w = int(W * dpmm) w = int(W * dpmm)
h = int(H * dpmm) h = int(H * dpmm)
blank = create_blank(w, h) blank = create_blank(w, h)
print(f'Created {w},{h}')
topLeftX = int(round(w * 0.2)) topLeftX = int(round(w * 0.2))
topLeftY = int(round(h * 0.2)) topLeftY = int(round(h * 0.2))
bottomRightX = int(round(w * 0.8)) bottomRightX = int(round(w * 0.8))
bottomRightY = int(round(h * 0.8)) bottomRightY = int(round(h * 0.8))
hundred = int(round(100.0 * dpmm)) hundred = int(round(100.0 * dpmm))
five = int(round(2.5 * dpmm)) five = int(round(2.5 * dpmm))
cv2.line(blank, (topLeftX, topLeftY,), (topLeftX + hundred, topLeftY,), [0, 0, 0], 1) cv2.line(blank, (topLeftX, topLeftY,), (topLeftX + hundred, topLeftY,), [0, 0, 0], 1)
cv2.line(blank, (topLeftX, topLeftY,), (topLeftX, topLeftY + hundred,), [0, 0, 0], 1) cv2.line(blank, (topLeftX, topLeftY,), (topLeftX, topLeftY + hundred,), [0, 0, 0], 1)
for i in MEASUREMENTS.keys() : for i in MEASUREMENTS.keys() :
print(i)
if 'x' in MEASUREMENTS[i] is not None: if 'x' in MEASUREMENTS[i] is not None:
print(MEASUREMENTS[i]['x'])
x = int(round(MEASUREMENTS[i]['x'] * dpmm)) x = int(round(MEASUREMENTS[i]['x'] * dpmm))
cv2.line(blank, (topLeftX + x, topLeftY + five,), (topLeftX + x, topLeftY - five,), [0, 0, 0], 1) cv2.line(blank, (topLeftX + x, topLeftY + five,), (topLeftX + x, topLeftY - five,), [0, 0, 0], 1)
draw_text(blank, (topLeftX + x, topLeftY - five - int(2 * dpmm),), f'{i}', dpi) draw_text(blank, (topLeftX + x, topLeftY - five - int(2 * dpmm),), f'{i}', dpi)
elif 'y' in MEASUREMENTS[i] is not None: elif 'y' in MEASUREMENTS[i] is not None:
print(MEASUREMENTS[i]['y'])
y = int(round(MEASUREMENTS[i]['y'] * dpmm)) y = int(round(MEASUREMENTS[i]['y'] * dpmm))
cv2.line(blank, (topLeftX + five, topLeftY + y,), (topLeftX - five, topLeftY + y,), [0, 0, 0], 1) cv2.line(blank, (topLeftX + five, topLeftY + y,), (topLeftX - five, topLeftY + y,), [0, 0, 0], 1)
draw_text(blank, (topLeftX + five + int(2 * dpmm), topLeftY + y,), f'{i}', dpi) draw_text(blank, (topLeftX + five + int(2 * dpmm), topLeftY + y,), f'{i}', dpi)
#display(blank) cv2.imwrite(args.output, blank)
def calculate_scale (obj) :
xReal = 0
xMeasured = 0
yReal = 0
yMeasured = 0
for i in MEASUREMENTS.keys() :
if 'x' in MEASUREMENTS[i] is not None:
xReal += MEASUREMENTS[i]['x']
xMeasured += obj[i]
elif 'y' in MEASUREMENTS[i] is not None:
yReal += MEASUREMENTS[i]['y']
yMeasured += obj[i]
return xReal / xMeasured, yReal / yMeasured
def merge (original, newImg) :
oH, oW = original.shape[:2]
nH, nW = newImg.shape[:2]
if nH == oH and nW == oW :
return newImg
if nH > oH and nW > oW :
# total crop
offsetX = int((nW - oW) / 2)
offsetY = int((nH - oH) / 2)
return newImg[offsetY:offsetY+oH, offsetX:offsetX+oW]
if nH < oH and nW < oW :
# total placement
offsetX = int((oH - nH) / 2)
offsetY = int((oW - nW) / 2)
original[offsetY:offsetY+nH, offsetX:offsetX+nW] = newImg
return original
if nH > oH and nW <= oW :
offsetX = int((oW - nW) / 2)
offsetY = int((nH - oH) / 2)
crop = newImg[offsetY:offsetY+oH,0:nW]
original[0:oH, offsetX:offsetX+nW] = crop
return original
if nH <= oH and nW > oW :
offsetX = int((nW - oW) / 2)
offsetY = int((oH - nH) / 2)
crop = newImg[0:nH,offsetX:offsetX+oW]
original[offsetY:offsetY+nH, 0:oW] = crop
return original
cv2.imwrite('test.jpg', blank)
def calibrate (args) : def calibrate (args) :
print('calibrate') print('calibrate')
@ -81,22 +135,58 @@ def calibrate (args) :
val = input(f'{m}: ') val = input(f'{m}: ')
json[m] = float(val) json[m] = float(val)
x, y = calculate_scale(json)
json['x'] = x
json['y'] = y
txt=dumps(json, sort_keys = True, indent = 4) txt=dumps(json, sort_keys = True, indent = 4)
if args.output is None : if args.output is None :
print(f'{txt}') print(f'{txt}')
else : else :
print(f'Wrote file to {args.output}') print(f'Wrote file to {args.output}')
with open(args.output, 'w') as output:
output.write(txt)
def scale (args) : def scale (args) :
print('scale') print('scale')
print('-----') print('-----')
if args.calibration is None :
print(f'Please provide a calibration file (-c/--calibration)')
exit(1)
if args.input is None :
print(f'Please provide an input file (-i/--input)')
exit(2)
if args.output is None:
print(f'Please provide an output file (-o/--output)')
exit(3)
obj = read_json(args.calibration)
img = cv2.imread(args.input)
height, width = img.shape[:2]
output = create_blank(width, height)
newWidth = int(round(width * obj['x']))
newHeight = int(round(height * obj['y']))
dim = (newWidth, newHeight)
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
output = merge(output, resized)
cv2.imwrite(args.output, output)
def main () : def main () :
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('action', help='The action to perform', choices=ACTIONS) parser.add_argument('action', help='The action to perform', choices=ACTIONS)
parser.add_argument('--dpi', '-d', help='DPI to generate', required=False, type=int) parser.add_argument('--dpi', '-d', help='DPI to generate', required=False, type=int)
parser.add_argument('--input', '-i', help='Input file', required=False) parser.add_argument('--input', '-i', help='Input file', required=False)
parser.add_argument('--output', '-o', help='Output file', required=False) parser.add_argument('--output', '-o', help='Output file', required=False)
parser.add_argument('--calibration', '-c', help='Calibration file', required=False)
args = parser.parse_args() args = parser.parse_args()
if args.action == 'generate' : if args.action == 'generate' :