|
|
|
|
|
|
|
|
|
|
|
import os |
|
|
import sys |
|
|
import json |
|
|
import math |
|
|
import numpy as np |
|
|
|
|
|
max_theta = math.pi / 4 |
|
|
max_scale_delta = 0.2 |
|
|
|
|
|
def img_size(imgname): |
|
|
w, h = os.popen('identify -format "%wx%h" ' + imgname).read().split("x") |
|
|
return int(w), int(h) |
|
|
|
|
|
def img_rotate_scale(imgname, angle, scale, landmark, dest_dir, annotate=False): |
|
|
|
|
|
noext, ext = os.path.splitext(imgname) |
|
|
angle_degree = angle / math.pi * 180 |
|
|
|
|
|
w, h = img_size(imgname) |
|
|
x0, y0 = float(w) / 2, float(h) / 2 |
|
|
|
|
|
c = math.cos(angle) |
|
|
s = math.sin(angle) |
|
|
|
|
|
xs = landmark["x"] |
|
|
ys = landmark["y"] |
|
|
|
|
|
|
|
|
new_xs = [] |
|
|
new_ys = [] |
|
|
for i in range(len(xs)): |
|
|
dx = xs[i] - x0 |
|
|
dy = ys[i] - y0 |
|
|
|
|
|
new_xs.append(int(scale * (dx * c - dy * s) + x0 + 0.5)) |
|
|
new_ys.append(int(scale * (dx * s + dy * c) + y0 + 0.5)) |
|
|
|
|
|
annotation_command = "" |
|
|
if annotate: |
|
|
annotation_command = "-fill '#0008'" |
|
|
annotation_command += \ |
|
|
"".join([" -draw 'rectangle %d,%d,%d,%d'" % (xx - 2, yy - 2, xx + 2, yy + 2) for xx, yy in zip(new_xs, new_ys)]) |
|
|
|
|
|
fn_output = noext + "_a%.3f_s%.3f.png" % (angle_degree, scale) |
|
|
os.system("convert %s -distort SRT '%f,%f %f,%f %f' %s %s" % (imgname, x0, y0, scale, scale, angle_degree, annotation_command, os.path.join(dest_dir, fn_output) )) |
|
|
|
|
|
return fn_output, { "x" : new_xs, "y" : new_ys } |
|
|
|
|
|
|
|
|
''' |
|
|
Input: landmarks.json and a dest_dir (sys.argv[1]) |
|
|
landmarks.json has the following format: |
|
|
{ |
|
|
filename1 : landmark_location1 |
|
|
filename2 : landmark_location2 |
|
|
} |
|
|
|
|
|
landmark_location1 = { x : [x1, x2, x3], y : [y1, y2, y3] } |
|
|
|
|
|
sys.argv[1] is the directory we want to save all deformed image to |
|
|
Output: |
|
|
A bunch of images within the dest_dir with a landmarks.json. |
|
|
|
|
|
''' |
|
|
|
|
|
landmarks = json.load(open(os.path.join(os.getcwd(), "landmarks.json"), "r")) |
|
|
dest_dir = sys.argv[1] |
|
|
os.system("mkdir -p " + dest_dir) |
|
|
|
|
|
angles = np.linspace(-max_theta, max_theta, 20) |
|
|
scales = np.linspace(1 - max_scale_delta, 1 + max_scale_delta, 20) |
|
|
|
|
|
output_landmarks = {} |
|
|
num_landmarks = 0 |
|
|
count = 0 |
|
|
for fn, landmark in landmarks.iteritems(): |
|
|
if not isinstance(landmark, dict): continue |
|
|
print("Deal with image = " + fn) |
|
|
for angle in angles: |
|
|
for scale in scales: |
|
|
fn_output, new_landmark = img_rotate_scale(fn, angle, scale, landmark, dest_dir, False) |
|
|
output_landmarks.update({ |
|
|
fn_output : new_landmark |
|
|
}) |
|
|
count += 1 |
|
|
num_landmarks = len(landmark["x"]) |
|
|
|
|
|
output_landmarks.update({ |
|
|
"num_landmarks" : num_landmarks, |
|
|
"num_images" : count |
|
|
}) |
|
|
|
|
|
json.dump(output_landmarks, open(os.path.join(dest_dir, "landmarks.json"), "w"), sort_keys=True, indent=4) |
|
|
|