Skip to content

Commit

Permalink
Used type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
hanzhi713 committed Nov 24, 2018
1 parent 16c9237 commit 2d4e4d8
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 36 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ dist
gui.spec
__pycache__
venv
test.sh
test.sh
.mypy_cache
14 changes: 7 additions & 7 deletions gui.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from tkinter import *
from tkinter import filedialog, messagebox
from tkinter.ttk import *
import traceback
import os
import cv2
from PIL import Image, ImageTk
from multiprocessing.pool import ThreadPool
from multiprocessing import Queue, freeze_support
from typing import Tuple, List
import traceback
import math
import sys
import os
import cv2
import make_img

make_img.pbar_ncols = 110


def limit_wh(w: int, h: int, max_width: int, max_height: int) -> [int, int]:
def limit_wh(w: int, h: int, max_width: int, max_height: int) -> Tuple[int, int]:
if h > max_height:
ratio = max_height / h
h = max_height
Expand Down Expand Up @@ -169,8 +170,7 @@ def action():
pool.close()

except:
t = traceback.format_exc()
messagebox.showerror("Error", t)
messagebox.showerror("Error", traceback.format_exc())


Button(right_top_panel, text=" Load source images ", command=load_images).grid(
Expand Down Expand Up @@ -324,7 +324,7 @@ def attach_uneven():


distance_metric = StringVar()
distance_metric.set("euclidena")
distance_metric.set("euclidean")
Label(right_collage_opt_panel, text="Metric: ").grid(row=5, column=0, sticky="W")
OptionMenu(right_collage_opt_panel, distance_metric, "", *make_img.all_metrics).grid(row=5, column=1, sticky="W")

Expand Down
61 changes: 33 additions & 28 deletions make_img.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
import sys
import time
import platform
from typing import *

pbar_ncols = None


def bgr_chl_sum(img: np.ndarray) -> [float, float, float]:
def bgr_chl_sum(img: np.ndarray) -> Tuple[float, float, float]:
return np.sum(img[:, :, 0]), np.sum(img[:, :, 1]), np.sum(img[:, :, 2])


Expand All @@ -32,7 +33,7 @@ def av_sat(img: np.ndarray) -> float:
return np.mean(hsv[:, :, 1])


def hsv(img: np.ndarray) -> [float, float, float]:
def hsv(img: np.ndarray) -> Tuple[float, float, float]:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
return np.mean(hsv[:, :, 0]), np.mean(hsv[:, :, 1]), np.mean(hsv[:, :, 2])

Expand Down Expand Up @@ -108,7 +109,7 @@ def finish(self):
self.tqdm.close()


def calculate_grid_size(rw: int, rh: int, num_imgs: int) -> tuple:
def calculate_grid_size(rw: int, rh: int, num_imgs: int) -> Tuple[int, int]:
"""
:param rw: the width of the target image
:param rh: the height of the target image
Expand All @@ -123,7 +124,7 @@ def calculate_grid_size(rw: int, rh: int, num_imgs: int) -> tuple:
return min(possible_wh, key=lambda x: ((x[0] / x[1]) - (rw / rh)) ** 2)


def make_collage(grid: tuple, sorted_imgs: list or np.ndarray, rev: False) -> np.ndarray:
def make_collage(grid: Tuple[int, int], sorted_imgs: List[np.ndarray], rev: bool = False) -> np.ndarray:
"""
:param grid: grid size
:param sorted_imgs: list of images sorted in correct position
Expand All @@ -145,7 +146,7 @@ def make_collage(grid: tuple, sorted_imgs: list or np.ndarray, rev: False) -> np
return combined_img


def calculate_decay_weights_normal(shape: tuple, sigma: float = 1) -> np.ndarray:
def calculate_decay_weights_normal(shape: Tuple[int, int], sigma: float = 1.0) -> np.ndarray:
"""
Generate a matrix of probabilities (as weights) sampled from a truncated bivariate normal distribution
centered at (0, 0) whose covariance matrix is equal to sigma times the identity matrix
Expand All @@ -170,7 +171,7 @@ def calculate_decay_weights_normal(shape: tuple, sigma: float = 1) -> np.ndarray
return weights


def sort_collage(imgs: list, ratio: tuple, sort_method="pca_lab", rev_sort=False) -> [tuple, np.ndarray]:
def sort_collage(imgs: List[np.ndarray], ratio: Tuple[int, int], sort_method="pca_lab", rev_sort=False) -> Tuple[Tuple[int, int], np.ndarray]:
"""
:param imgs: list of images
:param ratio: The aspect ratio of the collage
Expand Down Expand Up @@ -222,8 +223,8 @@ def sort_collage(imgs: list, ratio: tuple, sort_method="pca_lab", rev_sort=False
return result_grid, sorted_imgs


def chl_mean_hsv(weights: np.ndarray) -> "function":
def f(img: np.ndarray) -> [float, float, float]:
def chl_mean_hsv(weights: np.ndarray) -> Callable:
def f(img: np.ndarray) -> Tuple[float, float, float]:
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
return np.average(img[:, :, 0], weights=weights), \
np.average(img[:, :, 1], weights=weights), \
Expand All @@ -232,8 +233,8 @@ def f(img: np.ndarray) -> [float, float, float]:
return f


def chl_mean_hsl(weights: np.ndarray) -> "function":
def f(img: np.ndarray) -> [float, float, float]:
def chl_mean_hsl(weights: np.ndarray) -> Callable:
def f(img: np.ndarray) -> Tuple[float, float, float]:
img = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)
return np.average(img[:, :, 0], weights=weights), \
np.average(img[:, :, 1], weights=weights), \
Expand All @@ -242,17 +243,17 @@ def f(img: np.ndarray) -> [float, float, float]:
return f


def chl_mean_bgr(weights: np.ndarray) -> "function":
def f(img: np.ndarray) -> [float, float, float]:
def chl_mean_bgr(weights: np.ndarray) -> Callable:
def f(img: np.ndarray) -> Tuple[float, float, float]:
return np.average(img[:, :, 0], weights=weights), \
np.average(img[:, :, 1], weights=weights), \
np.average(img[:, :, 2], weights=weights)

return f


def chl_mean_lab(weights: np.ndarray) -> "function":
def f(img: np.ndarray) -> [float, float, float]:
def chl_mean_lab(weights: np.ndarray) -> Callable:
def f(img: np.ndarray) -> Tuple[float, float, float]:
img = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)
return np.average(img[:, :, 0], weights=weights), \
np.average(img[:, :, 1], weights=weights), \
Expand All @@ -261,8 +262,9 @@ def f(img: np.ndarray) -> [float, float, float]:
return f


