import os, sys, shutil, random, pathlib from os.path import join as pjoin import cv2 import utils utils.help_option(''' crops_dir2dataset_dir Convert 'crops_dir' to dataset directory It make train,valid and test directory in 'crops_dir' make list of pair of image:mask shuffle the list and then move image, masks into train/valid/test NOTE: the names of the masks are changed to the same as the image. [synopsys] python crops_dir2dataset_dir.py crops_dir label_str ex) python crops_dir2dataset_dir.py 35crops _mask_ ''') crops_dir = sys.argv[1] crops_dir = pathlib.Path(crops_dir).parts[0] label_str = sys.argv[2] all_paths = list(utils.file_paths(crops_dir)) img_paths = sorted(filter(lambda p: label_str not in p, all_paths)) mask_paths = sorted(filter(lambda p: label_str in p, all_paths)) img_mask_pairs = list(zip(img_paths, mask_paths)) random.shuffle(img_mask_pairs)
import utils utils.help_option(''' mask_maker make answer data from 'job_records' and then save them into 'answer_dir' if you want to start specific 'index' of job records, (want to rewrite some answers) pass integer as 4th argument. synopsis python mask_maker.py job_records answer_dir python mask_maker.py job_records answer_dir index example python mask_maker.py ./job_records.bin ./answers python mask_maker.py ./job_records.bin ./answers 13 ''') import manual_selector, textMaskMakerUI import sys, shutil, os, cv2 def is_done(imgpath_imgname): return (len(imgpath_imgname) == 3) def main(job_records_path, answer_dir, goto=None): now_idx, jobs, selected = manual_selector.load(job_records_path) if goto is not None:
import sys, os, cv2 from fp import pipe, cmap, cfilter import numpy as np import utils np.set_printoptions(threshold=np.nan, linewidth=np.nan) utils.help_option(''' clean_masks load masks from 'mask_dir', clean masks, merge 'selected_channel' to get graysacle image, and then *OVERWIRTE* masks with clean masks. it can know dataset is gray or rgb images. but DO NOT MIX graysacle & rgb images! [synopsys] python clean_masks.py mask_dir selected_channel ex) python clean_masks.py ./35crops/test/label/ rg ''') def binarization(img, threshold=100): #cv2.imshow('nb',img); cv2.waitKey(0) #_,binarized = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY) #print(img[:100,:100]) binarized = (img >= threshold).astype(np.uint8) * 255 #print((img >= threshold)[:100,:100]) #cv2.imshow('b',binarized); cv2.waitKey(0) return binarized
import os, random, _pickle, cv2 from fp import pipe, cmap import utils utils.help_option( ''' manual_selector select 'N' images from 'imgs_dir' and save image name and paths into 'job_records_path'. 'monitor_height' is maximum height size of ui if 'job_records_path' already exists, continue with this, append to selected. synopsis python manual_selector.py N monitor_height imgs_dir job_records_path example python manual_selector.py 2 980 ./mangas/ job_records.bin ''' ) def load(job_records_path): with open(job_records_path,'rb') as f: return _pickle.load(f) def save(now_idx, jobs, selected, job_records_path): with open(job_records_path,'wb') as f: _pickle.dump((now_idx,jobs,selected),f)
import pathlib, shutil, sys, cv2 import numpy as np import utils from fp import pipe, cmap, cfilter utils.help_option(''' separator: separate rgb/grayscale image files. create new argv[2] directory(tree structure preserved), separate images in argv[1], and move rgb imgs to new directory. ex) python separator.py ./data/examples/ ./data/rgb ^~~~~~~~~~~~~~~~ ^~~~~~~~~~ origin img dir new directory for rgb imgs. ''') is_grayscale = (lambda img: np.all(img[:, :, 0] == img[:, :, 1]) and np.all( img[:, :, 1] == img[:, :, 2])) if __name__ == '__main__': mixed_imgs_path = sys.argv[1] rgb_imgs_path = sys.argv[2] utils.safe_copytree(mixed_imgs_path, rgb_imgs_path, ('*.jpg', '*.jpeg', '*.png')) f = pipe(utils.file_paths, cmap(lambda path: (cv2.imread(path), path)), cfilter(lambda img_path: img_path[0] is not None), cfilter(lambda img_path: not is_grayscale(img_path[0]))) old_parent_dir = pathlib.Path(mixed_imgs_path).parts[-1]
import os, sys, _pickle, cv2, h5py import utils utils.help_option(''' manual_classifier: classify good/bad crop from 'crops.h5' and then save the result to 'ox_list' synopsis python manual_classifier crops.h5 ox_list example python manual_classifier ./crops.h5 ox_list ''') def load(ox_list_path): with open(ox_list_path, 'rb') as f: return _pickle.load(f) def save(now_idx, num_checked, ox_list, ox_list_path): with open(ox_list_path, 'wb') as f: _pickle.dump((now_idx, num_checked, ox_list), f) def look_and_decide(image, window_title='o x 4 6 q'): while True: cv2.imshow(window_title, image) key = cv2.waitKey(1) & 0xFF if (key == ord('o') or # good crop key == ord('x') or # bad crop
import sys, os, cv2, tqdm, pathlib from fp import pipe, cmap, cfilter, flatten import itertools import utils utils.help_option(''' img_cutter copy_tree structure of 'src_path' to 'dst_path' then save square crops of images in 'src_path' [synopsys] python img_cutter.py crop_size src_path dst_path ex) python img_cutter.py 256 ./src ./dst ''') def hw2start_yxs(origin_yx, img_hw, piece_hw): org_y, org_x = origin_yx img_h, img_w = img_hw piece_h, piece_w = piece_hw for y in range(org_y, img_h, piece_h): for x in range(org_x, img_w, piece_w): yield (y, x) def hw2not_excess_start_yxs(origin_yx, img_hw, piece_hw): img_h, img_w = img_hw piece_h, piece_w = piece_hw def not_excess(yx):
from skimage.measure import compare_ssim from fp import pipe, cmap, flip, unzip from layers import completion_net, discrimination_net from tester_ui import tester_ui import utils utils.help_option( ''' evaluator: evaluate all complnets in 'complnet_dir' using (origin,answer,mask) in 'dataset_dir'. save mse ratio similarity/error, masked/full ssim as yml. save mean of scores and list of all scores. [synopsis] python evaluator.py complnet_dir dataset_dir img_dir ex) python evaluator.py olds/192x_200e/ eval-data/mini_evals ./output/small30_1000results/ ''' ) def mse(A,B): return ((A-B)**2).mean() def normalized(uint8img): return uint8img.astype(np.float32) / 255 def inverse_normalized(float32img): return (float32img * 255).astype(np.uint8)