def wrapped(): dataset_path = 'image_data' imgs_list = glob.glob(dataset_path + '/img/*.jpg') random.shuffle(imgs_list) # gather all corresponding masks for each image all_masks_files = glob.glob(dataset_path + '/bool_mask_sep_inst/*.npy') image_to_masks = defaultdict(list) for x in all_masks_files: x = os.path.basename(x) # MaskId := ImageId_MaskNum.npy image_id = x[:x.rindex('_')] image_to_masks[image_id].append(x) for fname in imgs_list: image_id = os.path.basename(fname).rstrip('.jpg') mask_base = random.choice(image_to_masks[image_id]) ref_mask_path = random.choice(all_masks_files) image = skimage.img_as_float( imread(dataset_path + '/img/' + image_id + '.jpg')) mask = np.load(dataset_path + '/bool_mask_sep_inst/' + mask_base) ref_mask = np.load(ref_mask_path) if patch_size is not None: image = sk_resize(image, (patch_size, patch_size)) mask = skimage.img_as_bool( sk_resize(mask * 255., (patch_size, patch_size))) ref_mask = skimage.img_as_bool( sk_resize(ref_mask * 255., (patch_size, patch_size))) if align: ref_mask = align_mask(mask, ref_mask) yield (image, mask, ref_mask)
def read_binary_img(self, flipped, x_img): if self.augment: x_arr, flipped = image_binary_augment_array( x_img, self.prop_image, self.prop_array) x_arr = img_as_bool(x_arr) else: x_arr = np.array(x_img) x_arr = img_as_bool(x_arr) x_arr = np.array(x_arr, dtype=int) return flipped, x_arr
def __data_generation(self, list_ids_temp): # Generates data containing batch_size samples X : (n_samples, *dim, n_channels) x_image_raw = np.zeros((4, *self.dim, self.n_channels)) x_images = {'raw': x_image_raw} if self.finger_feature: finger = [] # Generate data sample = list_ids_temp[0] with Image.open(os.path.join(self.path, sample.split('/')[-1] + '.png')) as x_img: x_img = x_img.convert(mode=self.mode) x_arr_org = np.array(x_img) x_arr_org_zoom = zoom_image(x_arr_org, False, True) x_arr_lr, _ = flip_image(x_arr_org, False) x_arr_lr_zoom = zoom_image(x_arr_lr, False, True) if self.binary_mode: x_images['raw'][0] = np.array(np.expand_dims( img_as_bool(x_arr_org), 2), dtype=int) x_images['raw'][1] = np.array(np.expand_dims( img_as_bool(x_arr_org_zoom), 2), dtype=int) x_images['raw'][2] = np.array(np.expand_dims( img_as_bool(x_arr_lr), 2), dtype=int) x_images['raw'][3] = np.array(np.expand_dims( img_as_bool(x_arr_lr_zoom), 2), dtype=int) else: x_images['raw'][0] = np.expand_dims(x_arr_org, 2) x_images['raw'][1] = np.expand_dims(x_arr_org_zoom, 2) x_images['raw'][2] = np.expand_dims(x_arr_lr, 2) x_images['raw'][3] = np.expand_dims(x_arr_lr_zoom, 2) if self.finger_feature: index = int(sample[-2:]) for _ in range(4): finger.append(index - 1) if self.finger_feature: x_images['finger'] = keras.utils.to_categorical(finger, num_classes=10) return x_images
def unet_pred(img, mean, mod): prev_shape = img.shape[0:2] img = resize(img, (512, 512), order=0, preserve_range=True, mode='reflect', anti_aliasing=True).astype(img.dtype) unet_img = expend(img, 92, 92) #mask = model.predict(rgb, mean=mean_array)['predictions'].astype('uint8') dic_mask = slidding_window_predict(unet_img, mean, mod) dic_mask['predictions'][dic_mask['predictions'] > 0] = 255 dic_mask['predictions'] = img_as_bool( resize(dic_mask['predictions'], prev_shape, order=0, preserve_range=True, mode='reflect', anti_aliasing=True)) dic_mask['probability'] = resize(dic_mask['probability'], prev_shape, order=0, preserve_range=True, mode='reflect', anti_aliasing=True).astype( dic_mask['probability'].dtype) return dic_mask
def budget_binary_dilation(img, radius, fac=2): if radius < 0: return np.ones(img.shape, dtype=np.bool) ori_shape = img.shape # plt.imshow (img) # plt.show () if (len(img.shape) == 3): img = img[::fac, ::fac, ::fac] img = binary_dilation(img, ball(radius // fac)) else: img = img[::fac, ::fac] img = binary_dilation(img, disk(radius // fac)) # plt.imshow (img) # plt.show () with warnings.catch_warnings(): warnings.simplefilter("ignore") img = img_as_bool( resize(img, ori_shape, order=cv2.INTER_NEAREST, mode='reflect', anti_aliasing=False)) # plt.imshow (img) # plt.show () return img
def graph_build(): name = "Cables" thresh = 127 threshold(name + ".jpg", thresh) img = img_as_bool( color.rgb2gray(io.imread("Cables_threshold_{}.jpg".format(thresh)))) ske = skeletonize(~img).astype(np.uint16) # build graph from skeleton graph = sknw.build_sknw(ske) # draw image plt.imshow(img, cmap='gray') manager = plt.get_current_fig_manager() manager.resize(*manager.window.maxsize()) # draw edges by pts for (s, e) in graph.edges(): ps = graph[s][e]['pts'] plt.plot(ps[:, 1], ps[:, 0], 'green') # draw node by o nodes = graph.nodes() ps = np.array([nodes[i]['o'] for i in nodes]) plt.plot(ps[:, 1], ps[:, 0], 'r.') # title and show plt.title('') plt.axis('off') plt.show()
def read_train_data(train_path, d=3): train_ids = next(os.walk(train_path))[1] train_images = [] train_masks = [] train_labels = [] for id_ in tqdm(train_ids, desc='Reading train data..'): path = train_path + id_ image_file = next(os.walk(path + '/images/'))[2][0] image = img_as_ubyte( cv2.imread(path + '/images/' + image_file)[:, :, :d]) train_images.append(image) mask = None label = None for i, mask_file in enumerate(next(os.walk(path + '/masks/'))[2]): mask_ = img_as_bool(cv2.imread(path + '/masks/' + mask_file)) if len(mask_.shape) > 2: mask_ = mask_[..., 0] if mask is None: mask = np.zeros_like(mask_) if label is None: label = np.zeros_like(mask_, dtype=int) mask = np.maximum(mask, mask_) label += (i + 1) * mask_ train_masks.append(img_as_float(mask)) train_labels.append(label) return train_ids, train_images, train_masks, train_labels
def img2line(img): """Convert an image to a sequence of indexes Parameters ---------- img : 2d array_like image to extract line from Returns ------- iseq : array 1d sequnce of i coordinates jseq : array 1d sequnce of j coordinates """ img = img_as_bool(img) Ns = sum(img, axis=1) N = sum(Ns) ni, nj = img.shape jrange = np.arange(nj) iseq = np.zeros(N, dtype=int) jseq = np.zeros(N, dtype=int) ii = iseq jj = jseq for i, n in enumerate(Ns): ii, ii[:n] = ii[:n], i jj, jj[:n] = jj[:n], jrange[img[i, :] == 1] assert not ii assert not jj return iseq, jseq
def image_with_sections_contounered_in_cicle(img): circle_image_mask = create_internal_circle_mask(img) inverted_circle_image_mask = np.logical_not(circle_image_mask) img = cv2.multiply(img, circle_image_mask) edges = cv2.Canny(img,CANNY_THRESHOLD,CANNY_THRESHOLD) final_sobely = np.uint8(edges) final_image = np.zeros([img.shape[0],img.shape[1],1], dtype=np.uint8) thresh_gaussian = cv2.adaptiveThreshold(final_sobely,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,ADAPTATIVE_THRESHOLD_BLOCK_SIZE,ADAPTATIVE_THRESHOLD_C) (contours,hierarchy) = cv2.findContours(thresh_gaussian,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) contours = [c for c in contours if cv2.contourArea(c) > MIN_CONTOUR_AREA ] #remove smalls final_contours = [contour_validation(img,idx,c,inverted_circle_image_mask) for idx,c in enumerate(contours)] inner_holes = [c[0] for c in final_contours if c[1]] cv2.drawContours(final_image, inner_holes, -1, (255), 1) cv2.fillPoly(final_image, inner_holes, color=(255)) vessels = [c[0] for c in final_contours if not c[1]] cv2.drawContours(final_image, vessels, -1, (255), 1) cv2.fillPoly(final_image, vessels, color=(255)) final_image_bit = skimage.img_as_bool(cv2.bitwise_not(final_image)) final_image_bit = np.bitwise_and(final_image_bit,circle_image_mask) return final_image_bit,inner_holes,final_image
def resize_reshape(self, resize, width, height): """ Resizes each scan and target segmentation image of a patient to a given width and height. It also turns the target into a one-hot encoded tensor of shape: [depth, width, height, num_classes]. Args: resize (bool): Whether to resize or not the scans. width (int): Width to resize all scans and targets in dataset. height (int): Height to resize all scans and targets in dataset. """ # resize scans if resize: depth = self.scans.shape[0] scans = skimage.transform.resize(image=self.scans, output_shape=(depth, width, height)) self.scans = scans # turns target into one-hot tensor, adopted from: # https://stackoverflow.com/a/36960495 n_classes = self.seg.max() + 1 seg = (np.arange(n_classes) == self.seg[..., None]).astype(bool) # resize targets while preserving their boolean nature if resize: seg = skimage.img_as_bool( skimage.transform.resize(image=seg, output_shape=(depth, width, height, n_classes))) self.seg = seg.astype(int)
def segment(self, image): w, h = image.size image = cv2.resize(np.array(image), self.CCNET_INPUT_SIZE, cv2.INTER_CUBIC) outputs = self.model(Variable( self.input_transform(image).unsqueeze(0))) logprob = self.softmax(outputs).data.cpu().numpy() pred = np.argmax(logprob, axis=1) * 255 pred = Image.fromarray(pred[0].astype(np.uint8)) pred = np.array(pred) # Optional: uncomment the following lines to take only the biggest blob returned by CCNet ''' nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(pred, connectivity=4) if nb_components > 1: sizes = stats[:, -1] max_label = 1 max_size = sizes[1] for i in range(2, nb_components): if sizes[i] > max_size: max_label = i max_size = sizes[i] pred = np.zeros(output.shape) pred[output == max_label] = 255 pred = np.asarray(pred, dtype=np.uint8) ''' # Resize the mask to the original image size pred = img_as_bool( cv2.resize(np.array(pred), (w, h), cv2.INTER_NEAREST)) return pred
def prepare_model(dataset_path: Path = DATASET_PATH, clf_dump_path: Path = CLASSIFIER_DUMP_PATH, dimred_dump_path: Path = None, scaler_dump_path: Path = None): ''' Запускаем один раз, для тренировки модели с последующим сохранением, для дальнейшего использования. :param dataset_path: путь до датасета :param clf_dump_path: путь до дампа классификатора :param dimred_dump_path: путь до дампа декомпозера :param scaler_dump_path: путь до дампа шкалировщика :return: ''' letters = [] flat_images = [] for folder in range(1, 34): path_gen = Path(Path.cwd().parent / dataset_path / str(folder)).glob( '*.jpg') # Создаем генератор путей картинок # Записываем пути картинок paths = [path for path in path_gen if path.is_file()] for i in range(len(paths)): flat_images.append( img_as_ubyte(img_as_bool(img_as_ubyte( imread(paths[i])).ravel()))) letters.append(folder) # Картинка представляется IMG_SIZE * IMG_SIZE признаками (пикселями), # в каждом из которых берем интенсивность белого print( f'Модель учится на {len(paths)} изображениях с разрешением ' f'{IMG_SIZE}x{IMG_SIZE} в 33 категориях.') if dimred_dump_path: try: pca = PCA(n_components=0.9) # Оставляем признаки, объясняющие 90% зависимостей flat_images = pca.fit_transform(flat_images, letters) print(f'Оставлено {pca.n_components_} признаков, объясняющих 90% зависимостей.') dump(pca, Path.cwd().parent / dimred_dump_path) except MemoryError: # fixme Решить проблему с памятью print('Недостаточно памяти для понижения размерности. ' 'Этап понижения размерности пропущен.') pass if scaler_dump_path: scaler = StandardScaler() flat_images = scaler.fit_transform(flat_images) dump(scaler, Path.cwd().parent / scaler_dump_path) # svm_clf = SVC(kernel='poly', degree=2, C=1, cache_size=1000) # svm_clf.fit(flat_images, letters) rf_clf = RandomForestClassifier(n_estimators=750, random_state=1, n_jobs=-1, verbose=True) rf_clf.fit(flat_images, letters) dump(rf_clf, Path.cwd().parent / clf_dump_path) print(f'Модель обучена. Дамп модели сохранен в {clf_dump_path}')
def disk(mesh, center, pat, profile, gap): npat = np.copy(pat) rad1 = [center[0]] rad2 = [center[1]] r1 = np.asarray(rad1) r2 = np.asarray(rad2) # print(type(r1), type(r2), np.shape(r1), np.shape(r2)) for j in range(len(profile)): r2j = float(rad1[int(j)]) + float(profile[int(j)]) rad2.append(r2j) r1jj = float(rad2[int(j)]) + float(gap) * 0.3 rad1.append(r1jj) value = 0 for i in rad1[::-1]: value = (value + 1) % 2 Rad = i * 2 print(i, j) # circ = OsiteDif(mesh, r1, r2, pat, value, Rad); circ = Osite(mesh, i, j, pat) bpatBW = Im2bin(pat) #It seems DMD doesn't with this format only dummie = sk.img_as_bool(bpatBW)
def img_as_MNIST(self, img, mask): """ Transform the digit image so that it looks like a MNIST image in term of range ang shape. """ # put image in grayscale img = skimage.color.rgb2gray(img) # resize max_axis to 28 img = self._resize_max(img, 23) mask = self._resize_max(mask, 23) # pad to 28,28 h, w = img.shape pad_h = (int(np.ceil((28 - h) / 2)), int(np.floor((28 - h) / 2))) pad_w = (int(np.ceil((28 - w) / 2)), int(np.floor((28 - w) / 2))) img = skimage.util.pad(img, (pad_h, pad_w), constant_values=0) mask = skimage.util.pad(mask, (pad_h, pad_w), constant_values=0) # inverse colorspace and mask image img_masked = (255 - skimage.img_as_ubyte(img)) * skimage.img_as_bool(mask) # contrast stretch of images --> saturate upper 1% of pixel img_masked = skimage.exposure.rescale_intensity( img_masked, in_range=(0, np.percentile(img_masked, 100)), out_range=(0, 255)) return img_masked
def get_iou(img, mask): img_mask = img[:, :, 3] > 0 mask_resized = img_as_bool(resize(mask, img_mask.shape)) overlap = img_mask * mask_resized # Logical AND union = img_mask + mask_resized # Logical OR IOU = overlap.sum() / float(union.sum()) return IOU
def cv2_resize(array, size=500, is_bool=False): if is_bool: return np.array([img_as_bool(resize(x, (size, size))) for x in array]) return np.array([ resize(x, (size, size), preserve_range=True).astype("uint8") for x in array ])
def skeletonization(): from skimage import img_as_bool, io, color, morphology image = img_as_bool(color.rgb2gray(io.imread('planC2V2black.tiff'))) out = morphology.medial_axis(image) f, (ax0, ax1) = plt.subplots(1, 2) ax0.imshow(image, cmap='gray', interpolation='nearest') ax1.imshow(out, cmap='gray', interpolation='nearest') DefaultSize = plt.get_size_inches() plt.set_figsize_inches( (DefaultSize[0]*2, DefaultSize[1]*2) ) plt.savefig("test.png", dpi = (1000)) plt.show() res = [] for i in range(len(out)): res.append([]) for j in range(len(out[0])): if out[i][j]: res[i].append('1') else: if imarray[i][j][0] == 255: ##cette partie a ete modifiee pour garder les murs en memoire res[i].append('2') else: res[i].append('0') #print(res) #affCouleurs(suppParasites(res)) return res
def thinning(image, foreground_bias=10): """given a RGB image, get its foreground skeleton :param image: 3-channel image :param foreground_bias: bias ostu theshold value to make sure all fishes are foreground :return: thinned image which is a binary image """ start = time() # binarization gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # gray = cv2.GaussianBlur(gray, (3, 3), 0) res, _ = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY) # + cv2.THRESH_OTSU res, binary = cv2.threshold(gray, res + foreground_bias, 255, cv2.THRESH_BINARY) binary = cv2.bitwise_not(binary) # remove fish fins kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) erosion = cv2.erode(binary, kernel, iterations=1) dilation = cv2.dilate(erosion, kernel, iterations=1) # perform skeletonization or thinning bn = img_as_bool(dilation, force_copy=True) skeleton = skeletonize(bn) thin_img = img_as_ubyte(skeleton) cv2.imshow('thin_img', dilation) print('--- thinning taking time: {:.2f}'.format(time() - start)) return thin_img
def disk2(mesh, center, pat, profile, gap): #copy of the original pattern to be modify npat = np.copy(pat); x0 = [center[0]]; y0 = [center[1]]; #for loop for the creation of the different rings for j in range(len(profile)): r2j = float(x0[int(j)]) + float(profile[int(j)]); y0.append(r2j); r1jj = float(y0[int(j)]) + float(gap)*0.3; x0.append(r1jj); value = 0; for i in x0[::-1]: value = (value+1)%2; Rad = i*2; circ = OsiteDif(mesh, center[0], center[1], pat, value, Rad); #getting bin image of pattern bpatBW = Im2bin(pat); #It seems DMD doesn't with this format only # bpat = sk.color.grey2rgb(rpat); #In case RGB format is need dummie = sk.img_as_bool(bpatBW);
def get_branch_meas(path): read_lab_skel = img_as_bool(color.rgb2gray(io.imread(path))) lab_skel = skeletonize(read_lab_skel).astype("uint8") branch_data = summarise(lab_skel) curve_ind = [] for bd, ed in zip(branch_data["branch-distance"], branch_data["euclidean-distance"]): if ed != 0.0: curve_ind.append((bd - ed) / ed) else: curve_ind.append(bd - ed) branch_data["curvature-index"] = curve_ind grouped_branch_data_mean = branch_data.groupby(["skeleton-id"], as_index=False).mean() grouped_branch_data_sum = branch_data.groupby(["skeleton-id"], as_index=False).sum() counter = collections.Counter(branch_data["skeleton-id"]) n_branches = [] for i in grouped_branch_data_mean["skeleton-id"]: n_branches.append(counter[i]) branch_len = grouped_branch_data_mean["branch-distance"].tolist() tot_branch_len = grouped_branch_data_sum["branch-distance"].tolist() curv_ind = grouped_branch_data_mean["curvature-index"].tolist() return n_branches, branch_len, tot_branch_len, curv_ind
def __init__(self, input_path, output_path): """ Конструктор """ # @var input_path string - Путь к входному изображению # @var output_path string - Путь к выходному изображению self.image = img_as_bool(io.imread(input_path)) self.output_path = output_path
def preprocess_train(self): max_s = self.params['max_scans'] w, h = self.params['train_img_size'] n_classes = self.params['num_classes'] datas = [] labels = [] self.train_volume = [] for i, nii in enumerate(self.train_niis): data = nii[0].get_data() label = nii[1].get_data() depth = np.shape(data)[-1] data = np.moveaxis(data, -1, 0) min, max, data = normalize(data) data = skimage.transform.resize(image=data, output_shape=(depth, w, h)) data = np.expand_dims(data, -1) label = np.moveaxis(label, -1, 0) label = (np.arange(n_classes) == label[..., None]).astype(bool) label = skimage.img_as_bool( skimage.transform.resize(image=label, output_shape=(depth, w, h, n_classes))) label = label.astype(int) self.train_volume.append([]) de = 0 while de < depth: begin = de - self.overlap begin = begin if begin >= 0 else 0 end = begin + max_s end = end if end < depth else depth self.train_volume[i].append([begin, end]) data_volume = data[begin:end, :, :, :] label_volume = label[begin:end, :, :, :] d = end - begin if d < max_s: zerod = np.zeros((max_s - d, w, h, 1)) zerol = np.zeros((max_s - d, w, h, n_classes)) data_volume = np.concatenate((data_volume, zerod)) label_volume = np.concatenate((label_volume, zerol)) datas.append(data_volume) labels.append(label_volume) de = end print("preprocess train data %s" % i) self._datas = np.asarray(datas, dtype=np.float32) self._labels = np.asarray(labels, dtype=np.int32)
def check_chord_or_beam(img_input, staff_space): ''' **img is assumed to be binarized returns: 0 --> chord 1 --> beam /16 2 --> beam /32 -1 --> neither ''' se = sk.morphology.disk(staff_space//2-1) # img = sk.morphology.binary_opening(img_input, se) # img = sk.morphology.binary_erosion(img, se) # img = sk.morphology.binary_erosion(img) # se = sk.morphology.disk(staff_space//4) # img = sk.morphology.binary_dilation(img, se) img = sk.morphology.binary_opening(img_input, se) # show_images([img]) # se = sk.morphology.disk((staff_space//3)) se = sk.morphology.disk(staff_space//4) img = sk.morphology.binary_erosion(img) img = sk.morphology.binary_dilation(img) se = sk.morphology.disk(staff_space//2-1) img = sk.morphology.binary_erosion(img, se) # img = sk.morphology.binary_erosion(img) se = sk.morphology.disk(staff_space//8+1) img = sk.morphology.binary_dilation(img, se) img = sk.morphology.binary_erosion(img) # show_images([img]) bounding_boxes = sk.measure.find_contours(img, 0.8) if len(bounding_boxes) < 2: return -1 newImg = img.copy() centers, count_disks_spacing = [], 0 for box in bounding_boxes: [Xmin, Xmax, Ymin, Ymax] = [np.min(box[:, 1]), np.max( box[:, 1]), np.min(box[:, 0]), np.max(box[:, 0])] centers.append([Ymin+Ymin//2, Xmin+Xmin//2]) for i in range(1, len(centers)): if abs(centers[i][1] - centers[i-1][1]) > 2*staff_space: count_disks_spacing += 1 if count_disks_spacing != len(centers)-1: return 0 img = sk.morphology.thin(sk.img_as_bool(img_input)) h, theta, d = sk.transform.hough_line(img) h, theta, d = sk.transform.hough_line_peaks(h, theta, d) angels = np.rad2deg(theta) number_of_lines = np.sum(np.abs(angels) > 10) if number_of_lines < 1 or number_of_lines > 2: return -1 else: return number_of_lines
def complete(img): image = img_as_bool(io.imread(img)) out = ndi.distance_transform_edt(~image) out = out < 0.02 * out.max() out = morphology.skeletonize(out) out = segmentation.clear_border(out) out = out | image cv2.imwrite('gaps_filled.jpg', out)
def train(): np.random.seed(0) patch_size = 512 batch_size = 8 images, masks = load_parsed_sod() images = np.array([resize(im, (patch_size, patch_size)) for im in images]) masks = np.array([ np.expand_dims( skimage.img_as_bool( resize(skimage.img_as_float(ms), (patch_size, patch_size))), 2) for ms in masks ]) sess = tf.Session() net = ParameterizedUNet(patch_size=patch_size) net.build() sess.run(tf.global_variables_initializer()) print("start training") for epoch in range(500): out_im = None truth_img = None tweaked = None truth_mask = None index = np.arange(len(images)) np.random.shuffle(index) for i, batch_index in enumerate( np.array_split(index, len(index) // batch_size)): truth_img = images[batch_index] truth_mask = masks[batch_index] tweaked = [ tweak_foreground(im, ms) for im, ms in zip(truth_img, truth_mask) ] # TODO: tweaked is in (0, 1) which is good but why _, loss, out_im = sess.run( [net.train_op, net.loss, net.output_img], feed_dict={ net.input_img: tweaked, net.input_mask: truth_mask, net.truth_img: truth_img }) print('epoch', epoch, 'batch', i, loss, flush=True) else: plt.subplot(2, 3, 1) plt.imshow(tweaked[0]) plt.title('Input') plt.subplot(2, 3, 2) plt.imshow(truth_img[0]) plt.title('Truth') plt.subplot(2, 3, 3) plt.imshow(out_im[0]) plt.title('out') plt.subplot(2, 3, 5) plt.imshow(truth_mask[0]) plt.savefig(f'tmp/{epoch}.png') plt.close()
def binary_image(dst1, t): for i in range(dst1.shape[0]): for j in range(dst1.shape[1]): if (dst1[i, j] <= t): dst1[i, j] = 0 else: dst1[i, j] = 1 dst1 = img_as_bool(dst1) return dst1
def fillInContours(img): img = img_as_bool(img) img_out = ndi.distance_transform_edt(~img) img_out = img_out < 0.05 * img_out.max() img_out = morphology.skeletonize(img_out) img_out = morphology.binary_dilation(img_out, morphology.selem.disk(1)) img_out = segmentation.clear_border(img_out) img_out = img_out | img return img_out
def main(input_data_path, output_data_path, window): """ Convert the Volumetric CT data and mask (in NIfTI format) to a dataset of 2D images in tif and masks in bitmap for the brain extraction. """ # open data info dataframe info_df = pd.read_csv(os.path.join(input_data_path, 'info.csv'), index_col=0) # make patient directory if not os.path.exists(output_data_path): os.mkdir(output_data_path) # iterate over volume to extract data output_info = [] for n, id in enumerate(info_df.id.values): # read nii volume ct_nii = nib.load(os.path.join(input_data_path, f'ct_scans/{id}.nii')) mask_nii = nib.load(os.path.join(input_data_path, f'masks/{id}.nii.gz')) # get np.array ct_vol = ct_nii.get_fdata() mask_vol = skimage.img_as_bool(mask_nii.get_fdata()) # rotate 90° counter clockwise for head pointing upward ct_vol = np.rot90(ct_vol, axes=(0,1)) mask_vol = np.rot90(mask_vol, axes=(0,1)) # window the ct volume to get better contrast of soft tissues if window is not None: ct_vol = window_ct(ct_vol, win_center=window[0], win_width=window[1], out_range=(0,1)) if mask_vol.shape != ct_vol.shape: print(f'>>> Warning! The ct volume of patient {id} does not have ' f'the same dimension as the ground truth. CT ({ct_vol.shape}) vs Mask ({mask_vol.shape})') # make patient directory if not os.path.exists(os.path.join(output_data_path, f'{id:03}/ct/')): os.makedirs(os.path.join(output_data_path, f'{id:03}/ct/')) if not os.path.exists(os.path.join(output_data_path, f'{id:03}/mask/')): os.makedirs(os.path.join(output_data_path, f'{id:03}/mask/')) # iterate over slices to save slices for i, slice in enumerate(range(ct_vol.shape[2])): ct_slice_fn =f'{id:03}/ct/{slice+1}.tif' # save CT slice skimage.io.imsave(os.path.join(output_data_path, ct_slice_fn), ct_vol[:,:,slice], check_contrast=False) is_low = True if skimage.exposure.is_low_contrast(ct_vol[:,:,slice]) else False # save mask if some brain on slice if np.any(mask_vol[:,:,slice]): mask_slice_fn = f'{id:03}/mask/{slice+1}_Seg.bmp' skimage.io.imsave(os.path.join(output_data_path, mask_slice_fn), skimage.img_as_ubyte(mask_vol[:,:,slice]), check_contrast=False) else: mask_slice_fn = 'None' # add info to output list output_info.append({'volume':id, 'slice':slice+1, 'ct_fn':ct_slice_fn, 'mask_fn':mask_slice_fn, 'low_contrast_ct':is_low}) print_progessbar(i, ct_vol.shape[2], Name=f'Volume {id:03} {n+1:03}/{len(info_df.id):03}', Size=20, erase=False) # Make dataframe of outputs output_info_df = pd.DataFrame(output_info) # save df output_info_df.to_csv(os.path.join(output_data_path, 'slice_info.csv')) print('>>> Slice informations saved at ' + os.path.join(output_data_path, 'slice_info.csv')) # save patient df info_df.to_csv(os.path.join(output_data_path, 'volume_info.csv')) print('>>> Volume informations saved at ' + os.path.join(output_data_path, 'volume_info.csv'))
def medial_axis_image(thresh): #convert an image from OpenCV to skimage thresh_sk = img_as_float(thresh) image_bw = img_as_bool((thresh_sk)) image_medial_axis = medial_axis(image_bw) return image_medial_axis
def fillgaps(impath,am = 0.05): image = img_as_bool(io.imread(impath)) out = ndi.distance_transform_edt(~image) out = out < am * out.max() out = morphology.skeletonize(out) out = morphology.binary_dilation(out, morphology.selem.disk(1)) out = segmentation.clear_border(out) out = out | image return out
def img2bool(grayimage, **kwargs): """ Allow for *args, **kwargs to be passed """ return img_as_bool(grayimage)
1. Erosion <-> Dilation 2. Opening <-> Closing 3. White tophat <-> Black tophat Skeletonize =========== Thinning is used to reduce each connected component in a binary image to a *single-pixel wide skeleton*. It is important to note that this is performed on binary images only. """ from skimage import img_as_bool horse = ~img_as_bool(io.imread(data_dir+'/horse.png', as_grey=True)) sk = skeletonize(horse) plot_comparison(horse, sk, 'skeletonize') """ .. image:: PLOT2RST.current_figure As the name suggests, this technique is used to thin the image to 1-pixel wide skeleton by applying thinning successively. Convex hull =========== The ``convex_hull_image`` is the *set of pixels included in the smallest
def Flatten2DMphMath(image, **kwargs): # GOAL: flatten the 2d image using some morpho mat and warping # Parameters - check kawrgs.pop ### Original pipeline proposed by: ### Liu et al. "Automated macular pathology diagnosis in retinal OCT images using multi-scale spatial pyramid and ### local binary patterns in texture and shape encoding", Medical Image Anlysis 15 (2011) ### 1. Thresholding ### 2. Median filtering ### 3. Closing + opening ### 4. Fitting via 2nd order polynomial ### 5. Warping the entire image to get a straight line # ----- 1. THRESHOLDING ----- # # PARAMETERS ### Get the type of threshold needed to segment the image thres_type = kwargs.pop('thres_type', 'static') if (thres_type == 'static'): # Get the threshold if specified thres_val = kwargs.pop('thres_val', .2) # By default the static threshold will be .2 elif (thres_type == 'otsu'): # Import the threshold otsu from skimage from skimage.filters import threshold_otsu thres_val = threshold_otsu(image) else: raise ValueError('protoclass.preprocessing.flattening.Flatten2DMphMath: Unrecognise type of thresholding.') # PROCESSING ### Apply the thresholding bin_img = (image > thres_val) # ----- 2. MEDIAN FILTERING ----- # # PARAMETERS ### Get the morphological operator for the median filtering median_kernel_type = kwargs.pop('median_kernel_type', 'square') # Default type of kernel square median_kernel_size = kwargs.pop('median_kernel_size', 5) # Default kernel size 5 if (median_kernel_type == 'square'): from skimage.morphology import square median_kernel = square(median_kernel_size) elif (median_kernel_type == 'disk'): from skimage.morphology import disk median_kernel = disk(median_kernel_size) else: raise ValueError('protoclass.preprocessing.flattening.Flatten2DMphMath: Median kernel type unrecognized') # CONVERSION INTO UBYTE from skimage import img_as_ubyte bin_img_uint8 = img_as_ubyte(bin_img) # PROCESSING from skimage.filters import median bin_filt_img_uint8 = median(bin_img_uint8, median_kernel) # CONVERSION INTO BOOL from skimage import img_as_bool bin_filt_img = img_as_bool(bin_filt_img_uint8) # ----- 3. MORPHO MATH ----- # # PARAMETERS ### Get the morphological operator for the opening operation opening_kernel_type = kwargs.pop('opening_kernel_type', 'disk') # Default type of kernel disk opening_kernel_size = kwargs.pop('opening_kernel_size', 5) # Default kernel size 5 if (opening_kernel_type == 'square'): from skimage.morphology import square opening_kernel = square(opening_kernel_size) elif (opening_kernel_type == 'disk'): from skimage.morphology import disk opening_kernel = disk(opening_kernel_size) else: raise ValueError('protoclass.preprocessing.flattening.Flatten2DMphMath: Opening kernel type unrecognized') ### Get the morphological operator for the closing operation closing_kernel_type = kwargs.pop('closing_kernel_type', 'disk') # Default type of kernel disk closing_kernel_size = kwargs.pop('closing_kernel_size', 35) # Default kernel size 35 if (closing_kernel_type == 'square'): from skimage.morphology import square closing_kernel = square(closing_kernel_size) elif (closing_kernel_type == 'disk'): from skimage.morphology import disk closing_kernel = disk(closing_kernel_size) else: raise ValueError('protoclass.preprocessing.flattening.Flatten2DMphMath: Closing kernel type unrecognized') # PROCESSING ### Apply a closing operation from skimage.morphology import binary_closing bin_closing = binary_closing(bin_filt_img, closing_kernel) ### Apply an opening operation from skimage.morphology import binary_opening bin_opening = binary_opening(bin_closing, opening_kernel) # ----- 4. POLYNOMIAL FITTING ----- # # PROCESSING ### Get the x,y position of True value in the binary image y_img, x_img = np.nonzero(bin_opening) ### Fit a second order polynomial x_interp = np.arange(bin_opening.shape[1]) p_fitted = np.poly1d(np.polyfit(x_img, y_img, 2)) y_interp = p_fitted(x_interp) # ----- 5. WARPING OF THE IMAGE ----- # ### Allocate the memory for the image warped_img = np.zeros(image.shape) ### Get each column of the original image ### Get the minimum y of the interpolated value in order to align the value to this baseline baseline_y = np.min(y_interp) for col_ind, col_img in enumerate(image.T): ### Compute the distance to apply the rolling dist_roll = int(np.round(baseline_y - y_interp[col_ind])) ### Assign the new column to the warped image warped_img[:, col_ind] = np.roll(col_img, dist_roll) # Finally return the unflatten image return (np.round(baseline_y), warped_img)
def run(self, workspace): self.function = lambda(x_data): skimage.measure.label(skimage.img_as_bool(x_data)) super(ConvertImageToObjects, self).run(workspace)
#Don't forget to change the file range in the following line - (for f in files[0:1000]:) ############################################################### ############################################################### #Writes features to CSV #Path to Training pics library #trainImgs = "/home/kwyn/GalaxyQuest/images_training_rev1/" #Looping through the trainImgs directory with open(outputFilename, 'wb') as csvfile: writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) a = [0] * numFeatures writer.writerow(a) for root, dirs, files in os.walk(inputImgs): #sort file names into numeric order files = sorted(files) for f in files[0:10000]: galName = np.array(f[:-4]) path = inputImgs + f img = io.imread(path, as_grey=True) cropped = img[137:287,137:287] resized = resize(cropped, (20,20)) im = ~img_as_bool(resized) # selem = disk(6) # d = dilation(resized, selem) sk = skeletonize(im) i = np.vstack(sk) flat = i.flatten() total = np.append(galName, flat) writer.writerow(total)
def doProcessing(self): print("========== AccivImageProcessing: Process Frames =========") # load experiment settings self.allExpSet = AttrMap(self.cF.jsonLoad(self.cS.experimentSettingsFile)) ex = "%i" % self.cS.experimentNumber if ex not in self.allExpSet["experiments"]: raise ValueError("Experiment number %i not found in %s" % (self.cS.experimentNumber, self.cS.experimentSettingsFile)) # make experiment settings self.expSet = AttrMap(self.allExpSet["experiments"][ex]) print("Experiment Settings: ", self.expSet) # load intensity shift values if we have a numpy .npz file try: l=self.cF.jsonLoad(self.cS.intensityShift) self.intensityShift = dict(l) print("Loaded %i intensity shift values" % len(self.intensityShift) ) except: self.intensityShift = None print("No intensity shift values found! -> using none") # load background image # and try to shift intensity self.cS.background = self.loadImage( self.cS.backgroundFile ) if self.intensityShift is not None and self.intensityShift: try: frameIdx = int(re.match(self.cS.frameExtractRegex, self.cS.backgroundFile).group(1)) shiftI = self.intensityShift[frameIdx] print("Shift background intensity by -%f" % shiftI) self.cS.background -= shiftI; except: print("Did not shift background intensity") # load additional mask if "additionalMask" in self.cS and os.path.exists(self.cS.additionalMask): self.cS.additionalMask = img_as_bool(imread(self.cS.additionalMask)) else: self.cS.additionalMask = None # set height/width self.cS.height = self.cS.background.shape[0]; self.cS.width = self.cS.background.shape[1]; self.cS.mask = np.ones(self.cS.background.shape,np.uint8) # bounds (with x-Axis to the right, y-Axis up, like ACCIV) if "offsetZero" not in self.expSet: self.expSet.offsetZero = [0,0] min=self.expSet.aabbMeterCoordinates["minPoint"] max=self.expSet.aabbMeterCoordinates["maxPoint"] self.cS.bounds = np.array([ min[0], max[0], min[1],max[1] ] ) # process all frames for frame in self.fr: self._processFrame(frame) print("============== AccivImageProcessing: finished ===========")
mindist.append(pairwise.min()) # Tissue to sinusoid ratio tissue = np.sum(ski.img_as_bool(Es) * (1 - ski.img_as_bool(total))) sinusoids = np.sum(Es.shape[0] * Es.shape[1] - np.sum(ski.img_as_bool(total))) ratio.append(tissue.astype(float) / sinusoids) # Pickle results results = {} results["ratio"] = ratio results["inflcount"] = inflcount