animation/fourcell/apply_image.py

169 lines
4.6 KiB
Python
Raw Normal View History

import sys
import cv2
import numpy as np
from json import load
from os.path import exists, basename
from common import image_resize, display, read_json
holeConstant = .0156862745 # 160/10200
fontConstant = 1/6000
def generate_text (text, fontSize, rotation) :
2023-03-18 23:10:11 +00:00
rgb_color=(255,255,255)
color = tuple(reversed(rgb_color))
(w, h), baseline = cv2.getTextSize(text, cv2.FONT_HERSHEY_PLAIN, fontSize, 2)
image = np.zeros((h + baseline, w, 3), np.uint8)
image[:] = color
image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
image = cv2.putText(image, text, (0, h + round(baseline/2)), cv2.FONT_HERSHEY_PLAIN, fontSize, [0, 0, 0], 2, cv2.LINE_AA)
if rotation == 90 :
image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
elif rotation == -90 :
image = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)
return image
def place_text (output, text_image, i, points) :
#print('place_text')
height, width = text_image.shape[:2]
halfW = int(round(width/2))
halfH = int(round(height/2))
#print(f'{width}x{height}')
if i == 0 or i == 1 :
y = int(round((points['0']['y'] + points['1']['y']) / 2))
x = int(round((points['0']['x'] + points['1']['x']) / 2)) - width
elif i == 2 or i == 3 :
y = int(round((points['0']['y'] + points['1']['y']) / 2))
x = int(round((points['0']['x'] + points['1']['x']) / 2)) + width
output[y-halfH:y-halfH+height, x-halfW:x-halfW+width] = text_image
return output
def to_rotation (i) :
if i == 0 or i == 1 :
return -90
2023-03-18 23:10:11 +00:00
if i == 2 or i == 3 :
return 90
def to_text (fileName) :
parts = fileName.split('.')
name = parts[0]
parts = name.split('_')
return parts[len(parts)-1]
# use top left, top right, bottom left
def apply_image_to_points (original, target, points) :
rows, cols, ch = original.shape
ir, ic, ich = target.shape
print('Using points: ')
print(points)
atPts = np.float32(points)
targetPts = np.float32([[0, 0], [ic, 0], [0, ir]])
M = cv2.getAffineTransform(targetPts, atPts)
2023-02-20 23:54:08 +00:00
dst = cv2.warpAffine(target, M, (cols, rows),
flags = cv2.INTER_CUBIC,
borderMode = cv2.BORDER_CONSTANT,
borderValue = [0, 0, 0, 0])
2023-02-20 23:54:08 +00:00
mask = get_mask(dst)
return combine_images(original, dst, mask)
def create_blank(width, height):
rgb_color=(255,255,255)
image = np.zeros((height, width, 3), np.uint8)
color = tuple(reversed(rgb_color))
image[:] = color
2023-02-10 03:17:18 +00:00
#return image
return cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
# get points 0, 1 and 3 = top left, top right and bottom left
def to_points (d) :
return [[d['0']['x'], d['0']['y']], [d['1']['x'], d['1']['y']], [d['3']['x'], d['3']['y']]]
def get_mask (img) :
lower = np.array([0,0,0,0])
upper= np.array([0,0,0,0])
mask = cv2.inRange(img, lower, upper)
return cv2.bitwise_not(mask)
def combine_images (bg, fg, mask) :
fk = cv2.bitwise_or(fg, fg, mask=mask)
mask = cv2.bitwise_not(mask)
bk = cv2.bitwise_or(bg, bg, mask=mask)
return cv2.bitwise_or(fk, bk)
if len(sys.argv) < 2 :
print('Please provide an output destination file')
exit(1)
outputFile = sys.argv[1]
if len(sys.argv) < 3:
print('Please provide a calibration template to apply images to')
exit(2)
templateFile = sys.argv[2]
if not exists(templateFile) :
print('Calibration template does not exist, please provide one that does')
exit(3)
if len(sys.argv) < 4:
print('Please provide at least one image to apply')
exit(4)
if len(sys.argv) > 7:
print('Please provide maximum four images to apply')
exit(5)
images = []
for i in range(3, len(sys.argv)):
imagePath = sys.argv[i]
if not exists(imagePath) :
print(f'Image {imagePath} does not exist, exiting...')
exit(6)
images.append(imagePath)
print('Using images: ')
for img in images:
print(f' -> {basename(img)}')
tmpl = read_json(templateFile)
print(f"Image size {tmpl['width']}x{tmpl['height']}")
hole = round(tmpl['width'] * holeConstant)
blank = create_blank(tmpl['width'], tmpl['height'])
2023-03-18 23:10:11 +00:00
dpi = round(tmpl['width'] / 8.5)
fontSize = round((dpi / 48) / 2)
2023-02-20 23:54:08 +00:00
#blank = cv2.imread(templateFile.replace('.calibration.json', ''))
output = blank.copy()
hp = tmpl['holePunches']
for i in hp:
print(hp[i])
cv2.circle(output, (hp[i]['x'], hp[i]['y'],), hole, (200, 200, 200,), -1)
2023-02-20 23:54:08 +00:00
for i in range(0, len(images)) :
frame = cv2.imread(images[i])
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2RGBA)
#cv2.imwrite(f'test{i}.png', output)
2023-02-20 23:54:08 +00:00
output = apply_image_to_points(output, frame, to_points(tmpl[f'{i}']))
rotation = to_rotation(i)
text = to_text(basename(images[i]))
2023-03-18 23:10:11 +00:00
text_image = generate_text(text, fontSize, rotation)
output = place_text(output, text_image, i, tmpl[f'{i}'])
2023-02-20 23:54:08 +00:00
print(f'Applied {basename(images[i])}')
2023-02-20 23:54:08 +00:00
output = cv2.cvtColor(output, cv2.COLOR_BGRA2BGR)
#display(output)
cv2.imwrite(outputFile, output)
2023-02-10 03:17:18 +00:00
##print(f'Wrote {outputFile}')