def do_gen_result(): EXP_NAMES = [ "edge_angle_variance_with_hpf", "edge_angle_variance", "edge_pixel_classify", "meanshift_and_color_thresholding" ] argc, argv = len(sys.argv), sys.argv if argc == 2: exp_num = int(argv[1]) results = "\n".join( [gen_result(exp_num, exp_name) for exp_name in EXP_NAMES]) print(results) pyperclip.copy(results) eprint("Copied to clipboard") else: while True: line = input( dedent(f""" ROOT_PATH: {RESULT_ROOT_DIR} EXP NUM? > """).rstrip("\n")) if line: exp_num = int(line) results = "\n".join( [gen_result(exp_num, exp_name) for exp_name in EXP_NAMES]) print(results) pyperclip.copy(results) eprint("Copied to clipboard") else: break
def write_images(root_path, filenames_and_images, prefix="study"): for file_name, img in filenames_and_images: base_name = splitext(file_name)[0] ext = ".png" if img.dtype != np.uint8: ext = ".tiff" save_path = join( root_path, "_".join([ prefix, base_name + ext ]) ) result = cv2.imwrite( save_path, img ) if result: eprint( f"Saved Image -- {save_path}" ) else: raise RuntimeError( "Failed to save image" )
def recalc(path_json): eprint(f"Re-calculate metrics: {path_json}") j = json.load(open(path_json)) if isinstance(j["Score"], float): cm = j["Confusion Matrix"] FN, FP, TN, TP = cm["FN"], cm["FP"], cm["TN"], cm["TP"] metrics = { "Accuracy": 0 if (TP + FP + FN + TN) == 0 else 100 * (TP + TN) / (TP + FP + FN + TN), "Recall": 0 if (TP + FN) == 0 else 100 * TP / (TP + FN), "Specificity": 0 if (FP + TN) == 0 else 100 * TN / (FP + TN), "Precision": 0 if (TP + FP) == 0 else 100 * TP / (TP + FP), } j["Score"] = {**metrics, "F Score": j["Score"]} json.dump(j, open(add_prefix(path_json, "with_metrics"), "w"), ensure_ascii=False, sort_keys=True, indent="\t") return
def recalculate_scores(): RESULT_ROOT_DIR = "./tmp/detect_building_damage/master-v2/fixed_histogram" def add_prefix(file_path, prefix, delimiter="_"): base_name, ext = splitext(file_path) return f"{base_name}{delimiter}{prefix}{ext}" json_paths = sum( [[(dir_path, file_name) for file_name in file_names if "json" in file_name] for (dir_path, dir_names, file_names) in walk(RESULT_ROOT_DIR)], []) for dir_path, dir_name in json_paths: json_path = join(dir_path, dir_name) if exists(json_path): j = json.load(open(json_path)) if "Confusion Matrix" in j: j = {**j, "Score": calculate_metrics(j["Confusion Matrix"])} json.dump(j, open(add_prefix(json_path, "fixed"), "w"), ensure_ascii=False, sort_keys=True, indent="\t") eprint(f"Fixed: {json_path}") else: eprint(f"Not exists: {json_path}")
def fix_result_format(): RESULT_ROOT_DIR = "./tmp/detect_building_damage/2020_01_09_whole_test" EXP_PREFIX = "aerial_roi" OPTIONS = [ "no_norm", "GT_BOTH", ] dirs = [ path.join(RESULT_ROOT_DIR, d) for d in listdir(RESULT_ROOT_DIR) if isdir(path.join(RESULT_ROOT_DIR, d)) and "meanshift_and_color_thresholding" in d ] for d in dirs: json_path = path.join(d, "params_finder/params_morphology.json") if exists(json_path): j = json.load(open(json_path)) j = { **j, "Score": j["Score"]["F Score"], "Confusion Matrix": j["Score"]["Confusion Matrix"] } json.dump(j, open(_add_prefix(json_path, "fixed"), "w"), ensure_ascii=False, sort_keys=True, indent="\t") eprint(f"Fixed: {json_path}") else: eprint(f"Not exists: {json_path}")
def generate_scores_each_gt_type(): RESULT_ROOT_DIR = "tmp/detect_building_damage/master-v3/fixed_histogram/GT_BOTH" RESULT_GROUND_TRUTH = "img/resource/ground_truth" MAP_RESULT_IMAGE = { "meanshift_and_color_thresholding": "building_damage_fixed.tiff", "edge_angle_variance_with_hpf": "building_damage.tiff", "edge_pixel_classify": "building_damage.tiff" } C_RED = [0, 0, 255] C_ORANGE = [0, 127, 255] target_dirs = [ path.join(RESULT_ROOT_DIR, entry) for entry in listdir(RESULT_ROOT_DIR) if isdir(path.join(RESULT_ROOT_DIR, entry)) ] for target_dir in target_dirs: eprint(f"Target: {target_dir}") experiment_num, method_name = re.match( r".*/aerial_roi([0-9])_[0-9]{8}_[0-9]{6}_(.*)$", target_dir).groups() eprint( dedent(f""" Experiment Num: {experiment_num} Method: {method_name} """)) GT = cv2.imread( path.join(RESULT_GROUND_TRUTH, f"aerial_roi{experiment_num}.png")) result = imread_with_error( path.join(target_dir, MAP_RESULT_IMAGE[method_name]), cv2.IMREAD_UNCHANGED).astype(bool) for gt_type in ["GT_BOTH", "GT_RED", "GT_ORANGE"]: if gt_type == "GT_BOTH": ground_truth = np.all((GT == C_RED) | (GT == C_ORANGE), axis=2) elif gt_type == "GT_RED": ground_truth = np.all(GT == C_RED, axis=2) elif gt_type == "GT_ORANGE": ground_truth = np.all(GT == C_ORANGE, axis=2) cm, scores = evaluation_by_confusion_matrix(result, ground_truth) j = {"Confusion Matrix": cm, "Score": scores} save_path = path.join(target_dir, "evaluation", gt_type) if not exists(save_path): makedirs(save_path) json.dump(j, open(path.join(save_path, "scores.json"), "w"), ensure_ascii=False, sort_keys=True, indent="\t")
def _cleanup(self): eprint("CustomPool: cleanup") if exists(self.PATH_N_PROCESS): # eprint( # "File will be removed -- {path}".format( # path=self.PATH_N_PROCESS # ) # ) remove(self.PATH_N_PROCESS)
def remove_tiny_areas_and_recalc_score(): RESULT_ROOT_DIR = "tmp/detect_building_damage/master-v2/fixed_histogram" RESULT_GROUND_TRUTH = "img/resource/ground_truth" C_RED = [0, 0, 255] C_ORANGE = [0, 127, 255] target_dirs = [ dir_path for (dir_path, dir_names, file_names) in walk(RESULT_ROOT_DIR) if dir_path.endswith("meanshift_and_color_thresholding") ] for target_dir in target_dirs: eprint(f"Target: {target_dir}") gt_type, experiment_num = re.match(r".*/GT_(.*)/aerial_roi([0-9]).*", target_dir).groups() eprint( dedent(f""" Experiment Num: {experiment_num} GT_TYPE: GT_{gt_type} """)) result = imread_with_error( path.join(target_dir, "building_damage.tiff"), cv2.IMREAD_UNCHANGED) # Fixing Image result_fixed = BuildingDamageExtractor._remove_tiny_area( (result * 255.0).astype(np.uint8)) imwrite_with_error(path.join(target_dir, "building_damage_fixed.tiff"), result_fixed.astype(np.float32)) # Re-calc Score ground_truth = imread_with_error( path.join(RESULT_GROUND_TRUTH, f"aerial_roi{experiment_num}.png")) if gt_type == "BOTH": ground_truth = np.all( (ground_truth == C_RED) | (ground_truth == C_ORANGE), axis=2) elif gt_type == "RED": ground_truth = np.all(ground_truth == C_RED, axis=2) elif gt_type == "ORANGE": ground_truth = np.all(ground_truth == C_ORANGE, axis=2) cm, scores = evaluation_by_confusion_matrix(result_fixed, ground_truth) j = {"Confusion Matrix": cm, "Score": scores} json.dump(j, open(path.join(target_dir, "scores_fixed_result.json"), "w"), ensure_ascii=False, sort_keys=True, indent="\t")
def __init__(self, img, ksize=3, algorithm="sobel") -> None: """ コンストラクタ Parameters ---------- img : numpy.ndarray or str エッジ抽出を行う入力画像 画像データ(numpy.ndarray)と 画像ファイルへのパス(str)の 両方が許容される ksize : int エッジ抽出におけるカーネルサイズ 奇数である必要がある algorithm : str エッジ抽出のフィルタ指定 以下の値が利用可能である - `sobel` - `prewitt` """ # TODO: cv2.cvtColor(BGR2GRAY) と imread(IMREAD_GRAYSCALE) の結果が異なる!? TYPE_ASSERT(img, (str, np.ndarray)) TYPE_ASSERT(ksize, int) TYPE_ASSERT(algorithm, str) assert algorithm in ("sobel", "prewitt"), \ "Algorithm '{algorithm} is not support.".format(algorithm=algorithm) assert ksize % 2 == 1, \ "'ksize' must be odd number. (ksize={ksize})".format(ksize=ksize) if isinstance(img, str): if not path.exists(img): raise InvalidImageOrFile( "Cannot find file -- '{path}'".format(path=img)) else: self.src_img = cv2.imread(img, cv2.IMREAD_GRAYSCALE) elif isinstance(img, np.ndarray): if img.ndim == 3: self.src_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: self.src_img = img.copy() if self.src_img.dtype == np.uint8: self.src_img = self.src_img / 255 self.src_img = self.src_img.astype(np.float32) self.detector_params = {"ksize": ksize, "algorithm": algorithm} eprint("Edge params:", self.detector_params) self._edge_magnitude = None self._edge_angle = None
def imwrite_with_error(file_path, img, params=None): success = cv2.imwrite(file_path, img, params) if not success: raise IOError( f"Failed to write image: {file_path}" ) else: eprint( f"Write Image:", file_path )
def imread_with_error(file_path, flags=cv2.IMREAD_COLOR): img = cv2.imread(file_path, flags) if img is None: raise FileNotFoundError( file_path ) else: eprint( f" Load Image:", file_path ) return img
def _calc_features(_img, _feature_names): eprint("Calculating GLCM [ image.shape = {shape} ] ... ".format( shape=_img.shape)) _glcm = greycomatrix(_img, self.distances, self.degrees) return { _feature_name: {(_dist, _deg): greycoprops(_glcm, _feature_name)[_dist_idx][_deg_idx] for (_dist_idx, _dist), (_deg_idx, _deg) in keys_and_indices} for _feature_name in _feature_names }
def edge_angle_variance(self, window_size=33, step=1, skip_find_params=False): """ 建物被害検出: エッジ角度分散 - 入力画像から、特徴量としてエッジ角度分散画像を生成する - エッジ角度分散に閾値処理を行い、建物抽出結果とする Returns ------- building_damage : numpy.ndarray 被害抽出結果 Notes ----- `building_damage` - 1-Bit (bool 型) 2値画像 - 黒:背景、白:被害抽出結果 """ img = self.img_gs ground_truth = self.ground_truth logger = self.logger # Edge Angle Variance eprint("Calculate: Edge Angle Variance") fd_variance = self.calc_edge_angle_variance(img, window_size, step, logger=logger) if not skip_find_params: params_finder = ParamsFinder(logger=logger) # Find Thresholds (only AngleVariance) eprint("Calculate: Thresholds (AngleVar)") _, building_damage = params_finder.find_threshold( fd_variance, ground_truth, logger_suffix="angle_variance") # Logging if logger: logger.logging_img(building_damage, "building_damage") return building_damage return fd_variance
def test_all_procedures(path_src_img, path_ground_truth, parameters): """ すべての手法をテストする Parameters ---------- path_src_img : path-like object 入力画像へのパス path_ground_truth : path-like object 正解画像へのパス parameters : dict 各処理における引数リスト """ C_RED = [0, 0, 255] C_ORANGE = [0, 127, 255] IMG = cv2.imread(path_src_img, cv2.IMREAD_COLOR) GT = cv2.imread(path_ground_truth, cv2.IMREAD_COLOR) procedures = [ "meanshift_and_color_thresholding", "edge_angle_variance_with_hpf", "edge_pixel_classify" ] for gt_opt in ["GT_BOTH", "GT_RED", "GT_ORANGE"]: if gt_opt == "GT_BOTH": ground_truth = np.all((GT == C_RED) | (GT == C_ORANGE), axis=2) elif gt_opt == "GT_RED": ground_truth = np.all(GT == C_RED, axis=2) else: ground_truth = np.all(GT == C_ORANGE, axis=2) for proc_name in procedures: eprint("Do processing:", proc_name) logger = ImageLogger("./tmp/detect_building_damage", prefix=path.splitext( path.basename(path_src_img))[0], suffix=proc_name + "_no_norm_" + gt_opt) inst = BuildingDamageExtractor(IMG, ground_truth, logger=logger) if proc_name in parameters: inst.__getattribute__(proc_name)(**parameters[proc_name]) else: inst.__getattribute__(proc_name)()
def gen_source_overlay(): ROOT_DIR = "/Users/popunbom/Google Drive/情報学部/研究/修士/最終発表/Thesis/img/resource" SRC_DIR = join(ROOT_DIR, "aerial_image") GT_DIR = join(ROOT_DIR, "ground_truth") ROAD_MASK_DIR = join(ROOT_DIR, "road_mask") for exp_num in [1, 2, 3, 5, 9]: eprint("Experiment Num:", exp_num) bg, fg, road_mask = [ imread_with_error( join(root_dir, f"aerial_roi{exp_num}.png") ) for root_dir in [ SRC_DIR, GT_DIR, ROAD_MASK_DIR ] ] road_mask[:, :, [0, 2]] = [0, 0] gt_overlay = hsv_blending(bg, fg) imwrite_with_error( join( GT_DIR, f"aerial_roi{exp_num}_overlay.png" ), gt_overlay ) road_mask_overlay = hsv_blending(bg, road_mask) imwrite_with_error( join( ROAD_MASK_DIR, f"aerial_roi{exp_num}_overlay.png" ), road_mask_overlay )
def proc3( src_img_path ): """ エッジ特徴量を計算し可視化し、img フォルダに結果を出力する """ src_img = cv2.imread( src_img_path, cv2.IMREAD_GRAYSCALE ) eprint( "start edge calc ... ", end="" ) features = calcEdgeFeatures( src_img ) eprint( "done !" ) dst_img = getEdgeFeatureAsImage( src_img, features ) # dst_img = cv2.resize(dst_img, (0, 0), fx=3.0, fy=3.0, interpolation=cv2.INTER_NEAREST) # print("length: ", features['length_average']) # cv2.imshow( "Test", dst_img ) # cv2.waitKey( 0 ) cv2.imwrite( "img/DEBUG1_" + str( uuid.uuid4() ) + ".png", dst_img ) return
def calc_hsv_mean_each_image(): ROOT_DIR_SRC = "./img/resource/aerial_image/fixed_histogram_v2" ROOT_DIR_GT = "./img/resource/ground_truth" # experiments = [1, 2, 3, 4, 5, 6] experiments = [5] params_mean_shift = { # "spatial_radius": 8, # "range_radius": 5, "spatial_radius": 8, "range_radius": 5, "min_density": 0 } gt_type = "GT_ORANGE" results = dict() for exp_num in experiments: src_img = imread_with_error( path.join(ROOT_DIR_SRC, f"aerial_roi{exp_num}.png")) ground_truth = imread_with_error( path.join(ROOT_DIR_GT, f"aerial_roi{exp_num}.png")) eprint( dedent(f""" Experiment Num: {exp_num} gt_type: {gt_type} """)) eprint(f"Do Mean-Shift ... ", end="") src_img = pymeanshift.segment(src_img, **params_mean_shift)[0] eprint("done") metrics = calc_hsv_metrics_by_ground_truth(src_img, ground_truth) # print(dedent(f""" # Mean (H): {means['H']} # Mean (S): {means['S']} # Mean (V): {means['V']} # """)) results[f"aerial_roi{exp_num}"] = metrics for exp_name, metrics in results.items(): print("\t".join(["EXP_NAME", exp_name])) print("\t".join(["Ch.", *list(metrics.values())[0].keys()])) for ch_name, metric in metrics.items(): # for k, v in results.items(): # print(",".join([ # k, # *metric.values() # ])) print("\t".join([str(x) for x in [ch_name, *metric.values()]])) return results
def labeling_from_mask(img_bin): """ 2値画像へのラベリング - `cv2.connectedComponents` によるラベリング - ラベリング結果は各ラベルに属する座標値の配列 Parameters ---------- img_bin : numpy.ndarray 入力画像 (2値画像) Returns ------- numpy.ndarray ラベリング結果 """ NDIM_ASSERT(img_bin, 2) assert check_if_binary_image( img_bin), "'img_bin' must consist of binary values." if img_bin.max() != 255: img_bin = (img_bin == img_bin.max()).astype(np.uint8) * 255 eprint("Labeling... ", end="") n_labels, labels = cv2.connectedComponents(img_bin) eprint("done! (Labels = {n_labels})".format(n_labels=n_labels)) eprint("Create label array ... ", end="") labels_array = np.array( [np.argwhere(labels == label_num) for label_num in range(n_labels)]) eprint("done! ") return labels_array
def gen_result_overlay(): ROOT_DIR = "/Users/popunbom/Google Drive/情報学部/研究/修士/最終発表/Thesis/img" SRC_DIR = join(ROOT_DIR, "resource/aerial_image") for exp_num in [1, 2, 3, 5, 9]: eprint("Experiment Num:", exp_num) bg = imread_with_error( join( SRC_DIR, f"aerial_roi{exp_num}.png" ) ) building_damage = imread_with_error( join( ROOT_DIR, f"result/aerial_roi{exp_num}/result.png" ) ) building_damage_overlay = hsv_blending(bg, building_damage, bg_v_scale=0.6) imwrite_with_error( join( ROOT_DIR, f"result/aerial_roi{exp_num}/result_overlay.png" ), building_damage_overlay ) road_damage = imread_with_error( join( ROOT_DIR, f"result/aerial_roi{exp_num}/road_damage/thresholded.png" ) ) # White -> Red road_damage[:, :, [0, 1]] = [0, 0] road_damage_overlay = hsv_blending(bg, road_damage) imwrite_with_error( join( ROOT_DIR, f"result/aerial_roi{exp_num}/road_damage/result_overlay.png" ), road_damage_overlay ) road_damage_wo_veg = imread_with_error( join( ROOT_DIR, f"result/aerial_roi{exp_num}/road_damage/removed_vegetation/thresholded.png" ) ) # White -> Red road_damage_wo_veg[:, :, [0, 1]] = [0, 0] road_damage_wo_veg_overlay = hsv_blending(bg, road_damage_wo_veg) imwrite_with_error( join( ROOT_DIR, f"result/aerial_roi{exp_num}/road_damage/removed_vegetation/result_overlay.png" ), road_damage_wo_veg_overlay )
# BEEP 5 TIMES (for notification) for _ in range(5): sleep(1.0) print("\a", end="", flush=True) for _ in range(5): sleep(1.0) print("\a", end="", flush=True) if __name__ == '__main__': argc, argv = len(sys.argv), sys.argv if argc != 2: eprint("usage: {prog} [experiment-json-file]".format(prog=argv[0])) sys.exit(-1) else: try: do_experiment(json.load(open(argv[1]))) except Exception as e: import traceback traceback.print_exc() with open("error.log", "wt") as f: f.write(repr(e)) # for DEBUG raise e
def to_latex_table(exp_num): ROOT_DIR = "/Users/popunbom/Google Drive/情報学部/研究/修士/最終発表/Thesis/img/result" root_dir = join(ROOT_DIR, f"aerial_roi{exp_num}") json_paths = list() json_paths.append(join(root_dir, "evaluation/scores.json")) if exists(join(root_dir, "evaluation/removed_vegetation")): json_paths.append( join(root_dir, "evaluation/removed_vegetation/scores.json")) codes = "" for json_path in json_paths: j = json.load(open(json_path)) vegetation_status = "" if "removed_vegetation" in json_path: vegetation_status = ", 植生除去あり" caption = f"精度評価 (実験{exp_num}{vegetation_status})" records = list() # Insert Header records.append([*HEADERS, *TRANSLATE["HEADERS"].values()]) # Insert Each Record for k_gt_type, v_gt_type in TRANSLATE["GT_TYPE"].items(): for k_method, v_method in TRANSLATE["METHODS"].items(): records.append([ v_gt_type, v_method, *[ j[k_method][k_gt_type]["Score"][k] for k in TRANSLATE["HEADERS"].keys() ] ]) # Row-cell merging first_row = [records[i][0] for i in range(1, len(records))] c = Counter(first_row) prev = None for i, r in enumerate(first_row, start=1): if prev is None: prev = r records[i][0] = "\\multirow{{{n}}}{{*}}{{{value}}}".format( n=c[r], value=r) else: if r == prev: records[i][0] = "" else: prev = r records[i][0] = "\\multirow{{{n}}}{{*}}{{{value}}}".format( n=c[r], value=r) code = dedent(""" \\begin{{table}}[H] \\begin{{center}} \\caption{{{caption}}} \\label{{tab:{caption}}} \\resizebox{{\\textwidth}}{{!}}{{ \\begin{{tabular}}{{clrrrrrrr}} \\hline \\hline {headers} \\\\ \\hline \\hline {records} \\\\ \\hline \\hline \\end{{tabular}} }} \\end{{center}} \\end{{table}} """.format( caption=caption, headers=" & ".join([f"\\textbf{{{h}}}" for h in records[0]]), records=" \\\\\n".join([ " " * 26 + " & ".join( [f"{x:.1f}" if isinstance(x, float) else x for x in row]) for row in records[1:] ]))) codes += code + "\n" print(codes) pyperclip.copy(codes) eprint("Copied to clipboard")
def eval_by_utilize_methods(): ROOT_DIR_RESULT = "/Users/popunbom/Google Drive/情報学部/研究/修士/最終発表/Thesis/img/result" SPLIT_PATTERNS = { "MEAN_SHIFT" : (0,), "ANGLE_VARIANCE" : (1,), "PIXEL_CLASSIFY" : (2,), "MEAN_SHIFT_AND_ANGLE_VARIANCE" : (0, 1), "MEAN_SHIFT_AND_PIXEL_CLASSIFY" : (0, 2), "ANGLE_VARIANCE_AND_PIXEL_CLASSIFY" : (1, 2), "MEAN_SHIFT_AND_ANGLE_VARIANCE_AND_PIXEL_CLASSIFY": (0, 1, 2) } result_paths = sorted([ join(dir_path, "result.png") for (dir_path, dir_names, file_names) in walk(ROOT_DIR_RESULT) if "result.png" in file_names ]) for result_path in result_paths: exp_num, = re.match( r".*aerial_roi([0-9]).*", result_path ).groups() result_src = imread_with_error( result_path ) gt_src = imread_with_error( join( ROOT_DIR_GT, f"aerial_roi{exp_num}.png" ) ) result_dir = join( dirname(result_path), "evaluation" ) if not exists(result_dir): makedirs(result_dir) NDARRAY_ASSERT(result_src, ndim=3) print("File:", result_path) print( np.unique( result_src.reshape(result_src.shape[0] * result_src.shape[1], result_src.shape[2]), axis=0 ) ) # Use Vegetation Mask OPTIONS = ["NORMAL"] path_vegetation_mask = join( ROOT_DIR_VEG_MASK, f"aerial_roi{exp_num}.png" ) vegetation_mask = None if exists(path_vegetation_mask): vegetation_mask = imread_with_error( path_vegetation_mask, cv2.IMREAD_GRAYSCALE ).astype(bool) OPTIONS.append("REMOVED_VEGETATION") scores = dict() for option in OPTIONS: for name, channels in SPLIT_PATTERNS.items(): eprint("Evaluation:", name) result = np.zeros(result_src.shape[:2], dtype=np.int16) for channel in channels: result += (result_src[:, :, channel] != 0) result = result.astype(bool) if option == "NORMAL": save_dir = result_dir elif option == "REMOVED_VEGETATION": result = result & ~vegetation_mask save_dir = join( result_dir, "removed_vegetation" ) if not exists(save_dir): makedirs(save_dir) imwrite_with_error( join(save_dir, name.replace(" & ", "_and_") + ".png"), (result * 255).astype(np.uint8) ) scores[name] = dict() for gt_type in ["GT_BOTH", "GT_ORANGE", "GT_RED"]: ground_truth = None if gt_type == "GT_BOTH": ground_truth = np.all( (gt_src == C_RED) | (gt_src == C_ORANGE), axis=2 ) elif gt_type == "GT_RED": ground_truth = np.all( gt_src == C_RED, axis=2 ) elif gt_type == "GT_ORANGE": ground_truth = np.all( gt_src == C_ORANGE, axis=2 ) cm, metrics = evaluation_by_confusion_matrix( result, ground_truth ) scores[name][gt_type] = { "Confusion Matrix": cm, "Score" : metrics } json.dump( scores, open(join(save_dir, "scores.json"), "w"), ensure_ascii=False, sort_keys=True, indent="\t" )
def only_overlay_image(): result_dirs = sum([ [ join( ROOT_DIR_RESULT, gt_type, d ) for d in listdir( join( ROOT_DIR_RESULT, gt_type ) ) if isdir( join( ROOT_DIR_RESULT, gt_type, d ) ) ] # for gt_type in ["GT_BOTH", "GT_ORANGE", "GT_RED"] for gt_type in ["GT_BOTH"] ], []) result_dirs = sorted(result_dirs) for result_dir in result_dirs: gt_type, experiment_num = re.match( r".*/GT_(.*)/aerial_roi([0-9]).*", result_dir ).groups() eprint(dedent(f""" Experiment Num: {experiment_num} GT_TYPE: GT_{gt_type} """)) # Load: ground_truth ground_truth = imread_with_error( join( ROOT_DIR_GT, f"aerial_roi{experiment_num}.png" ) ) # Load: source src = imread_with_error( join( ROOT_DIR_SRC, f"aerial_roi{experiment_num}.png" ) ) src_gs = cv2.cvtColor( cv2.cvtColor( src, cv2.COLOR_BGR2GRAY ), cv2.COLOR_GRAY2BGR ) if gt_type == "BOTH": ground_truth = np.all( (ground_truth == C_RED) | (ground_truth == C_ORANGE), axis=2 ) elif gt_type == "RED": ground_truth = np.all( ground_truth == C_RED, axis=2 ) elif gt_type == "ORANGE": ground_truth = np.all( ground_truth == C_ORANGE, axis=2 ) ground_truth = (ground_truth * 255).astype(np.uint8) Z = np.zeros( ground_truth.shape[:2], dtype=np.uint8 ) if "edge_angle_variance_with_hpf" in result_dir: fd_angle_var = imread_with_error( join( result_dir, "edge_angle_variance/angle_variance.tiff" ), cv2.IMREAD_UNCHANGED ) fd_angle_var = (cm.get_cmap("jet")( fd_angle_var / fd_angle_var.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] fd_hpf = imread_with_error( join( result_dir, "high_pass_filter/HPF_gray.tiff" ), cv2.IMREAD_UNCHANGED ) fd_hpf = (cm.get_cmap("jet")( fd_hpf / fd_hpf.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] # Overlay fd_overlay_angle_var = hsv_blending( src_gs, fd_angle_var ) # fd_overlay_angle_var = overlay.do_gimp_overlay( # src_gs, fd_angle_var, overlay.FUNC_GRAIN_MERGE # ) fd_overlay_hpf = hsv_blending( src_gs, fd_hpf ) # fd_overlay_hpf = overlay.do_gimp_overlay( # src_gs, fd_hpf, overlay.FUNC_GRAIN_MERGE # ) write_images( result_dir, [ ("fd_overlay_angle_var", fd_overlay_angle_var), ("fd_overlay_hpf", fd_overlay_hpf) ] ) elif "edge_angle_variance" in result_dir: fd_angle_var = imread_with_error( join( result_dir, "edge_angle_variance/angle_variance.tiff" ), cv2.IMREAD_UNCHANGED ) fd_angle_var = (cm.get_cmap("jet")( fd_angle_var / fd_angle_var.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] # Overlay fd_overlay_angle_var = hsv_blending( src_gs, fd_angle_var ) # fd_overlay_angle_var = overlay.do_gimp_overlay( # src_gs, fd_angle_var, overlay.FUNC_GRAIN_MERGE # ) write_images( result_dir, [ ("fd_overlay_angle_var", fd_overlay_angle_var) ] ) elif "edge_pixel_classify" in result_dir: fd = imread_with_error( join( result_dir, "features.tiff" ), cv2.IMREAD_UNCHANGED ) fd = (cm.get_cmap("jet")( fd / fd.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] # Overlay fd_overlay = hsv_blending( src_gs, fd ) # fd_overlay = overlay.do_gimp_overlay( # src_gs, fd, overlay.FUNC_GRAIN_MERGE # ) write_images( result_dir, [ ("fd_overlay", fd_overlay) ] )
def gen_study_data(): result_dirs = sum([ [ join( ROOT_DIR_RESULT, gt_type, d ) for d in listdir( join( ROOT_DIR_RESULT, gt_type ) ) if isdir( join( ROOT_DIR_RESULT, gt_type, d ) ) ] # for gt_type in ["GT_BOTH", "GT_ORANGE", "GT_RED"] for gt_type in ["GT_BOTH"] ], []) result_dirs = sorted(result_dirs) pprint(result_dirs[1:2]) for result_dir in result_dirs: gt_type, experiment_num = re.match( r".*/GT_(.*)/aerial_roi([0-9]).*", result_dir ).groups() eprint(dedent(f""" Experiment Num: {experiment_num} GT_TYPE: GT_{gt_type} """)) # Load: ground_truth ground_truth = imread_with_error( join( ROOT_DIR_GT, f"aerial_roi{experiment_num}.png" ) ) # Load: source src = imread_with_error( join( ROOT_DIR_SRC, f"aerial_roi{experiment_num}.png" ) ) src_gs = cv2.cvtColor( cv2.cvtColor( src, cv2.COLOR_BGR2GRAY ), cv2.COLOR_GRAY2BGR ) if gt_type == "BOTH": ground_truth = np.all( (ground_truth == C_RED) | (ground_truth == C_ORANGE), axis=2 ) elif gt_type == "RED": ground_truth = np.all( ground_truth == C_RED, axis=2 ) elif gt_type == "ORANGE": ground_truth = np.all( ground_truth == C_ORANGE, axis=2 ) ground_truth = (ground_truth * 255).astype(np.uint8) Z = np.zeros( ground_truth.shape[:2], dtype=np.uint8 ) if "meanshift_and_color_thresholding" in result_dir: result = (imread_with_error( join( result_dir, "building_damage_fixed.tiff" ), cv2.IMREAD_UNCHANGED ) * 255).astype(np.uint8) confusion_matrix = np.dstack( [result, ground_truth, result] ) missing = confusion_matrix.copy() missing[~np.all(missing == C_GREEN, axis=2)] = [0, 0, 0] wrong = confusion_matrix.copy() wrong[~np.all(wrong == C_MAGENTA, axis=2)] = [0, 0, 0] # Extract missing_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(missing == C_GREEN, axis=2) ) missing_extracted_with_color = hsv_blending( src_gs, missing ) wrong_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(wrong == C_MAGENTA, axis=2) ) wrong_extracted_with_color = hsv_blending( src_gs, wrong ) write_images( result_dir, [ ("confusion_matrix", confusion_matrix), ("missing", missing), ("wrong", wrong), ("missing_extracted", missing_extracted), ("missing_extracted_with_color", missing_extracted_with_color), ("wrong_extracted", wrong_extracted), ("wrong_extracted_with_color", wrong_extracted_with_color) ] ) elif "edge_angle_variance_with_hpf" in result_dir: result = (imread_with_error( join( result_dir, "building_damage.tiff" ), cv2.IMREAD_UNCHANGED ) * 255).astype(np.uint8) fd_angle_var = imread_with_error( join( result_dir, "edge_angle_variance/angle_variance.tiff" ), cv2.IMREAD_UNCHANGED ) fd_angle_var = (cm.get_cmap("jet")( fd_angle_var / fd_angle_var.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] fd_hpf = imread_with_error( join( result_dir, "high_pass_filter/HPF_gray.tiff" ), cv2.IMREAD_UNCHANGED ) fd_hpf = (cm.get_cmap("jet")( fd_hpf / fd_hpf.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] # Generate Image of Confusion Matrix confusion_matrix = np.dstack( [result, ground_truth, result] ) missing = confusion_matrix.copy() missing[~np.all(missing == C_GREEN, axis=2)] = [0, 0, 0] wrong = confusion_matrix.copy() wrong[~np.all(wrong == C_MAGENTA, axis=2)] = [0, 0, 0] # Overlay fd_overlay_angle_var = hsv_blending( src_gs, fd_angle_var ) # fd_overlay_angle_var = overlay.do_gimp_overlay( # src_gs, fd_angle_var, overlay.FUNC_GRAIN_MERGE # ) fd_overlay_hpf = hsv_blending( src_gs, fd_hpf ) # fd_overlay_hpf = overlay.do_gimp_overlay( # src_gs, fd_hpf, overlay.FUNC_GRAIN_MERGE # ) # Extract missing_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(missing == C_GREEN, axis=2) ) missing_extracted_with_color = hsv_blending( src_gs, missing ) missing_extracted_by_anglevar = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd_angle_var, np.all(missing == C_GREEN, axis=2) ) missing_extracted_by_hpf = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd_hpf, np.all(missing == C_GREEN, axis=2) ) wrong_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(wrong == C_MAGENTA, axis=2) ) wrong_extracted_with_color = hsv_blending( src_gs, wrong ) wrong_extracted_by_anglevar = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd_angle_var, np.all(wrong == C_MAGENTA, axis=2) ) wrong_extracted_by_hpf = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd_hpf, np.all(wrong == C_MAGENTA, axis=2) ) write_images( result_dir, [ ("fd_overlay_angle_var", fd_overlay_angle_var), ("fd_overlay_hpf", fd_overlay_hpf), ("confusion_matrix", confusion_matrix), ("missing", missing), ("wrong", wrong), ("missing_extracted", missing_extracted), ("missing_extracted_with_color", missing_extracted_with_color), ("missing_extracted_by_anglevar", missing_extracted_by_anglevar), ("missing_extracted_by_hpf", missing_extracted_by_hpf), ("wrong_extracted", wrong_extracted), ("wrong_extracted_with_color", wrong_extracted_with_color), ("wrong_extracted_by_anglevar", wrong_extracted_by_anglevar), ("wrong_extracted_by_hpf", wrong_extracted_by_hpf) ] ) elif "edge_angle_variance" in result_dir: result = (imread_with_error( join( result_dir, "building_damage.tiff" ), cv2.IMREAD_UNCHANGED ) * 255).astype(np.uint8) fd_angle_var = imread_with_error( join( result_dir, "edge_angle_variance/angle_variance.tiff" ), cv2.IMREAD_UNCHANGED ) fd_angle_var = (cm.get_cmap("jet")( fd_angle_var / fd_angle_var.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] # Generate Image of Confusion Matrix confusion_matrix = np.dstack( [result, ground_truth, result] ) missing = confusion_matrix.copy() missing[~np.all(missing == C_GREEN, axis=2)] = [0, 0, 0] wrong = confusion_matrix.copy() wrong[~np.all(wrong == C_MAGENTA, axis=2)] = [0, 0, 0] # Overlay fd_overlay_angle_var = hsv_blending( src_gs, fd_angle_var ) # fd_overlay_angle_var = overlay.do_gimp_overlay( # src_gs, fd_angle_var, overlay.FUNC_GRAIN_MERGE # ) # Extract missing_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(missing == C_GREEN, axis=2) ) missing_extracted_with_color = hsv_blending( src_gs, missing ) missing_extracted_by_anglevar = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd_angle_var, np.all(missing == C_GREEN, axis=2) ) wrong_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(wrong == C_MAGENTA, axis=2) ) wrong_extracted_with_color = hsv_blending( src_gs, wrong ) wrong_extracted_by_anglevar = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd_angle_var, np.all(wrong == C_MAGENTA, axis=2) ) write_images( result_dir, [ ("fd_overlay_angle_var", fd_overlay_angle_var), ("confusion_matrix", confusion_matrix), ("missing", missing), ("wrong", wrong), ("missing_extracted", missing_extracted), ("missing_extracted_with_color", missing_extracted_with_color), ("missing_extracted_by_anglevar", missing_extracted_by_anglevar), ("wrong_extracted", wrong_extracted), ("wrong_extracted_with_color", wrong_extracted_with_color), ("wrong_extracted_by_anglevar", wrong_extracted_by_anglevar) ] ) elif "edge_pixel_classify" in result_dir: result = (imread_with_error( join( result_dir, "building_damage.tiff" ), cv2.IMREAD_UNCHANGED ) * 255).astype(np.uint8) fd = imread_with_error( join( result_dir, "features.tiff" ), cv2.IMREAD_UNCHANGED ) fd = (cm.get_cmap("jet")( fd / fd.max() ) * 255).astype(np.uint8)[:, :, [2, 1, 0]] # Overlay fd_overlay = hsv_blending( src_gs, fd ) # fd_overlay = overlay.do_gimp_overlay( # src_gs, fd, overlay.FUNC_GRAIN_MERGE # ) # Generate Image of Confusion Matrix confusion_matrix = np.dstack( [result, ground_truth, result] ) missing = confusion_matrix.copy() missing[~np.all(missing == C_GREEN, axis=2)] = [0, 0, 0] wrong = confusion_matrix.copy() wrong[~np.all(wrong == C_MAGENTA, axis=2)] = [0, 0, 0] # Extract missing_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(missing == C_GREEN, axis=2) ) missing_extracted_with_color = hsv_blending( src_gs, missing ) missing_extracted_by_fd = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd, np.all(missing == C_GREEN, axis=2) ) wrong_extracted = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), src, np.all(wrong == C_MAGENTA, axis=2) ) wrong_extracted_with_color = hsv_blending( src_gs, wrong ) wrong_extracted_by_fd = merge_arrays_by_mask( (src_gs * CONT).astype(np.uint8), fd, np.all(wrong == C_MAGENTA, axis=2) ) write_images( result_dir, [ ("fd_overlay", fd_overlay), ("confusion_matrix", confusion_matrix), ("missing", missing), ("wrong", wrong), ("missing_extracted", missing_extracted), ("missing_extracted_with_color", missing_extracted_with_color), ("missing_extracted_by_fd", missing_extracted_by_fd), ("wrong_extracted", wrong_extracted), ("wrong_extracted_with_color", wrong_extracted_with_color), ("wrong_extracted_by_fd", wrong_extracted_by_fd) ] )
def merge_regions_by_score(self, entropy_calc_mode='rgb', condition_to_merge="score < 0.5"): """ エントロピーに基づいた領域統合 - 隣接領域間のエントロピー差分 (score) を計算 - score が 引数 condition_to_merge の条件を 満たす場合、領域統合が行われる Parameters ---------- entropy_calc_mode : str 関数 calc_entropy_all の mode 引数に対応する condition_to_merge : str 領域統合を行う条件式 Returns ------- """ TYPE_ASSERT(entropy_calc_mode, str) TYPE_ASSERT(condition_to_merge, str) scores = self.calc_entropy_all(mode=entropy_calc_mode) try: score = 1.0 eval(condition_to_merge) except Exception as e: eprint( "Catch exception while evaluation 'condition_to_merge'\ncondition_to_merge: '{condition_to_merge}'" .format(condition_to_merge=condition_to_merge)) print(e) f = open("merged_regions.csv", "wt") for label_1, v in scores.items(): for label_2, score in v.items(): if eval(condition_to_merge): self.merge_region(label_1, label_2) f.close() # Re-Labeling # merged_labels = self.merged_labels # merged_labels[merged_labels == self.LINE_LABEL_VAL] = self.LINE_PIXEL_VAL # merged_labels[merged_labels != self.LINE_PIXEL_VAL] = np.bitwise_not(self.LINE_PIXEL_VAL) # Opening lines # kernel = np.array([ # [1, 1, 1], # [1, 1, 1], # [1, 1, 1] # ], dtype=np.uint8) # merged_labels = cv2.morphologyEx(merged_labels.astype(np.uint8), cv2.MORPH_CLOSE, kernel) # _, self.merged_labels = cv2.connectedComponents( # np.bitwise_not( merged_labels.astype(np.uint8) ), # connectivity=4 # ) if self.is_logging: self.logger.logging_img(self._labels, "labels") if self.is_logging: self.logger.logging_img(self._merged_labels, "labels_merged")
def do_experiment(experiment_parameters): """ 実験ファイル (.json) に基づく実験を実行 Parameters ---------- experiment_parameters : dict 実験ファイルデータ """ def extract_parameters(parameters, case_num, procedure_name): """ 各手法におけるパラメータを抽出 Parameters ---------- parameters : list of dict パラメータリスト case_num : int 実験番号 procedure_name :str 手法名称 Returns ------- dict 抽出された引数リスト """ parameters_by_case = [ p for p in parameters if p["experiment_num"] == case_num ] if parameters_by_case: parameters_by_case = parameters_by_case[0] if procedure_name in parameters_by_case: return parameters_by_case[procedure_name] return dict() C_RED = [0, 0, 255] C_ORANGE = [0, 127, 255] p = experiment_parameters for case_num in p["options"]["experiments"]: # Check files existence img_paths = [ path.join(p["resource_dirs"][img_type], "aerial_roi{n}.png".format(n=case_num)) for img_type in ["aerial_image", "ground_truth"] ] for img_path in img_paths: if not exists(img_path): raise FileNotFoundError( "Not found image file -- {path}".format(path=img_path)) src_img, gt_img = [ cv2.imread(img_path, cv2.IMREAD_COLOR) for img_path in img_paths ] for gt_opt in p["options"]["ground_truth"]: ground_truth = None if gt_opt == "GT_BOTH": ground_truth = np.all((gt_img == C_RED) | (gt_img == C_ORANGE), axis=2) elif gt_opt == "GT_RED": ground_truth = np.all(gt_img == C_RED, axis=2) elif gt_opt == "GT_ORANGE": ground_truth = np.all(gt_img == C_ORANGE, axis=2) for procedure_name in p["options"]["procedures"]: eprint("Experiment Procedure:", procedure_name) logger = ImageLogger(p["resource_dirs"]["logging"], prefix="aerial_roi{n}".format(n=case_num), suffix=procedure_name + "_no_norm_" + gt_opt) inst = BuildingDamageExtractor(src_img, ground_truth, logger=logger) inst.__getattribute__(procedure_name)(**extract_parameters( p["parameters"], case_num, procedure_name)) # BEEP 5 TIMES (for notification) for _ in range(5): sleep(1.0) print("\a", end="", flush=True) for _ in range(5): sleep(1.0) print("\a", end="", flush=True)
def eval_road_damage(): ROOT_DIR_RESULT = "/Users/popunbom/.tmp/EQDmgAnalyzr/detect_road_damage_v2" dirs = [ join(ROOT_DIR_RESULT, d) for d in listdir(ROOT_DIR_RESULT) if isdir(join(ROOT_DIR_RESULT, d)) ] for d in dirs: print(d) exp_num, = re.match( r".*aerial_roi([0-9]).*", d ).groups() eprint(dedent(f""" Experiment Num: {exp_num} """)) road_mask = imread_with_error( join( ROOT_DIR_ROAD_MASK, f"aerial_roi{exp_num}.png" ), cv2.IMREAD_GRAYSCALE ).astype(bool) # GT: GT_BOTH ground_truth = imread_with_error( join( ROOT_DIR_GT, f"aerial_roi{exp_num}.png" ), cv2.IMREAD_GRAYSCALE ).astype(bool) result_dirs = [d] if exists(join(d, "removed_vegetation")): result_dirs.append( join(d, "removed_vegetation") ) for result_dir in result_dirs: result = imread_with_error( join(result_dir, "thresholded.png"), cv2.IMREAD_GRAYSCALE ).astype(bool) result = result[road_mask == True] ground_truth_masked = ground_truth[road_mask == True] # ground_truth[road_mask == False] = False cm, metrics = evaluation_by_confusion_matrix( result, ground_truth_masked ) result = { "Confusion Matrix": cm, "Score": metrics } json.dump( result, open( join(result_dir, "scores.json"), "w" ), ensure_ascii=False, sort_keys=True, indent="\t" )
def switch_backend(new_backend): old_backend = plt.get_backend() plt.switch_backend(new_backend) eprint("Matplotlib: Switch Backend from {0} to {1}".format( old_backend, new_backend))
def compute_by_window(imgs, func, window_size=16, step=2, dst_dtype=np.float32, n_worker=12): """ 画像を一部を切り取り、func 関数で行った計算結果を 返却する Parameters ---------- imgs : numpy.ndarray or tuple of numpy.ndarray 入力画像 tuple で複数画像を与える場合、各画像に対して 同じ領域を切り取り、処理を行うため、各画像の 縦、横サイズは一致している必要がある func : callable object 切り取った画像の一部に対して何らかの計算を行う 関数。引数として画像の一部が渡される。 window_size : int or tuple of int 画像を切り取るサイズ。 int を指定した場合は、縦横同じサイズで切り取る。 tuple(int, int) を指定した場合は、縦横で異なったサイズ で切り取り、指定する順序は ndarray の次元に対応する step : int or tuple of int 切り取り間隔 int を指定した場合は、縦横同じ間隔を開けて処理をする tuple(int, int) を指定した場合は、縦横で異なった間隔 を開けて処理を行い、指定する順序は ndarray の次元に 対応する dst_dtype : type, default numpy.float32 返却値のデータ型 n_worker : int, default 4 並列するプロセス数 Returns ------- numpy.ndarray 各切り取り画像に対する処理結果の行列 """ # TYPE ASSERTION TYPE_ASSERT(imgs, [np.ndarray, tuple]) TYPE_ASSERT(window_size, [int, tuple]) TYPE_ASSERT(step, [int, tuple]) TYPE_ASSERT(dst_dtype, type) TYPE_ASSERT(n_worker, int) if isinstance(imgs, np.ndarray): imgs = tuple([imgs]) for img in imgs: TYPE_ASSERT(img, np.ndarray) for i in range(len(imgs) - 1): SAME_SHAPE_ASSERT(imgs[i], imgs[i + 1]) n_imgs = len(imgs) height, width = imgs[0].shape[:2] assert callable(func) and n_args(func) >= n_imgs, \ "argument 'func' must be callable object which has {0} argument at least. \n".format(n_imgs) + \ " ( num of argumets of 'func' depends on argument 'imgs')" if isinstance(step, int): step = tuple([step] * 2) if isinstance(window_size, int): window_size = tuple([window_size] * 2) s_i, s_j = step w_w, w_h = window_size results_shape = ceil(height / s_i), ceil(width / s_j) # Add padding to input images eprint("Add padding ... ") imgs = [ np.pad( img, pad_width=[ tuple([w_w // 2]), tuple([w_h // 2]), ] + [] if img.ndim == 2 else [tuple([0])], mode="constant", constant_values=0 ) for img in imgs ] if n_worker == 1: results = np.ndarray(results_shape, dtype=dst_dtype) for ii, i in tqdm(enumerate(range(w_h // 2, height + w_h // 2, s_i)), total=results_shape[0]): for jj, j in tqdm(enumerate(range(w_w // 2, width + w_w // 2, s_j)), total=results_shape[1], leave=False): rois = [ img[ get_window_rect( img.shape, center=(j, i), wnd_size=(w_w, w_h), ret_type="slice" ) ] for img in imgs ] results[ii][jj] = func(*rois) else: global _func global _callee _func = func def _callee(_imgs, _func, _width, _s_j, _w_w, _n_loop): _worker_id = current_process()._identity[0] _desc = f"Worker #{_worker_id:3d}" _results = list() for jj, j in tqdm(enumerate(range(_w_w // 2, _width + _w_w // 2, _s_j)), total=_n_loop, desc=_desc, position=_worker_id, leave=False): _rois = [ # _roi[:, j:j + _w_w] _roi[ get_window_rect( _roi.shape, center=(j, -1), wnd_size=(_w_w, -1), ret_type="slice" ) ] for _roi in _imgs ] _results.append(_func(*_rois)) return _results progress_bar = tqdm(total=results_shape[0], position=0) def _update_progressbar(arg): progress_bar.update() cp = CustomPool() pool = cp.Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),)) results = list() for ii, i in enumerate(range(w_h // 2, height + w_h // 2, s_i)): rois = [ img[ get_window_rect( img.shape, center=(-1, i), wnd_size=(-1, w_h), ret_type="slice" ) ] for img in imgs ] results.append( pool.apply_async( _callee, args=(rois, func, width, s_j, w_h, results_shape[1]), callback=_update_progressbar ) ) pool.close() pool.join() cp.update() results = np.array( [result.get() for result in results], dtype=dst_dtype ) return results
def calc_score_all(self, distance=5): relation = self.relations img = self.src_img edge = EdgeProcedures(self.src_img) edge_angle = edge._calc_angle() scores = dict() for label_1 in relation.keys(): for label_2, connected_points in relation[label_1].items(): eprint( "\rCalculating Score [ Label: ({label_1}, {label_2}) ] ..." .format(label_1=label_1, label_2=label_2), end="") if label_1 not in scores: scores[label_1] = dict() connected_points = list(connected_points) angle_of_points = np.array( [edge_angle[tuple(point)] for point in connected_points], dtype=np.float32) pts_1, pts_2 = EdgeProcedures.calc_end_points( points=connected_points, deg_angles=angle_of_points, distance=distance) pts = np.stack([pts_1, pts_2], axis=1) # Filtering if in range coordinates pts_filtered = pts[ ((0 <= pts[:, 0, 0]) & (pts[:, 0, 0] < img.shape[0])) & ((0 <= pts[:, 0, 1]) & (pts[:, 0, 1] < img.shape[1])) & ((0 <= pts[:, 1, 0]) & (pts[:, 1, 0] < img.shape[0])) & ((0 <= pts[:, 1, 1]) & (pts[:, 1, 1] < img.shape[1]))] val = np.zeros(tuple((*pts_filtered.shape[:2], 3)), dtype=np.int32) val[:, 0] = [ cv2.cvtColor(img[tuple(pt)].reshape(1, 1, 3), cv2.COLOR_BGR2HSV)[0, 0].astype(np.int32) for pt in pts_filtered[:, 0] ] val[:, 1] = [ cv2.cvtColor(img[tuple(pt)].reshape(1, 1, 3), cv2.COLOR_BGR2HSV)[0, 0].astype(np.int32) for pt in pts_filtered[:, 1] ] # for pt_1, pt_2 in zip( pts_1, pts_2 ): # val_1 = cv2.cvtColor( img[tuple( pt_1 )].reshape( 1, 1, 3 ), cv2.COLOR_BGR2HSV )[0, 0].astype( np.int32 ) # val_2 = cv2.cvtColor( img[tuple( pt_2 )].reshape( 1, 1, 3 ), cv2.COLOR_BGR2HSV )[0, 0].astype( np.int32 ) # # average_of_difference += np.abs( val_1 - val_2 ) scores[label_1][label_2] = np.mean( np.sum(np.abs(val[:, 0] - val[:, 1]), axis=1)) # return cv2.cvtColor( img[tuple(x)].reshape( 1, 1, 3 ), cv2.COLOR_BGR2HSV )[0, 0].astype( np.int32 ) return scores