def run_folder(folder): files = glob.glob(os.path.join(folder, "*.tif")) folder_out = r"C:\Users\Neil\Desktop\results" for wafer_type in 'fully_impure', 'transition', 'middle', 'edge', 'corner': folder = os.path.join(folder_out, wafer_type) if not os.path.isdir(folder): os.makedirs(folder) parameters.SLOPE_MULTI_WAFER = True parameters.BORDER_ERODE = 3 parameters.MIN_IMPURE_AREA = 0.01 results = [] for e, fn in enumerate(files): print "%s (%d/%d)" % (fn, e + 1, len(files)) f, cropped, rgb = run_single(fn, display=False, downsize=False) results.append(f) wafer_type = multi_wafer.WaferType.types[f['wafer_type']] folder = os.path.join(folder_out, wafer_type) fn_root = os.path.splitext(os.path.split(fn)[1])[0] fn_out = os.path.join(folder, fn_root + '_0.png') ip.save_image(fn_out, cropped) fn_out = os.path.join(folder, fn_root + '_2.png') ip.save_image(fn_out, rgb) df = pd.DataFrame(results) df.to_csv(os.path.join(folder_out, "results.csv"))
def main(readfilename, header, transmitted=True, writefilename='images/decompressed_img.jpg', start_index = 0, end_index = 0): """ Recreates image from transmitted data """ data = read_from_file(readfilename) data = data_processing.decomplexize_data(data) print('decomplexized') if end_index != 0: data = data[start_index:end_index] if transmitted: data = data_processing.estimate_transmitted_signal(data) else: data = np.real(data) print('estimated transmitted signal') data = data_processing.unexpand_and_correct(data) print('unexpanded') [dimensions, encoded_img, decode_dict] = data_processing.data_from_array(data, header) print('data to array') decode_dict = data_processing.binary_to_dictionary(decode_dict) img_1d = puffman.puffman(encoded_img, decode_dict) print('LEN decoded img', len(img_1d)) img = puffman.to_array(img_1d, dimensions) image_processing.save_image(img, writefilename) print 'done' return [decode_dict, img]
def try_frame_difference(): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(0) + ".png") depth_im = image_processing.load_image("falling balls and cylinder", "depth_" + str(0) + ".png", "depth") start = time.time() frame_difference = FrameDifference(depth_im / 255, rgb_im / 255, 0.3, 0.005) print("initialization: ", time.time() - start) for i in range(5): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(i) + ".png") depth_im = image_processing.load_image("falling balls and cylinder", "depth_" + str(i) + ".png", "depth") start = time.time() frame_difference.current_depth = depth_im / 255 frame_difference.current_rgb = rgb_im / 255 mask = frame_difference.subtraction_mask() mask = frame_difference.create_mask(mask) print(time.time() - start) mask = mask * 255 all_masks = np.zeros_like(depth_im) all_masks = all_masks.astype(float) for j in range(len(mask)): all_masks += mask[j].astype(float) image_processing.save_image(all_masks / 255, "Results/Frame difference", i, "mask")
def try_DEVB(): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(0) + ".png") depth_im = image_processing.load_image("falling balls and cylinder", "depth_" + str(0) + ".png", "depth") start = time.time() devb = DEVB(rgb_im=rgb_im / 255, depth_im=depth_im / 255, number_of_samples=10, time_factor=16) print(time.time() - start) for i in range(5): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(i) + ".png") depth_im = image_processing.load_image("falling balls and cylinder", "depth_" + str(i) + ".png", "depth") start = time.time() devb.set_images(rgb_im / 255, depth_im / 255) devb.set_mask() print(time.time() - start) mask = devb.mask image_processing.save_image(mask, "Results/DEVB", i, "mask")
def try_RGB_MoG(): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(0) + ".png") start = time.time() mog = RGB_MoG(rgb_im, number_of_gaussians=3) print("initialization: ", time.time() - start) for i in range(5): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(i) + ".png") start = time.time() mask = mog.set_mask(rgb_im) print("frame updating: ", time.time() - start) image_processing.save_image(mask / 255, "Results/RGB MoG", i, "mask")
def analyse_module(features): im = np.ascontiguousarray(features["_im_ratio_cropped"]) h, w = im.shape # mask out rows and columns border = 20 border_cols = features['_divisions_cols'] - features['_divisions_cols'][0] for c in border_cols: im[:, max(c - border, 0):min(c + border + 1, w)] = 0 border_rows = features['_divisions_rows'] - features['_divisions_rows'][0] for r in border_rows: im[max(r - border, 0):min(r + border + 1, h), :] = 0 # scale so max is around scale = ((2**15) / im.max()) im *= scale f = {} hist = ip.histogram_percentiles(im, f, skip_zero=True) hist = hist[:f['hist_percentile_99.9']] hist_norm = hist / hist.max() lower = np.where(hist_norm > 0.02)[0][0] upper = 2 * f['hist_peak'] - lower high_vals = (hist[upper:].sum() / float(hist.sum())) features['module_bright_area_fraction'] = high_vals if False: print "%s: %0.01f%%" % (features['fn'], high_vals) ip.print_metrics(f) plt.figure() plt.xlabel("PL/EL ratio") plt.ylabel("Count") plt.title("Above threshold: %0.02f%%" % high_vals) xs = np.arange(len(hist)) / float(scale) plt.plot(xs, hist) plt.vlines([upper / float(scale)], ymin=0, ymax=hist.max()) if False: plt.savefig( os.path.join(r"C:\Users\Neil\Desktop\M1\hist", features['fn'] + '_1.png')) im = features["_im_ratio_cropped"] im[im > f['hist_percentile_99']] = f['hist_percentile_99'] ip.save_image( os.path.join(r"C:\Users\Neil\Desktop\M1\hist", features['fn'] + '_0.png'), im) else: plt.show() view = ImageViewer(im[::3, ::3]) view.show() sys.exit()
def save_images_from_VREP(path="3d_map/"): client_id = vrep_functions.vrep_connection() vrep_functions.vrep_start_sim(client_id) kinect_rgb_id = vrep_functions.get_object_id(client_id, 'kinect_rgb') kinect_depth_id = vrep_functions.get_object_id(client_id, 'kinect_depth') depth_im, rgb_im = vrep_functions.vrep_get_kinect_images( client_id, kinect_rgb_id, kinect_depth_id) depth_im, rgb_im = np.flip(depth_im, (0)), np.flip(rgb_im, (0)) vrep_functions.vrep_stop_sim(client_id) image_processing.save_image(rgb_im, path, 0, "room_rgb") image_processing.save_image(depth_im, path, 0, "room_depth") return depth_im, rgb_im
def point_cloud_from_VREP(): import vrep_functions import image_processing """Function for checking if vrep_functions and PointsObject are working fine""" client_id = vrep_functions.vrep_connection() vrep_functions.vrep_start_sim(client_id) kinect_rgb_id = vrep_functions.get_object_id(client_id, 'kinect_rgb') kinect_depth_id = vrep_functions.get_object_id(client_id, 'kinect_depth') depth_im, rgb_im = vrep_functions.vrep_get_kinect_images( client_id, kinect_rgb_id, kinect_depth_id) image_processing.save_image(rgb_im, "preDiploma_PC/", 0, "rgb_box_") image_processing.save_image(depth_im, "preDiploma_PC/", 0, "depth_box_") print(depth_im.shape, rgb_im.shape) vrep_functions.vrep_stop_sim(client_id) depth, rgb = image_processing.calculate_point_cloud(rgb_im, depth_im) current_object = PointsObject() current_object.add_points(depth, rgb) current_object.save_all_points("preDiploma_PC/", "box")
def try_ViBE(): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(0) + ".png") start = time.time() vibe = ViBЕ(rgb_im=rgb_im / 255, number_of_samples=10, threshold_r=20 / 255, time_factor=16) print(time.time() - start) for i in range(5): rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(i) + ".png") start = time.time() vibe.current_rgb = rgb_im / 255 vibe.set_mask() print(time.time() - start) mask = vibe.mask image_processing.save_image(mask, "Results/ViBE", i, "mask")
def request(mode, display=False, send_path=False, return_path=False, skip_features=False, return_cropped=True, return_uncropped=False, return_outline=False): ########### # REQUEST # ########### param_names_float = [ "verbose", "already_cropped", "skip_features", "return_cropped", "return_uncropped", "return_outline", "ORIGINAL_ORIENTATION" ] param_vals_float = [ 0, 0, int(skip_features), int(return_cropped), int(return_uncropped), int(return_outline), 1 ] params_dict = dict(zip(param_names_float, param_vals_float)) param_names_str = [] param_vals_str = [] if return_path: param_names_str.append("im_output_path") param_vals_str.append("C:\Users\Neil\Desktop\im_out") images = None # assemble image data print "Mode = %d" % mode if mode == 0: msg = struct.pack('=B', mode) # send to server sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((HOST, PORT)) send_data(sock, msg) response = get_data(sock, 1) success = struct.unpack('B', response)[0] print "Success: %s" % str(success == 0) return [], [] if mode == 10: fn = r"C:\Users\Neil\BT\Data\R2 FFT\multi\raw 10 sec.tif" elif mode == 40: if int(params_dict['already_cropped']) == 0: fn = r"C:\Users\Neil\BT\Data\blocks\B4\693 - PL Image B4 W2 4V (PL Image - Composite).tif" else: fn = r"C:\Users\Neil\BT\Data\blocks\2015-08\tifs\120815_ISE_E_nf_14A_22C_PL_600000-dark&FFcor_cropped.tif" elif mode in [70, 71]: if mode == 70: fn = r"C:\Users\Neil\BT\Data\slugs\zhonghuan\tifs\219609 - 160-1-6 (Uncalibrated PL Image).tif" elif mode == 71: fn = r"C:\Users\Neil\BT\Data\slugs\pseudo round\2861 - THICK SAMPLE TEST-2 %28Uncalibrated PL Image%29.tif" param_names_float += ['rds_percent', 'slug_radius'] param_vals_float += [50, 0] elif mode == 80: # PERC mono cell # fn = r"C:\Users\Neil\BT\Data\C3\perc\mono\BAC_1024_100\20150910_122155.612_BAC_1024_100_201.tif" # fn = r"C:\Users\Neil\BT\Data\cropping_test_set\cells\tifs\plg.meas.cell.plqrs.a.img.tif" fn = r"C:\Users\Neil\BT\Data\C3\perc\mono\BAC_1024_100\20150910_122155.612_BAC_1024_100_201.tif" if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) elif mode == 81: # PERC multi cell fn = r"C:\Users\Neil\BT\Data\C3\perc\multi\Point\1329 - REC test E1 PL Image (PL Open-circuit Image).tif" if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) elif mode == 82: # mono cell fn = r"C:\Users\Neil\BT\Data\C3\mono\INES_c-Si_100_1024\20150908_175300.680_INES_c-Si_100_1024_46.tif" if True: param_names_float.append("no_post_processing") param_vals_float.append(1) if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) elif mode == 83: # multi cell fn = r"C:\Users\Neil\BT\Data\C3\multi\misc\20170302T110107.328_Batch 3_ID467.tif" # fn = r"C:\Users\Neil\BT\Data\C3\multi\Astronergy\20170831T153538.783_zt-DJ--5_ID-8.tif" if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) elif mode == 84: # mono wafer # fn = r"C:\Users\Neil\BT\Data\CIC\cracks\tifs\S0067_20140821.131519_VI_PL21F_ID10063_GRADEB1_BIN2_raw_image.tif" # fn = r"C:\Users\Neil\BT\Data\mono wafer\2015-10-26\S0041_20151026.161500_longi DCA 1-2_ID2_GRADEA2_BIN4_raw.tif" fn = r"C:\Users\Neil\Desktop\outlines\mode84.tif" if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) elif mode == 85: # multi wafer fn = r"C:\Users\Neil\BT\Data\overlay test set\unnormalised\tifs\S0050_20120516.193034__ID10586 - Cor.tiff" if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) elif mode == 86: # X3 fn = r"C:\Users\Neil\BT\Data\X3\mono PERC\20161024_103301.320_a_00058101.tif" if int(params_dict['already_cropped']) == 1: fn = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) param_names_float += [ "num_stripes", "multi", "no_stripe_images", "ORIGINAL_ORIENTATION" ] param_vals_float += [5, 0, 1, 1] elif mode == 87: # mono stripe fn = r"C:\Users\Neil\BT\Data\stripe\2017-09-07 Baccini 1 in 1\S0041_20170907.120710_Baccini 1 in 1 test_ID6_raw.tif" elif mode == 88: # multi stripe fn = r"C:\Users\Neil\BT\Data\stripe\2017-09-07 Baccini 1 in 1\S0041_20170907.120917_Baccini 1 in 1 test_ID7_raw.tif" elif mode == 89: # QC-C3 #fn = r"C:\Users\Neil\BT\Data\half processed\1390 - Tet P4604 PLOC 0.2s 1Sun (Uncalibrated PL Image).tif" fn = r"C:\Users\Neil\Desktop\outlines\mode89.tif" elif mode in [90, 901]: # plir if True: fn1 = r"C:\Users\Neil\BT\Data\blocks\PLIR\Trina\2016-05-12\5.4V W (Uncalibrated PL Image) west short pass.tif" fn2 = r"C:\Users\Neil\BT\Data\blocks\PLIR\Trina\2016-05-12\5.4V W (Uncalibrated PL Image) west long pass.tif" fn3 = r"C:\Users\Neil\BT\Data\blocks\PLIR\Trina\2016-05-12\5.4V W (Uncalibrated PL Image) west no filter.tif" else: fn1 = r"C:\Users\Neil\Desktop\B35 files for B3\Face 1\plg.meas.block.b3bl.north.shortpass.img.tif" fn2 = r"C:\Users\Neil\Desktop\B35 files for B3\Face 1\plg.meas.block.b3bl.north.raw.img.tif" fn3 = r"C:\Users\Neil\Desktop\B35 files for B3\Face 1\plg.meas.block.b3bl.north.longpass.img.tif" im_sp = ip.open_image(fn1, cast_long=False).astype(np.uint16) im_lp = ip.open_image(fn2, cast_long=False).astype(np.uint16) im_pl = ip.open_image(fn3, cast_long=False).astype(np.uint16) if True: images = {'im_sp': im_sp, 'im_lp': im_lp, 'im_pl': im_pl} else: images = {'im_sp': im_sp, 'im_lp': im_lp} fn_xfer = r"C:\Users\Neil\BT\Data\2017-09-06 TransferFunctions.TXT" vals = block.load_transfer(fn_xfer) images['im_xfer'] = vals if mode == 901: del images['im_pl'] mode = 90 elif mode == 92: # brick markers fn = r"C:\Users\Neil\Desktop\20160826\1267 - Ref-C-25chiller-2 (North - Shortpass Image).tif" elif mode == 95: # resolution fn = r"C:\Users\Neil\BT\Data\2017-09-06 new calibration target.tif" elif mode == 100: if True: fn_pl = r"C:\Users\Neil\BT\Data\modules\WIN-555\WIN-555_LR0245_P93_2x2_OCPL.tif" fn_el = r"C:\Users\Neil\BT\Data\modules\WIN-555\WIN-555_LR0160_CV43.00_2x2_EL.tif" else: fn_pl = r"C:\Users\Neil\Desktop\Processed\CNY-098\CNY-098_G00_LR0090_P93_2x2_OCPL.tif" fn_el = r"C:\Users\Neil\Desktop\Processed\CNY-098\CNY-098_G00_LR0090_CC10.80_2x2_EL.tif" im_pl = ip.open_image(fn_pl).astype(np.uint16) im_el = ip.open_image(fn_el).astype(np.uint16) images = {'im_pl': im_pl} # , 'im_el': im_el} param_names_float += ["ORIGINAL_ORIENTATION"] param_vals_float += [0] elif mode == 255: msg = struct.pack('B', 255) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((HOST, PORT)) send_data(sock, msg) return [], [] else: print "Unknown mode" sys.exit() if images is None: # open im_pl im = ip.open_image(fn).astype(np.uint16) if False: im = im.T images = {'im_pl': im} if False and images['im_pl'].shape[0] > 800: print 'WARNING: Image resized' images['im_pl'] = ndimage.zoom(images['im_pl'], 0.25) if False: view = ImageViewer(images['im_pl']) view.show() # gather images image_names = ','.join(images.keys()) msg = struct.pack('=BI', mode, len(image_names)) msg += image_names for image_name, im in images.iteritems(): assert image_name[:2] in ['bl', 'mk', 'im', 'ov'] if image_name == 'im_xfer': bit_depth = 32 else: bit_depth = 16 binning = 1 if send_path: # pass by path msg += struct.pack('=HHBBB', 0, 0, bit_depth, binning, len(fn)) msg += fn else: # pass data msg += struct.pack('=HHBB', im.shape[1], im.shape[0], bit_depth, binning) msg += im.ravel().tostring() if False: param_names_float = [] param_vals_float = [] param_names_str = [] param_vals_str = [] # numerical parameter list param_names = ','.join(param_names_float) msg += struct.pack('=I', len(param_names)) msg += param_names msg += np.array(param_vals_float, np.float32).tostring() # string input parameters param_names = ','.join(param_names_str) msg += struct.pack('=I', len(param_names)) msg += param_names param_vals = ','.join(param_vals_str) msg += struct.pack('=I', len(param_vals)) msg += param_vals t1 = timeit.default_timer() # send to server sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((HOST, PORT)) send_data(sock, msg) ############ # RESPONSE # ############ features = {} # get response code response = get_data(sock, 1) success = struct.unpack('B', response)[0] if success != 0: print("Error occurred: %d" % success) sys.exit() # get images & masks data = get_data(sock, 4) image_names_length = struct.unpack('=I', data)[0] if image_names_length > 0: image_names = get_data(sock, image_names_length).split(",") for im_name in image_names: if im_name[:3] not in ['bl_', 'mk_', 'im_', 'ov_']: print "ERROR: Invalid image name: %s" % im_name sys.exit() data = get_data(sock, 6) im_w, im_h, bit_depth, binning = struct.unpack('=hhBB', data) if im_w == 0 or im_h == 0: # read from disk fn_len = struct.unpack('=B', get_data(sock, 1))[0] fn = str(get_data(sock, fn_len)) features[im_name] = ip.open_image(fn) else: if bit_depth == 8: data = get_data(sock, 4) encoding_length = struct.unpack('I', data)[0] png_data = get_data(sock, encoding_length) features[im_name] = ip.decode_png(png_data) num_pixels = features[im_name].shape[0] * features[ im_name].shape[1] print "%s compression: %0.1f%%" % ( im_name, (100 * encoding_length) / float(num_pixels)) elif bit_depth == 16: pixel_data = get_data(sock, im_w * im_h * 2) features[im_name] = np.frombuffer(pixel_data, np.uint16).reshape( im_h, im_w) elif bit_depth == 32: pixel_data = get_data(sock, im_w * im_h * 4) features[im_name] = np.frombuffer(pixel_data, np.float32).reshape( im_h, im_w) else: print '****', im_name else: image_names = [] # get numerical metric response = get_data(sock, 4) string_size = struct.unpack('I', response)[0] if string_size > 0: feature_names = get_data(sock, string_size) feature_names = feature_names.split(',') num_features = len(feature_names) bytes_expected = num_features * 4 feature_data = get_data(sock, bytes_expected) feature_data = list(np.frombuffer(feature_data, np.float32)) else: feature_names = [] feature_data = [] # get string metrics string_size = struct.unpack('I', get_data(sock, 4))[0] if string_size > 0: feature_names += get_data(sock, string_size).split(',') string_size = struct.unpack('I', get_data(sock, 4))[0] if string_size > 0: feature_data += get_data(sock, string_size).split(',') metric_vals = zip(feature_names, feature_data) ################### # DISPLAY RESULTS # ################### metrics = {} for i in range(len(feature_names)): features[feature_names[i]] = feature_data[i] metrics[feature_names[i]] = feature_data[i] print "Returned images:" for image_name in image_names: print " %s" % image_name print "Metrics:" pprint(metrics) t2 = timeit.default_timer() print('Total time: %0.03f seconds' % (t2 - t1)) rgb = None view = None if "im_cropped_u8" in features: if mode == 80: rgb = perc.create_overlay(features) elif mode == 81: rgb = perc.create_overlay_multi(features) elif mode == 82: rgb = cz_cell.create_overlay(features) elif mode == 83: rgb = multi_cell.create_overlay(features) elif mode == 84: rgb = cz_wafer.create_overlay(features) elif mode == 85: if 'skip_features' not in params_dict or params_dict[ 'skip_features'] != 1: rgb = multi_wafer.create_overlay(features) elif mode == 86: rgb = x3.create_overlay(features) if False: # save cropped version for testing fn_cropped = os.path.join(r"C:\Users\Neil\BT\Data\cropped", os.path.split(fn)[1]) ip.save_image(fn_cropped, features['im_cropped_u16']) if display and mode != 100: print 'Images:' if 'im_pl' in images: print ' 1: Input PL image' im = images['im_pl'] view = ImageViewer(im) e = 2 for feature in features.keys(): if (feature.startswith('im_') or feature.startswith('mk_') or feature.startswith('ov_') or feature.startswith('bl_')): print ' %d: %s' % (e, feature) ImageViewer(features[feature]) e += 1 if rgb is not None: print ' %d: Colour overlay' % e e += 1 ImageViewer(rgb) if view is not None: view.show() return image_names, metric_vals
def create_mask(): color_mask = image_processing.load_image("tracking_results", "global_two_different3.png") binary_mask = np.where(np.sum(color_mask, axis=2), 1, 0) image_processing.save_image(binary_mask, "Mask", "mask")
def feature_extraction(im_pl, im_el, features): t_start = timeit.default_timer() # TODO: check if entire EL image is dark. ratio of means? # segment the module into individual cells and find cell template module_props = extract_cell_images(im_pl, im_el, features) if False: folder_out = r"C:\Users\Neil\Desktop\module_cracks" module_id = features['fn'].split('_')[0] # save cell images for cell_props in features['_cell_properties'].values(): cell_name = cell_props['cell_name'] if ((module_id == "CNY-098" and cell_name in ['B3', 'G3', 'H3', 'E4']) or (module_id == "CNY-101" and cell_name in ['C1', 'J1', 'H2', 'I2', 'J2']) or (module_id == "CNY-139" and cell_name in ['A3']) or (module_id == "CNY-232" and cell_name in ['G6']) or (module_id == "CNY-449" and cell_name in ['D1', 'F1', 'A2', 'I2', 'A3', 'D4', 'E4', 'G5']) or (module_id == "REC-143" and cell_name in ['H2', 'H4', 'B6', 'D6']) or (module_id == "STP-410" and cell_name in ['K3', 'E6', 'H2', 'H3'])): im_pl = (ip.scale_image(cell_props['im_cell_pl']) * 255).astype(np.uint8) fn_im = os.path.join(folder_out, "%s_%s_pl.png" % (module_id, cell_name)) ip.save_image(fn_im, im_pl) im_el = (ip.scale_image(cell_props['im_cell_el']) * 255).astype(np.uint8) fn_im = os.path.join(folder_out, "%s_%s_el.png" % (module_id, cell_name)) ip.save_image(fn_im, im_el) im_ratio = (ip.scale_image(cell_props['im_cell_ratio']) * 255).astype(np.uint8) fn_im = os.path.join( folder_out, "%s_%s_ratio.png" % (module_id, cell_name)) ip.save_image(fn_im, im_ratio) fn_raw = os.path.join(folder_out, "%s_%s.npz" % (module_id, cell_name)) np.savez_compressed(fn_raw, im_pl=cell_props['im_cell_pl'], im_el=cell_props['im_cell_el'], im_ratio=cell_props['im_cell_ratio']) if False: print module_id, cell_name view = ImageViewer(cell_props['im_cell_pl']) ImageViewer(cell_props['im_cell_el']) ImageViewer(cell_props['im_cell_ratio']) view.show() sys.exit() # module-level metrics analyse_module(features) if False: # cell processing if False: # process each cell individually for cell_props in features['_cell_properties'].values(): cell_processing(cell_props) else: # process cells in parallel pool = mp.Pool(processes=4) results = [ pool.apply_async(cell_processing, args=(cp, )) for cp in features['_cell_properties'].values() ] [p.get() for p in results] pool.close() # save results # for cell_props in features['_cell_properties'].values(): # cell_name = cell_props['cell_name'] # cell_im = np.round(cell_props['im_cell']).astype(np.uint16) # features['im_%s_pl_u16' % cell_name] = cell_im # TODO: check for dark cells/rows # - example ratio images # undo rotation if False and parameters.ORIGINAL_ORIENTATION: for feature in features.keys(): if ((feature.startswith('im_') or feature.startswith('ov_') or feature.startswith('bl_') or feature.startswith('mk_')) and features[feature].ndim == 2): features[feature] = features[feature].T[:, ::-1] # compute runtime t_stop = timeit.default_timer() features['processing_runtime'] = t_stop - t_start
def handle(self): reload(parameters) # self.request is the TCP socket connected to the client # get the image dimensions, which is contain in the first two # unsigned shorts (two bytes each) start_time = str(datetime.datetime.now()) mode = struct.unpack('B', self.get_data(1))[0] print('Request received at %s (mode=%d)' % (start_time, mode)) if mode == 255: print(' Mode: Exit') self.server.shutdown() return if mode == 0: msg = struct.pack('=B', 0) self.send_data(msg) return # get input images image_desc_length = struct.unpack('=I', self.get_data(4))[0] if image_desc_length == 0: print "ERROR: No images passed as input" return image_names_in = self.get_data(image_desc_length).split(',') images = {} for im_name in image_names_in: data = self.get_data(6) width, height, bit_depth, binning = struct.unpack('=HHBB', data) num_pixels = width * height if num_pixels == 0: # read from disk fn_len = struct.unpack('=B', self.get_data(1))[0] fn = str(self.get_data(fn_len)) images[im_name] = ip.open_image(fn) else: if bit_depth == 8: pixel_data = self.get_data(num_pixels) im_data = np.frombuffer(pixel_data, np.uint8) elif bit_depth == 16: pixel_data = self.get_data(num_pixels * 2) im_data = np.frombuffer(pixel_data, np.uint16) elif bit_depth == 32: pixel_data = self.get_data(num_pixels * 4) im_data = np.frombuffer(pixel_data, np.float32) images[im_name] = im_data.reshape(height, width).astype(np.float32) # get numerical parameters data = self.get_data(4) param_desc_length = struct.unpack('=I', data)[0] if param_desc_length > 0: param_names = self.get_data(param_desc_length).split(",") num_params = len(param_names) param_data = self.get_data(num_params * 4) params_array = list(np.frombuffer(param_data, np.float32)) else: param_names = [] params_array = [] # get string parameters data = self.get_data(4) param_desc_length = struct.unpack('=I', data)[0] if param_desc_length > 0: param_names += self.get_data(param_desc_length).split(",") param_vals_length = struct.unpack('=I', self.get_data(4))[0] params_array += self.get_data(param_vals_length).split(",") # override defaults in parameters.py for pn, pv in zip(param_names, params_array): if pn.upper() in dir(parameters): setattr(parameters, pn.upper(), pv) # store input parameters in the features dict param_names = ['input_param_' + pn for pn in param_names] features = dict(zip(param_names, params_array)) if 'input_param_already_cropped' in features and int( features['input_param_already_cropped']) == 1: already_cropped = True else: already_cropped = False if 'input_param_return_uncropped' in features and int( features['input_param_return_uncropped']) == 1: return_uncropped = True else: return_uncropped = False if 'input_param_return_cropped' in features and int( features['input_param_return_cropped']) == 0: return_cropped = False else: return_cropped = True if 'input_param_return_outline' in features and int( features['input_param_return_outline']) == 1: return_outline = True else: return_outline = False # call image processing algorithm try: if mode == 10: print(' Mode: Hash Pattern correction') im_raw = images['im_pl'].astype(np.float32) im_corrected = FF.correct_hash_pattern(im_raw) features['im_corrected_u16'] = im_corrected.astype(np.uint16) elif mode == 40: print(' Mode: Block processing') im = images['im_pl'].astype(np.float32) block.feature_extraction(im, features, crop=not already_cropped) features['crop_left'] = features['_crop_bounds'][0] features['crop_right'] = features['_crop_bounds'][1] features['crop_top'] = features['_crop_bounds'][2] features['crop_bottom'] = features['_crop_bounds'][3] features['bl_cropped_u8'] = np.zeros_like( features['im_cropped_u8'], np.uint8) if return_uncropped or return_outline: left, right, top, bottom = features['_crop_bounds'] mask = np.ones_like(images['im_pl'], np.uint8) mask[top:bottom, left:right] = 0 if abs(features['crop_rotation']) > 0.01: h, w = mask.shape rot_mat = cv2.getRotationMatrix2D( (w // 2, h // 2), features['crop_rotation'] * -1, 1.0) mask = cv2.warpAffine(mask, rot_mat, (w, h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REPLICATE ) # .astype(np.uint8) if return_uncropped: features['bl_uncropped_u8'] = mask elif mode in [70, 71]: print(' Mode: Slugs') im = images['im_pl'].astype(np.float32) if 'input_param_rds_percent' not in features: features['param_rds_percent'] = 50 else: features['param_rds_percent'] = int( features['input_param_rds_percent']) if 'param_radius_prior' not in features: features['param_radius_prior'] = 0 else: features['param_radius_prior'] = int( features['input_param_slug_radius']) slugs.feature_extraction(im, features) update_corner_features(features, features) features['im_cropped_u8'] = (ip.scale_image(images['im_pl']) * 255).astype(np.uint8) features['im_cropped_u16'] = images['im_pl'].astype(np.uint16) mask = features['bl_uncropped_u8'] if not return_uncropped: del features['bl_uncropped_u8'] elif mode in [84, 85, 89]: if mode == 84: print(' Mode: Mono wafer') im = images['im_pl'].astype(np.float32) features['_alg_mode'] = 'mono wafer' crop_props = cropping.crop_wafer_cz( im, create_mask=True, skip_crop=already_cropped) features['corners'] = crop_props['corners'] features['_wafer_middle_orig'] = crop_props['center'] cropped = cropping.correct_rotation( im, crop_props, pad=False, border_erode=parameters.BORDER_ERODE_CZ, fix_chamfer=False) cz_wafer.feature_extraction(cropped, crop_props, features=features) update_corner_features(features, crop_props) elif mode == 85: print(' Mode: Multi wafer') im = images['im_pl'].astype(np.float32) features['_alg_mode'] = 'multi wafer' if not already_cropped: crop_props = cropping.crop_wafer(im, create_mask=True) features['corners'] = crop_props['corners'] cropped = cropping.correct_rotation( im, crop_props, pad=False, border_erode=parameters.BORDER_ERODE) else: crop_props = {} crop_props['estimated_width'] = im.shape[0] crop_props['center'] = (im.shape[0] / 2, im.shape[1] / 2) crop_props['corners'] = [ [0, 0], [0, im.shape[1]], [im.shape[0], im.shape[1]], [im.shape[0], 0], ] crop_props['corners_floats'] = crop_props['corners'] crop_props['estimated_rotation'] = 0 crop_props['mask'] = np.ones_like(im, np.uint8) cropped = im multi_wafer.feature_extraction(cropped, crop_props, features=features) multi_wafer.combined_features(features) update_corner_features(features, crop_props) elif mode == 89: print(' Mode: QC-C3') features['_alg_mode'] = 'qc' im = images['im_pl'].astype(np.float32) crop_props = qc.feature_extraction(im, features) if return_uncropped: features['bl_uncropped_u8'] = crop_props['mask'] elif mode in [80, 81, 82, 83, 86, 87, 88]: if mode == 80: print(' Mode: PERC mono') im = images['im_pl'].astype(np.float32) features['_alg_mode'] = 'perc mono' perc.feature_extraction(im, features, already_cropped=already_cropped) elif mode == 81: print(' Mode: PERC multi') im = images['im_pl'].astype(np.float32) features['_alg_mode'] = 'perc multi' perc.feature_extraction_multi( im, features, already_cropped=already_cropped) elif mode == 82: print(' Mode: Mono cells') im = images['im_pl'].astype(np.float32) features['_alg_mode'] = 'mono cell' cz_cell.feature_extraction(im, features, skip_crop=already_cropped) elif mode == 83: print(' Mode: Multi cells') im = images['im_pl'].astype(np.float32) features['_alg_mode'] = 'multi cell' multi_cell.feature_extraction( im, features, already_cropped=already_cropped) elif mode == 86: print(' Mode: X3') features['_alg_mode'] = 'x3' im = images['im_pl'].astype(np.float32) x3.feature_extraction(im, features, already_cropped=already_cropped) elif mode == 87: print(' Mode: Stripe (mono)') features['_alg_mode'] = 'stripe' features['_cell_type'] = 'mono' im = images['im_pl'].astype(np.float32) stripe.feature_extraction(im, features, skip_crop=already_cropped) elif mode == 88: print(' Mode: Stripe (multi)') features['_alg_mode'] = 'stripe' features['_cell_type'] = 'multi' im = images['im_pl'].astype(np.float32) stripe.feature_extraction(im, features, skip_crop=already_cropped) update_corner_features(features, features) if return_uncropped: mask = features['bl_cropped_u8'] im_h, im_w = im.shape if 'cell_rotated' in features and features['cell_rotated']: if parameters.ORIGINAL_ORIENTATION: mask = mask[:, ::-1].T im_h = im.shape[1] im_w = im.shape[0] # undo rotation and cropping mask = np.pad(mask, ((features['crop_top'], im_h - features['crop_bottom']), (features['crop_left'], im_w - features['crop_right'])), mode='constant', constant_values=((1, 1), (1, 1))) # created rotated version of full image mask_rotated = np.empty(im.shape, np.float32) h, w = mask.shape if 'cell_rotated' not in features or not features[ 'cell_rotated']: rot_mat = cv2.getRotationMatrix2D( (w // 2, h // 2), -features['crop_rotation'], 1.0) else: rot_mat = cv2.getRotationMatrix2D( (h // 2, h // 2), -features['crop_rotation'], 1.0) cv2.warpAffine(mask.astype(np.float32), rot_mat, (im.shape[1], im.shape[0]), flags=cv2.INTER_NEAREST, borderMode=cv2.BORDER_CONSTANT, dst=mask_rotated, borderValue=1) #print mask.shape, im.shape assert mask_rotated.shape == im.shape features['bl_uncropped_u8'] = np.round( mask_rotated).astype(np.uint8) elif mode == 90: print(' Mode: plir') im_sp = images['im_sp'].astype(np.float32) im_lp = images['im_lp'].astype(np.float32) if 'im_xfer' not in images: print "ERROR: Transfer functions not found" self.send_data(struct.pack('=B', 6)) return spline_plir, spline_nf, spline_sp, spline_lp = block.interpolate_transfer( images['im_xfer']) if 'im_pl' in images: im_pl = images['im_pl'].astype(np.float32) plc_found = block.plir(im_sp, im_lp, im_pl, features, spline_plir, spline_nf) else: plc_found = block.plir2(im_sp, im_lp, features, spline_plir, spline_sp) if not plc_found: self.send_data(struct.pack('=B', 5)) return if return_uncropped or return_outline: left, right, top, bottom = features['_crop_bounds'] if 'im_pl' in images: left *= 2 right *= 2 top *= 2 bottom *= 2 mask = np.ones_like(images['im_pl'], np.uint8) else: mask = np.ones_like(images['im_sp'], np.uint8) mask[top:bottom, left:right] = 0 if abs(features['crop_rotation']) > 0.01: h, w = mask.shape rot_mat = cv2.getRotationMatrix2D( (w // 2, h // 2), features['crop_rotation'] * -1, 1.0) mask = cv2.warpAffine(mask, rot_mat, (w, h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REPLICATE ) # .astype(np.uint8) if return_uncropped: features['bl_uncropped_u8'] = mask elif mode == 92: print(' Mode: Distance between brick markers') im = images['im_pl'].astype(np.float32) block.MarkerLineDist(im, features) elif mode == 95: print(' Mode: Pixels per mm') im = images['im_pl'].astype(np.float32) resolution.resolution(im, features) elif mode == 100: print(' Mode: M1') if 'im_el' in images: im_el = images['im_el'].astype(np.float32) else: im_el = None im_pl = images['im_pl'].astype(np.float32) m1.feature_extraction(im_pl, im_el, features) else: print("ERROR: Mode %d not supported" % mode) self.send_data(struct.pack('=B', 1)) return if not return_cropped: for im_name in [ 'im_cropped_u16', 'im_cropped_u8', 'bl_cropped_u8', "im_cropped_sp_u8", 'im_cropped_nf_u8', 'im_cropped_sp_u16', 'im_cropped_nf_u16', 'im_cropped_lp_u16' ]: if im_name in features: del features[im_name] if return_outline: if mode in [40, 70, 90]: binary_struct = ndimage.generate_binary_structure(2, 1) foreground = 1 - mask outline = foreground - ndimage.binary_erosion( foreground, binary_struct) features['bl_crop_outline_u8'] = outline.astype(np.uint8) else: features['bl_crop_outline_u8'] = cropping.draw_crop_box( im, features, mode="mask") except cropping.WaferMissingException: self.send_data(struct.pack('=B', 2)) return except cell.MissingBusbarsException: self.send_data(struct.pack('=B', 3)) return except cell.CellFingersException: self.send_data(struct.pack('=B', 4)) return except: traceback.print_exc(file=sys.stdout) self.send_data(struct.pack('=B', 1)) return # success msg = struct.pack('=B', 0) self.send_data(msg) # return images image_names = [] for f in features.keys(): if f.split('_')[-1] not in ['u8', 'u16', 'f32'] or f[0] == '_': continue if f[:3] not in ['bl_', 'mk_', 'im_', 'ov_']: print "ERROR: invalid image name: %s" % f image_names.append(f) image_names.sort() image_names_send = ','.join(image_names) self.send_data(struct.pack('I', len(image_names_send))) self.send_data(image_names_send) for im_name in image_names: fields = im_name.split('_') if fields[-1] == "u8": bit_depth = 8 elif fields[-1] == "u16": bit_depth = 16 elif fields[-1] == "f32": bit_depth = 32 # convert binary masks from 0,1 to 0,255 if fields[0] == 'mk' and bit_depth == 8: features[im_name] *= 255 if ('input_param_im_output_path' in features and len(features['input_param_im_output_path']) > 0 and bit_depth in [8, 16]): # send back as path. msg = struct.pack('=hhBB', 0, 0, 0, 1) if bit_depth == 8: ext = '.png' else: ext = '.tif' fn_out = os.path.join(features['input_param_im_output_path'], im_name + ext) ip.save_image(fn_out, features[im_name], scale=False) fn_len = len(fn_out) msg += struct.pack('=B', fn_len) msg += fn_out else: # image data height, width = features[im_name].shape binning = 1 msg = struct.pack('=hhBB', width, height, bit_depth, binning) if fields[-1] == "u8": png = ip.encode_png(features[im_name]) msg += struct.pack('=I', len(png)) msg += png elif fields[-1] in ["u16", "f32"]: msg += features[im_name].tostring() self.send_data(msg) # numerical features feature_names = [] feature_vals = [] for k in features.keys(): if (k in ['cropped', 'corners', 'filename', 'center'] or k.startswith("bl_") or k.startswith('_') or k.startswith("mask_") or k.startswith("mk_") or k.startswith("im_") or k.startswith("ov_")): continue if type(features[k]) is str: continue feature_names.append(k) feature_names.sort() for feature in feature_names: feature_vals.append(float(features[feature])) feature_names = ','.join(feature_names) feature_vals = np.array(feature_vals, np.float32) bytes_to_send = len(feature_names) self.send_data(struct.pack('=I', bytes_to_send)) self.send_data(feature_names) msg = feature_vals.ravel().tostring() self.send_data(msg) # string features feature_names = [] feature_vals = [] for k in features.keys(): if k.startswith('_'): continue if type(features[k]) is not str: continue feature_names.append(k) feature_names.sort() for feature in feature_names: feature_vals.append(features[feature]) feature_names = ','.join(feature_names) feature_vals = ','.join(feature_vals) bytes_to_send = len(feature_names) self.send_data(struct.pack('=I', bytes_to_send)) if bytes_to_send > 0: self.send_data(feature_names) bytes_to_send = len(feature_vals) self.send_data(struct.pack('=I', bytes_to_send)) if bytes_to_send > 0: self.send_data(feature_vals) return
print('dimensions=', dimensions) data = np.concatenate(args) print('================') print('TOTAL DATA LENGTH = ', len(data), ' BITS') print('================') data = data_processing.expand(data) data = data_processing.complexize_data(data) write_to_file(data, fn) return def write_to_file(complex_array, fn): """ Takes in np array with complex values & writes them to file """ #source; https://stackoverflow.com/questions/29809988/numpy-array-tofile-binary-file-looks-strange-in-notepad print fn fp = open(fn, mode='wb') off = np.array(complex_array, dtype=np.float32) off.tofile(fp) fp.close() if __name__ == '__main__': ImageProcessing = image_processing.ImageProcessing() ImageProcessing.compress() img = ImageProcessing.tiles[6].y_tile image_processing.save_image(img, 'images/img_precompressed.jpg') header = np.zeros(1000) header[41] = 1 main(img, header, 'no_transmission.dat')
import numpy as np import os image_antique = "/images/antique.jpg" image_face = "/images/face.jpg" image_fog = "/images/fog.jpg" image_text_gif = "/images/text.gif" image_text = "/images/text.jpg" image_text_small = "/images/text_small.png" se_3x3 = np.ones(shape=(3, 3)) se_3x3[0][0] = 0 se_3x3[0][2] = 0 se_3x3[2][0] = 0 se_3x3[2][2] = 0 if __name__ == "__main__": image_address = os.getcwd() + image_text_gif image_array = image_processing.prepare_image(image_address, True, True, print_flag=True) image_processing.save_image(image_array, 'binary', image_address, binary_image=True) skeletonized_image = morphology.skeletonization(image_array, se_3x3) image_processing.save_image(skeletonized_image, "skeleton", image_address, binary_image=True)
def objects_test_moving_figures_global(): classes = {} rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(0) + ".png") depth_im = image_processing.load_image("falling balls and cylinder", "depth_" + str(0) + ".png", "depth") mog = RGBD_MoG(rgb_im, depth_im, number_of_gaussians=3) for number_of_frame in range(1, 5): color_mask = np.zeros([rgb_im.shape[0], rgb_im.shape[1], 3]) rgb_im = image_processing.load_image( "falling balls and cylinder", "rgb_" + str(number_of_frame) + ".png") depth_im = image_processing.load_image( "falling balls and cylinder", "depth_" + str(number_of_frame) + ".png", "depth") mask = mog.set_mask(rgb_im, depth_im) depth_im = depth_im * (mask / 255).astype(int) masks = region_growing(mask / 255, depth_im / 255, depth_threshold=0.01, significant_number_of_points=10) if len(masks) == 0: print("No moving objects in the frame") else: for mask in masks: xyz_points, rgb_points = image_processing.calculate_point_cloud( rgb_im / 255, depth_im * mask / 255) current_object = PointsObject() current_object.set_points(xyz_points, rgb_points) norms = current_object.get_normals() compared_object_descriptor = GlobalCovarianceDescriptor( xyz_points, rgb_points, norms, depth_im, rgb_im, mask, use_xyz=True, use_rgb=True, use_normals=True) match_found = False lengths = np.zeros([len(classes)]) if number_of_frame == 1: match_found = False else: match_found = True for object_number, object_class in enumerate(classes): lengths[ object_number] = object_class.compare_descriptors( compared_object_descriptor. object_descriptor) min_arg = np.argmin(lengths) print(lengths) for object_number, object_class in enumerate(classes): if object_number == min_arg: color_mask[:, :, 0] += mask * classes[object_class][0] color_mask[:, :, 1] += mask * classes[object_class][1] color_mask[:, :, 2] += mask * classes[object_class][2] if not match_found: classes[compared_object_descriptor] = np.random.rand(3) color_mask[:, :, 0] += mask * classes[ compared_object_descriptor][0] color_mask[:, :, 1] += mask * classes[ compared_object_descriptor][1] color_mask[:, :, 2] += mask * classes[ compared_object_descriptor][2] image_processing.save_image(color_mask, "tracking_results", frame_number=number_of_frame, image_name="global_two_same")
def objects_test_moving_figures_local(): number_of_comparing_points = 100 classes = {} rgb_im = image_processing.load_image("falling balls and cylinder", "rgb_" + str(0) + ".png") depth_im = image_processing.load_image("falling balls and cylinder", "depth_" + str(0) + ".png", "depth") mog = RGBD_MoG(rgb_im, depth_im, number_of_gaussians=3) for number_of_frame in range(1, 5): color_mask = np.zeros([rgb_im.shape[0], rgb_im.shape[1], 3]) rgb_im = image_processing.load_image( "falling balls and cylinder", "rgb_" + str(number_of_frame) + ".png") depth_im = image_processing.load_image( "falling balls and cylinder", "depth_" + str(number_of_frame) + ".png", "depth") mask = mog.set_mask(rgb_im, depth_im) depth_im = depth_im * (mask / 255).astype(int) masks = region_growing(mask / 255, depth_im / 255, depth_threshold=0.01, significant_number_of_points=10) if len(masks) == 0: print("No moving objects in the frame") else: for mask in masks: xyz_points, rgb_points = image_processing.calculate_point_cloud( rgb_im / 255, depth_im * mask / 255) current_object = PointsObject() current_object.set_points(xyz_points, rgb_points) norms = current_object.get_normals() compared_object_descriptor = CovarianceDescriptor( xyz_points, rgb_points, norms, k_nearest_neighbours=None, relevant_distance=0.1, use_alpha=True, use_beta=True, use_ro=True, use_theta=True, use_psi=True, use_rgb=True) match_found = False lengths = np.zeros([ len(classes), np.amin( [number_of_comparing_points, xyz_points.shape[0]]) ]) if number_of_frame == 1: match_found = False else: match_found = True for object_number, object_class in enumerate(classes): lengths[ object_number] = object_class.compare_descriptors( compared_object_descriptor. object_descriptor, number_of_comparing_points) print(np.sum(mask)) min_args = np.argmin( lengths, axis=0)[np.amin(lengths, axis=0) < 0.1] unique, counts = np.unique(min_args, return_counts=True) best_match = unique[np.argmax(counts)] for object_number, object_class in enumerate(classes): if object_number == best_match: color_mask[:, :, 0] += mask * classes[object_class][0] color_mask[:, :, 1] += mask * classes[object_class][1] color_mask[:, :, 2] += mask * classes[object_class][2] if not match_found: classes[compared_object_descriptor] = np.random.rand(3) color_mask[:, :, 0] += mask * classes[ compared_object_descriptor][0] color_mask[:, :, 1] += mask * classes[ compared_object_descriptor][1] color_mask[:, :, 2] += mask * classes[ compared_object_descriptor][2] image_processing.save_image(color_mask, "tracking_results", frame_number=number_of_frame, image_name="local_two_same")
def extract_cell_images(im_pl, im_el, features): # Use PL as this is more reliable for finding rotation t1 = timeit.default_timer() rotation_pl, im_pl_rotated = module_rotate(im_pl) t2 = timeit.default_timer() if False: print " Rotation time: %0.02fs Angle: %0.02f" % (t2 - t1, rotation_pl) view = ImageViewer(im_pl[::2, ::2]) ImageViewer(im_pl_rotated[::2, ::2]) view.show() if im_el is not None: # Registration # - assume no between capture rotation. use same rotation as for PL image rotation_el, im_el_rotated = module_rotate(im_el, rotation_pl) if False: view = ImageViewer(im_pl_rotated[::4, ::4]) ImageViewer(im_el_rotated[::4, ::4]) view.show() # horizontal registration shift_h = register_images(im_pl_rotated, im_el_rotated) im_el_registered = np.roll(im_el_rotated, shift_h, axis=1) # vertical registration shift_v = register_images(im_pl_rotated.T, im_el_registered.T) im_el_registered = np.roll(im_el_registered, shift_v, axis=0) if False: print shift_v, shift_h view = ImageViewer(im_pl_rotated[::4, ::4]) ImageViewer(im_el_registered[::4, ::4]) view.show() sys.exit() # PL/EL ratio im_ratio = im_pl_rotated / np.maximum(0.01, im_el_registered) features['im_pl_el'] = im_ratio if False: view = ImageViewer(im_ratio[::4, ::4]) view.show() else: im_ratio = None # segment individual cells segment_module(im_pl_rotated, features) if False: # not yet sure if there is any use for these features["_im_pl_cropped"] = im_pl_rotated[ features['_divisions_rows'][0]:features['_divisions_rows'][-1], features['_divisions_cols'][0]:features['_divisions_cols'][-1]] features["_im_el_cropped"] = im_el_rotated[ features['_divisions_rows'][0]:features['_divisions_rows'][-1], features['_divisions_cols'][0]:features['_divisions_cols'][-1]] features["_im_ratio_cropped"] = im_ratio[ features['_divisions_rows'][0]:features['_divisions_rows'][-1], features['_divisions_cols'][0]:features['_divisions_cols'][-1]] # save cell images & create cell template # 1. need to pick a "good" one for reference template. # - It should be interior. # - If picked at random, could be an abnormal one. Therefore, ranks cells by some feature (e.g. std) # and pick the one that is in the middle module_cell_props = features['_cell_properties'] cell_character = [] for (cell_num, cell_props) in module_cell_props.iteritems(): if cell_props['border_cell']: continue top = cell_props['crop_top'] bottom = cell_props['crop_bottom'] left = cell_props['crop_left'] right = cell_props['crop_right'] cell_pl = im_pl_rotated[top:bottom, left:right] cell_character.append((cell_num, cell_pl.std())) if False: print cell_props['cell_name'] view = ImageViewer(cell_pl) view.show() # - this is a measure of how uniform the cells appear. if high variation, there is probably something wrong # with the module, and trying to register each cell individually won't work well # - suitable threshold seems to be around 0.3 # TODO: can we do something more robust that works in these cases? stds = np.array([c[1] for c in cell_character]) cell_cov = stds.std() / stds.mean() features['cell_variation'] = cell_cov cell_character.sort(key=lambda x: x[1]) cell_ref_num = cell_character[len(cell_character) // 2][0] cell_props = module_cell_props[cell_ref_num] cell_ref = im_pl_rotated[cell_props['crop_top'] - 1:cell_props['crop_bottom'] + 1, cell_props['crop_left'] - 1:cell_props['crop_right'] + 1] cell_ref = cell_rotate(cell_ref, {}) cell_ref_data = {'im': cell_ref} if False: view = ImageViewer(cell_ref) view.show() cell_records = list(module_cell_props.iteritems()) # create cell template: # 1. register with "reference" cell # 2. median of mean to make robust # - too memory/computationally expensive to take median of all cells # - therefore, take mean of batches, and median of mean? # - alternative: median of sub-sample (might have less blurring?) registered_cells = np.empty( (len(cell_records), cell_ref.shape[0], cell_ref.shape[1])) for e, (cell_num, cell_props) in enumerate(cell_records): if False: print cell_props['cell_name'], top = cell_props['crop_top'] bottom = cell_props['crop_bottom'] left = cell_props['crop_left'] right = cell_props['crop_right'] cell_pl = im_pl_rotated[top:bottom, left:right] cell_crop_props = {} rotated = cell_rotate(cell_pl, cell_crop_props, debug=cell_props['cell_name'] == 'D666') registered = register_to_template( rotated, cell_ref_data, cell_crop_props, debug=cell_props['cell_name'] == 'F66') cell_props['im_cell_pl'] = registered # extract ratio image if im_ratio is not None: cell_el = im_el[top:bottom, left:right] cell_el_rotated = cell_rotate(cell_el, cell_crop_props) cell_el_reg = register_to_template(cell_el_rotated, cell_ref_data, cell_crop_props) cell_props['im_cell_el'] = cell_el_reg cell_ratio = im_ratio[top:bottom, left:right] cell_ratio_rotated = cell_rotate(cell_ratio, cell_crop_props) cell_ratio_reg = register_to_template(cell_ratio_rotated, cell_ref_data, cell_crop_props) cell_props['im_cell_ratio'] = cell_ratio_reg if False: print "Cell: %s" % cell_props['cell_name'], top view = ImageViewer(cell_pl) ImageViewer(rotated) ImageViewer(registered) view.show() registered_cells[e, :, :] = registered if False: folder = r"C:\Users\Neil\Desktop\cells" fn_out = os.path.join(folder, "cell_%s.png" % cell_props['cell_name']) im_out = (ip.scale_image(registered) * 255).astype(np.uint8) ip.save_image(fn_out, im_out) # cell_template /= features['num_cells'] cell_template = np.median(registered_cells, axis=0) # cell_template = np.mean(registered_cells, axis=0) features['im_00_template_u16'] = np.round(cell_template).astype(np.uint16) if False: template = (ip.scale_image(cell_template) * 255).astype(np.uint8) ip.save_image(r"C:\Users\Neil\Desktop\cell comp\t1.png", template) view = ImageViewer(cell_template) cell_num = 12 if False and 'cell_pl_im' in module_cell_props[cell_num]: ImageViewer(module_cell_props[cell_num]['cell_pl_im']) ImageViewer(module_cell_props[cell_num]['cell_ratio_im']) ImageViewer(module_cell_props[cell_num]['cell_pl_im'] / cell_template) view.show() sys.exit() return features
def block_foreground(im, features): per_col = features['_col_60'] im_col = np.dot(np.ones((im.shape[0], 1), np.float32), per_col.reshape(1, per_col.shape[0])) per_row = features['_row_90'] im_row = np.dot(per_row.reshape(im.shape[0], 1), np.ones((1, im.shape[1]), np.float32)) background = ip.fast_smooth(np.minimum(im_col, im_row), sigma=5) foreground = background - im pixel_ops.ApplyThresholdLT_F32(foreground, foreground, 0, 0) pixel_ops.ApplyThresholdLT_F32(background, foreground, 0.3, 0) if False: view = ImageViewer(im, vmin=0, vmax=1) ImageViewer(im_col, vmin=0, vmax=1) ImageViewer(im_row, vmin=0, vmax=1) ImageViewer(background, vmin=0, vmax=1) ImageViewer(foreground, vmin=0, vmax=1) view.show() sys.exit() # skeletonized version of defects local_mins = np.zeros_like(foreground, np.uint8) f = cv2.GaussianBlur(foreground * -1, ksize=(0, 0), sigmaX=2) pixel_ops.LocalMins(f, local_mins) dis = ((local_mins == 1) & (foreground > 0.1)).astype(np.uint8) ys, xs = np.where(dis) pixel_ops.FastThin(dis, ys.copy(), xs.copy(), ip.thinning_lut) ip.remove_small_ccs(dis, 10) if False: crossing = np.zeros_like(dis) pixel_ops.ComputeCrossings(dis, crossing) junctions = crossing > 2 struct = ndimage.generate_binary_structure(2, 2) junctions_d = ndimage.binary_dilation(junctions, struct) branches = dis.copy() branches[junctions_d] = 0 # find branches that touch an end point ccs, num_ccs = ip.connected_components(branches) spurs = np.zeros_like(dis) for cc in set(ccs[crossing == 1]): if cc == 0: continue spurs[ccs == cc] = 1 # sys.exit() remove = spurs.copy() ip.remove_small_ccs(remove, 10) removed = spurs - remove pruned = dis - removed crossing = np.zeros_like(dis) pruned = pruned.astype(np.uint8) pixel_ops.ComputeCrossings(pruned, crossing) pruned[crossing == 1] = 0 dis = pruned rgb = ip.overlay_mask(im, dis, colour='b') ip.save_image("brick_lines_skeleton.png", dis) ip.save_image("brick_lines_overlay.png", rgb) view = ImageViewer(foreground, vmin=0, vmax=1) ImageViewer(rgb) view.show() sys.exit() # create a height-based profile of dislocation levels # - crop impure areas at top and bottom, imp = np.where(per_row < 0.5)[0] mid = len(per_row) // 2 upper_half = imp[imp < mid] if len(upper_half) > 0: top = upper_half.max() else: top = 0 lower_half = imp[imp > mid] if len(lower_half) > 0: bottom = lower_half.min() else: bottom = len(per_row) if False: plt.figure() plt.plot(per_row) plt.vlines([top, bottom], ymin=0, ymax=1) plt.show() sys.exit() foreground_pure = foreground[top:bottom, :] dislocation_profile = foreground_pure.mean(axis=0) dislocation_profile[per_col < 0.6] = 0 dislocation_profile = ndimage.gaussian_filter1d(dislocation_profile, sigma=5) features['_dis_avg_height'] = dislocation_profile if False: view = ImageViewer(im, vmin=0, vmax=1) # ImageViewer(im_col, scale=0.5, vmin=0, vmax=1) # ImageViewer(im_row, scale=0.5, vmin=0, vmax=1) ImageViewer(background, vmin=0, vmax=1) ImageViewer(foreground, vmin=0, vmax=1) ImageViewer(foreground_pure, vmin=0, vmax=1) plt.figure() plt.plot(dislocation_profile) view.show() sys.exit() return foreground
def feature_extraction(im, features, already_cropped=False): t_start = timeit.default_timer() # rotation & cropping rotated = cropping.correct_cell_rotation(im, features, already_cropped=already_cropped) cropped = cropping.crop_cell(rotated, im, features, width=None, already_cropped=already_cropped) features['_cropped_f32'] = cropped features['im_cropped_u16'] = cropped.astype(np.uint16) h, w = cropped.shape if False: plt.figure() plt.plot(cropped.mean(axis=0)) view = ImageViewer(im) ImageViewer(rotated) ImageViewer(cropped) view.show() # find fingers, busbars, etc cell.cell_structure(cropped, features) if False: view = ImageViewer(cropped) ImageViewer(features['bl_cropped_u8']) view.show() sys.exit() # normalise ip.histogram_percentiles(cropped, features, center_y=h // 2, center_x=w // 2, radius=features['wafer_radius']) cell.normalise(cropped, features) norm = features['im_norm'] if False: view = ImageViewer(cropped) ImageViewer(norm) view.show() sys.exit() # full-size cell with no fingers/busbars cell.remove_cell_template(norm, features) if False: view = ImageViewer(norm) # ImageViewer(im_peaks) ImageViewer(features['im_no_fingers']) ImageViewer(features['im_no_figners_bbs']) view.show() sys.exit() if False: import os, glob folder = r"C:\Users\Neil\Desktop\crack_interp" fns = glob.glob(os.path.join(folder, "*.*")) fn_out = os.path.join(folder, "flat_%03d.png" % len(fns)) im_out = (255 * ip.scale_image(features['im_no_figners_bbs'])).astype(np.uint8) ip.save_image(fn_out, im_out) if 'input_param_skip_features' not in features or int(features['input_param_skip_features']) != 1: # feature extraction finger_defects(features) bright_areas(features) efficiency_analysis(features) cell.multi_cracks(features) # firing_defects(features) # undo rotation if parameters.ORIGINAL_ORIENTATION and features['cell_rotated']: for feature in features.keys(): if ((feature.startswith('im_') or feature.startswith('mask_') or feature.startswith('map_') or feature.startswith('ov_') or feature.startswith('bl_') or feature.startswith('mk_')) and features[feature].ndim == 2): features[feature] = features[feature].T[:, ::-1] if 'impure_edge_side' in features: if features['impure_edge_side'] == 0: features['impure_edge_side'] = 1 elif features['impure_edge_side'] == 2: features['impure_edge_side'] = 3 elif features['impure_edge_side'] == 1: features['impure_edge_side'] = 2 elif features['impure_edge_side'] == 3: features['impure_edge_side'] = 0 # compute runtime t_stop = timeit.default_timer() features['runtime'] = t_stop - t_start