def calculate_collage_bipartite(dest_img_path: str, imgs: list, dup: int = 1, colorspace="lab", ctype="float16",
sigma: float = 1.0, metric : str = "euclidean", v=None) -> [tuple, list, float]:
def calculate_collage_bipartite(dest_img_path: str, imgs: List[np.ndarray], dup: int = 1,
colorspace: str = "lab", ctype: str ="float16", sigma: float = 1.0,
metric : str = "euclidean", v = None) -> Tuple[Tuple[int, int], List[np.ndarray], float]:
"""
Compute the optimal assignment between the set of images provided and the set of pixels of the target image,
with the restriction that every image should be used the same amount of times
Expand Down Expand Up @@ -327,8 +329,8 @@ def calculate_collage_bipartite(dest_img_path: str, imgs: list, dup: int = 1, co
# compute pair-wise distances
cost_matrix = cdist(img_keys, dest_img, metric=metric)

ctype = eval("np." + ctype)
cost_matrix = ctype(cost_matrix)
np_ctype = eval("np." + ctype)
cost_matrix = np_ctype(cost_matrix)

print("Computing optimal assignment on a {}x{} matrix...".format(cost_matrix.shape[0], cost_matrix.shape[1]))

Expand All @@ -338,13 +340,16 @@ def calculate_collage_bipartite(dest_img_path: str, imgs: list, dup: int = 1, co
from lapjv import lapjv

if v is not None and platform.system() == "Linux" and v.gui:
from wurlitzer import pipes, STDOUT
from wurlitzer import Wurlitzer
Wurlitzer.flush_interval = 0.1
wrapper = JVOutWrapper(v)
with pipes(stdout=wrapper, stderr=STDOUT):
_, cols, cost = lapjv(cost_matrix, verbose=1)
wrapper.finish()
try:
from wurlitzer import pipes, STDOUT
from wurlitzer import Wurlitzer
Wurlitzer.flush_interval = 0.1
wrapper = JVOutWrapper(v)
with pipes(stdout=wrapper, stderr=STDOUT):
_, cols, cost = lapjv(cost_matrix, verbose=1)
wrapper.finish()
except ImportError:
_, cols, cost = lapjv(cost_matrix)

else:
_, cols, cost = lapjv(cost_matrix)
Expand All @@ -362,7 +367,7 @@ def calculate_collage_bipartite(dest_img_path: str, imgs: list, dup: int = 1, co


def calculate_collage_dup(dest_img_path: str, imgs: list, max_width: int = 50, color_space="lab",
sigma: float = 1.0, metric : str = "euclidean") -> [tuple, list, float]:
sigma: float = 1.0, metric : str = "euclidean") -> Tuple[Tuple[int, int], List[np.ndarray], float]:
"""
Compute the optimal assignment between the set of images provided and the set of pixels of the target image,
given that every image could be used arbitrary amount of times
Expand Down Expand Up @@ -448,7 +453,7 @@ def imwrite(filename, img):
imwrite(path, img)


def read_images(pic_path: str, img_size: tuple, recursive=False, num_process=1) -> list:
def read_images(pic_path: str, img_size: Tuple[int, int], recursive: bool = False, num_process: int = 1) -> List[np.ndarray]:
assert os.path.isdir(pic_path), "Directory " + pic_path + "is non-existent"
files = []
if recursive:
Expand Down Expand Up @@ -498,7 +503,7 @@ def read_images(pic_path: str, img_size: tuple, recursive=False, num_process=1)
return imgs


def read_img_helper(files, img_size, queue) -> list:
def read_img_helper(files: List[str], img_size: Tuple[int, int], queue) -> List[np.ndarray]:
def imread(filename):
return cv2.imdecode(np.fromfile(filename, np.uint8), cv2.IMREAD_COLOR)

Expand Down

0 comments on commit 2d4e4d8

Please sign in to comment.