def removeNoise(img, r=7): # Creating a circle inside an array c = r # Center d = 2 * r + 1 # Diameter y, x = np.ogrid[-c:d-c, -c:d-c] # Create a True/False grid in numpy mask = x * x + y * y <= r * r # Circular shape structuringElement = np.zeros((d, d)) structuringElement[mask] = 1 # Fill ones at the places with True # Applying erosion at the binary image eroded = erosion(img, structuringElement) # Dilate the remaining pixels from the eroded image dilated = dilation(eroded, structuringElement) # We have now opened the image. Now we need to close it: # We could have done this in the same step as the last, but we want to show all steps dilated2 = dilation(dilated, structuringElement) # Then we close by eroding back to normal eroded2 = erosion(dilated2, structuringElement) return eroded, dilated, dilated2, eroded2
def returnProcessedImage(que,folder,img_flist): X = [] for fname in img_flist: cur_img = imread(folder+'/'+fname , as_grey=True) cur_img = 1 - cur_img ######## randomly add samples # random add contrast r_for_eq = random() cur_img = equalize_adapthist(cur_img,ntiles_x=8,ntiles_y=8,clip_limit=(r_for_eq+0.5)/3) #random morphological operation r_for_mf_1 = random() if 0.05 < r_for_mf_1 < 0.25: # small vessel selem1 = disk(0.5+r_for_mf_1) cur_img = dilation(cur_img,selem1) cur_img = erosion(cur_img,selem1) elif 0.25 < r_for_mf_1 < 0.5: # large vessel selem2 = disk(2.5+r_for_mf_1*3) cur_img = dilation(cur_img,selem2) cur_img = erosion(cur_img,selem2) elif 0.5 < r_for_mf_1 < 0.75: # exudate selem1 = disk(9.21) selem2 = disk(7.21) dilated1 = dilation(cur_img, selem1) dilated2 = dilation(cur_img, selem2) cur_img = np.subtract(dilated1, dilated2) cur_img = img_as_float(cur_img) X.append([cur_img.tolist()]) # X = np.array(X , dtype = theano.config.floatX) que.put(X) return X
def get_internal_wsl(self, labelimage): se = morphology.diamond(1) ero = morphology.erosion(labelimage, se) grad = labelimage - ero res = np.zeros(labelimage.shape) res[grad>0] = 255 return res
def erode(data, erodrN = 2): eroded = data.copy() for i in range(erodrN): eroded = erosion(eroded) return eroded
def get_symbols(image): dil_eros = bin_search(dilatation_cross_numb, [image], (1, 16), 1.0, "dec") block_size = 50 binary_adaptive_image = erosion(dilation(threshold_adaptive( array(image.convert("L")), block_size, offset=10), square(dil_eros)), square(dil_eros)) all_labels = label(binary_adaptive_image, background = True) objects = find_objects(all_labels) av_width = av_height = 0 symbols = [] for obj in objects: symb = (binary_adaptive_image[obj], (obj[0].start, obj[1].start)) symbols.append(symb) av_height += symb[0].shape[0] av_width += symb[0].shape[1] av_width /= float(len(objects)) av_height /= float(len(objects)) symbols = [symb for symb in symbols if symb[0].shape[0] >= av_height and symb[0].shape[1] >= av_width] return symbols
def focus_score(self): f_score = (color.rgb2grey(self.img) - erosion(color.rgb2grey(self.img), square(4))) non_zero_pixel_area = self.get_nonzero_pixel_area(f_score) #print("focus score: " + str(np.sum(f_score) / non_zero_pixel_area)) #plt.imshow(f_score) #plt.show() return np.sum(f_score) / non_zero_pixel_area
def extract_region_opening(img, is_demo=False): """ Extracts fingerprint region of image via mophological opening """ after_median = skimage.filter.rank.median(img, skmorph.disk(9)) after_erode = skmorph.erosion(after_median, skmorph.disk(11)) after_dil = skmorph.dilation(after_erode, skmorph.disk(5)) _, t_dil_img = cv2.threshold(after_dil, 240, 40, cv2.THRESH_BINARY) if is_demo: _, t_med_img = cv2.threshold(after_median, 240, 255, cv2.THRESH_BINARY) _, t_erd_img = cv2.threshold(after_erode, 240, 40, cv2.THRESH_BINARY) erd_gry = t_erd_img.astype(np.uint8) * 255 rgb_erd = np.dstack((erd_gry, img, img)) dil_gry = t_dil_img.astype(np.uint8) * 255 rgb_dil = np.dstack((dil_gry, img, img)) plt.subplot(2,2,1) plt.imshow(after_erode, cmap="gray", interpolation="nearest") plt.subplot(2,2,2) plt.imshow(rgb_erd, interpolation="nearest") plt.subplot(2,2,3) plt.imshow(after_dil, cmap="gray", interpolation="nearest") plt.subplot(2,2,4) plt.imshow(rgb_dil, interpolation="nearest") plt.show() return t_dil_img
def removeChessboard(img): # Get the major lines in the image edges, dilatedEdges, (h, theta, d) = findLines(img) # Create image with ones to fill inn lines lines = np.ones(img.shape[:2]) # Add lines to image as zeroes for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle) x, y = line(int(y1), 0, int(y0), img.shape[1] - 1) x = np.clip(x, 0, img.shape[0] - 1) y = np.clip(y, 0, img.shape[1] - 1) lines[x, y] = 0 # Remove border edges from image with all edges w = 4 edges = np.pad(edges[w:img.shape[0] - w, w:img.shape[1] - w], w, mode='constant') # Erode the lines bigger, such that they cover the original lines lines = erosion(lines, square(13)) # Remove major lines and close shape paths removedChessboard = closing(edges * lines, square(8)) return removedChessboard
def morpho_rec(self, img, size=10): # internal gradient of the cells: se = morphology.diamond(size) ero = morphology.erosion(img, se) rec = morphology.reconstruction(ero, img, method='dilation').astype(np.dtype('uint8')) return rec
def test_morpho2(self, bigsize=20.0, smallsize=3.0, threshold=5.0): img = self.read_H_image() pref = self.morpho_rec(img, 10) filename = os.path.join(test_out_folder, 'morpho_00_rec_%s.png' % self.image_name) skimage.io.imsave(filename, pref) res = self.difference_of_gaussian(pref, bigsize, smallsize) filename = os.path.join(test_out_folder, 'morpho_01_diff_%s_%i_%i.png' % (self.image_name, int(bigsize), int(smallsize))) skimage.io.imsave(filename, res) #res = self.morpho_rec2(diff, 15) #filename = os.path.join(test_out_folder, 'morpho_02_rec_%s.png' % self.image_name) #skimage.io.imsave(filename, res) res[res>threshold] = 255 filename = os.path.join(test_out_folder, 'morpho_03_res_%s_%i.png' % (self.image_name, threshold)) skimage.io.imsave(filename, res) se = morphology.diamond(3) ero = morphology.erosion(res, se) filename = os.path.join(test_out_folder, 'morpho_03_ero_%s_%i.png' % (self.image_name, threshold)) skimage.io.imsave(filename, ero) res[ero>0] = 0 overlay_img = self.overlay(img, res) filename = os.path.join(test_out_folder, 'morpho_04_overlay_%s_%i.png' % (self.image_name, int(threshold))) skimage.io.imsave(filename, overlay_img) return
def detectOpticDisc(image): kernel = octagon(10, 10) thresh = threshold_otsu(image[:,:,1]) binary = image > thresh print binary.dtype luminance = convertToHLS(image)[:,:,2] t = threshold_otsu(luminance) t = erosion(luminance, kernel) labels = segmentation.slic(image[:,:,1], n_segments = 3) out = color.label2rgb(labels, image[:,:,1], kind='avg') skio.imshow(out) x, y = computeCentroid(t) print x, y rows, cols, _ = image.shape p1 = closing(image[:,:,1],kernel) p2 = opening(p1, kernel) p3 = reconstruction(p2, p1, 'dilation') p3 = p3.astype(np.uint8) #g = dilation(p3, kernel)-erosion(p3, kernel) #g = rank.gradient(p3, disk(5)) g = cv2.morphologyEx(p3, cv2.MORPH_GRADIENT, kernel) #markers = rank.gradient(p3, disk(5)) < 10 markers = drawCircle(rows, cols, x, y, 85) #markers = ndimage.label(markers)[0] #skio.imshow(markers) g = g.astype(np.uint8) #g = cv2.cvtColor(g, cv2.COLOR_GRAY2RGB) w = watershed(g, markers) print np.max(w), np.min(w) w = w.astype(np.uint8) #skio.imshow(w) return w
def compute_mask(self, params): """Creates the mask for the base image. Needs the base image, an instance of imageloaderparams and the clip area, which should be already defined by the load_base_image method. Creates the mask by improving the base mask created by the compute_base_mask method. Applies the mask closing, dilation and fill holes parameters. """ self.compute_base_mask(params) mask = np.copy(self.base_mask) closing_matrix = np.ones((params.mask_closing, params.mask_closing)) if params.mask_closing > 0: # removes small dark spots and then small white spots mask = img_as_float(morphology.closing( mask, closing_matrix)) mask = 1 - \ img_as_float(morphology.closing( 1 - mask, closing_matrix)) for f in range(params.mask_dilation): mask = morphology.erosion(mask, np.ones((3, 3))) if params.mask_fill_holes: # mask is inverted mask = 1 - img_as_float(ndimage.binary_fill_holes(1.0 - mask)) self.mask = mask self.overlay_mask_base_image()
def get_rough_detection(self, img, bigsize=40.0, smallsize=4.0, thresh = 0): diff = self.difference_of_gaussian(-img, bigsize, smallsize) diff[diff>thresh] = 1 se = morphology.square(4) ero = morphology.erosion(diff, se) labimage = label(ero) #rec = morphology.reconstruction(ero, img, method='dilation').astype(np.dtype('uint8')) # connectivity=1 corresponds to 4-connectivity. morphology.remove_small_objects(labimage, min_size=600, connectivity=1, in_place=True) #res = np.zeros(img.shape) ero[labimage==0] = 0 ero = 1 - ero labimage = label(ero) morphology.remove_small_objects(labimage, min_size=400, connectivity=1, in_place=True) ero[labimage==0] = 0 res = 1 - ero res[res>0] = 255 #temp = 255 - temp #temp = morphology.remove_small_objects(temp, min_size=400, connectivity=1, in_place=True) #res = 255 - temp return res
def get_distorted(image, params, orient = "horizont"): shifts = [] np_image = array(image.convert("L")) for el in params: if el[0] == "sin": shifts.append(lambda x: np_image.shape[0] / el[1] * \ np.sin(x * el[2] / np_image.shape[1])) if el[0] == "cos": shifts.append(lambda x: np_image.shape[0] / el[1] * \ np.cos(x * el[2] / np_image.shape[1])) if el[0] == "triang": lambda x: np_image.shape[0] / el[1] * \ (x / el[2] / np_image.shape[1] - math.floor(x / (el[2] / np_image.shape[1]))) if el[0] == "erosion": np_image = erosion(np_image, square(el[1])) if el[0] == "dilation": np_image = dilation(np_image, square(el[1])) if orient == "horizont": for idx in xrange(np_image.shape[0]): for shift in shifts: np_image[idx,:] = np.roll(np_image[idx,:], int(shift(idx))) if orient == "vert": for idx in xrange(np_image.shape[1]): for shift in shifts: np_image[:, idx] = np.roll(np_image[:, idx], int(shift(idx))) return Image.fromarray(np_image)
def fill_holes(self, binary_image, selem, iterations): image = binary_image.copy() for j in range(0, iterations): image = dilation(image, selem) image = ndi.binary_fill_holes(image) for j in range(0, iterations): image = erosion(image, selem) return image
def ContourLabeled(bin_image, radius): copied = bin_image.copy() copied = erosion(copied, disk(radius)) contour = bin_image.copy() - copied res = np.zeros_like(bin_image, dtype='uint8') res[bin_image == 1] = 255 res[contour == 1] = 127 return res
def get_large_wsl(self, labelimage): se = morphology.diamond(1) dil = morphology.dilation(labelimage, se) ero = morphology.erosion(labelimage, se) grad = dil - ero res = np.zeros(labelimage.shape) res[grad>0] = 255 return res
def add_contours(rgb_image, contour, ds = 2): """ The image has to be a binary image """ rgb = rgb_image.copy() contour[contour > 0] = 1 boundery = contour - erosion(contour, disk(ds)) rgb[boundery > 0] = np.array([0, 0, 0]) return rgb
def filter_wsl(self, imbin, ws_labels, imin): # internal gradient of the cells: se = morphology.diamond(1) #ero = morphology.erosion(imbin, se) #grad = imbin - ero # watershed line wsl = self.get_external_wsl(ws_labels) #wsl = self.get_large_wsl(ws_labels) wsl_remove = wsl.copy() # watershed line outside the cells is 0 wsl_remove[imbin==0] = 0 # watershed line on the gradient (border of objects) # is also not considered #wsl_remove[grad>0] = 0 # gradient image pref = 255 * filters.gaussian_filter(imin, 3.0) pref[pref < 0] = 0 pref = pref.astype(np.dtype('uint8')) ero = morphology.erosion(pref, se) dil = morphology.dilation(pref, se) grad = dil - ero grad_filtered = grad if self.settings.debug: out_filename = os.path.join(self.settings.img_debug_folder, '%s09_watershed_regions.png' % self.prefix) skimage.io.imsave(out_filename, ws_labels.astype(np.dtype('uint8'))) out_filename = os.path.join(self.settings.img_debug_folder, '%s09_wsl.png' % self.prefix) skimage.io.imsave(out_filename, wsl.astype(np.dtype('uint8'))) out_filename = os.path.join(self.settings.img_debug_folder, '%s09_wsl_remove.png' % self.prefix) skimage.io.imsave(out_filename, wsl_remove.astype(np.dtype('uint8'))) out_filename = os.path.join(self.settings.img_debug_folder, '%s09_wsl_gradient.png' % self.prefix) skimage.io.imsave(out_filename, grad_filtered.astype(np.dtype('uint8'))) labimage = label(wsl_remove) properties = measure.regionprops(labimage, grad_filtered) mean_intensities = np.array([0.0] + [pr.mean_intensity for pr in properties]) filter_intensities = np.where(mean_intensities < self.settings.postfilter['wsl_mean_intensity'], 255, 0) filter_intensities[0] = 0 wsl_remove = filter_intensities[labimage] #print filter_intensities #print mean_intensities wsl[wsl_remove>0] = 0 if self.settings.debug: out_filename = os.path.join(self.settings.img_debug_folder, '%s09_wsl_remove2.png' % self.prefix) skimage.io.imsave(out_filename, wsl_remove.astype(np.dtype('uint8'))) return wsl
def erode(data, radius): """ Erode data using ball structuring element :param data: 2d or 3d array :param radius: radius of structuring element :return: data eroded """ from skimage.morphology import erosion, ball selem = ball(radius) return erosion(data, selem=selem, out=None)
def filter_by_erode_high_frequencies(img): #kernel = np.ones((5,5),np.uint8) #i = ndimage.grey_erosion(img,size=(10,10)) selem = disk(3) #i = erosion(img, selem) #print( "the mean is" + str(np.mean(img))) thresh = threshold_otsu(img) i = img > thresh i = erosion(i, selem) return i
def removeNoise(img, r=7): structuringElement = disk(r) # Applying erosion at the binary image eroded = erosion(img, structuringElement) # Dilate the remaining pixels from the eroded image dilated = dilation(eroded, structuringElement) # We have now opened the image. Now we need to close it: # We could have done this in the same step as the last, but we want to show all steps dilated2 = dilation(dilated, structuringElement) # Then we close by eroding back to normal result = erosion(dilated2, structuringElement) return result
def segmentation_border_image(segmentation, index, width=1): isolated_region = np.zeros(segmentation.image_array.shape, dtype=np.uint8) isolated_region[np.where(segmentation.image_array == index)] = 255 selem = disk(width) border = isolated_region - erosion(isolated_region, selem) return border
def boundaryExtraction(img): # Creating a 3x3 array with ones structuringElement = np.ones((3, 3)) # Applying erosion at the binary image eroded = erosion(img, structuringElement) # Dilate the remaining pixels from the eroded image boundaryExtract = img - eroded return eroded, boundaryExtract
def pre_process_image(image_file): #get the image and resize image_data = ndi.imread(image_file, mode = 'L') resized_image = resize(image_data, (200,200)) 0.6 up_left,low_right = cropper(resized_image,40,0.6) resized_image = resize(resized_image[up_left[0]:low_right[0]+1,up_left[1]:low_right[1]+1], (200,200)) binar = binarize(resized_image, 0.4) undilated = deepcopy(binar) #dilate the binarized image selem = rectangle(1,2) dil = dilation(binar, selem) #binarize dilation dil = binarize(dil) #final = dil final = deepcopy(dil) for i in range(4): for j in range(4): final[i*50+3:i*50+25,j*50+3:j*50+44] = undilated[i*50+3:i*50+25,j*50+3:j*50+44] #Try to remove all borders and grid lines in the image. #Do this by scanning over rows and cols and if more than 25% #of the pixels are <= 0.45 then set the entire row to 1(white) #first rows for row in range(len(final)): count = 0 for pixel in final[row,:]: if pixel == 0: count += 1 if count >= 48: final[row,:] = final[row,:]*0 + 1 #columns for col in range(len(final[0,:])): count = 0 for pixel in final[:,col]: if pixel == 0: count += 1 if count >= 48: final[:,col] = final[:,col]*0 + 1 #add some final erosion (black) to fill out numbers and ensure they're connected final = binarize(erosion(final, rectangle(1,2)),.0000001) return final
def opening_by_reconstruction(img, se): diffImg = True orig_img = img.copy() last_rec = img.copy() while diffImg: er_img = morphology.erosion(img, se) img = morphology.reconstruction(er_img, orig_img) if np.array_equal(last_rec, img): diffImg = False else: last_rec = img.copy() return last_rec
def overlay(self, img, imbin, contour=False): colim = color.gray2rgb(img) colorvalue = (0, 100, 200) if contour: se = morphology.diamond(2) ero = morphology.erosion(imbin, se) grad = imbin - ero colim[grad > 0] = colorvalue else: colim[imbin>0] = colorvalue return colim
def pred_f(image, param=param): # pdb.set_trace() prob_image1, bin_image1 = PredImageFromNet( net_1, image, with_depross=True) segmentation_mask = DynamicWatershedAlias(prob_image1, param) segmentation_mask[segmentation_mask > 0] = 1 contours = dilation(segmentation_mask, disk(2)) - \ erosion(segmentation_mask, disk(2)) x, y = np.where(contours == 1) image[x, y] = np.array([0, 0, 0]) return image
def _getPoseMask(peaks, height, width, radius=4, var=4, mode='Solid'): ## MSCOCO Pose part_str = [nose, neck, Rsho, Relb, Rwri, Lsho, Lelb, Lwri, Rhip, Rkne, Rank, Lhip, Lkne, Lank, Leye, Reye, Lear, Rear, pt19] # find connection in the specified sequence, center 29 is in the position 15 # limbSeq = [[2,3], [2,6], [3,4], [4,5], [6,7], [7,8], [2,9], [9,10], \ # [10,11], [2,12], [12,13], [13,14], [2,1], [1,15], [15,17], \ # [1,16], [16,18], [3,17], [6,18]] # limbSeq = [[2,3], [2,6], [3,4], [4,5], [6,7], [7,8], [2,9], [9,10], \ # [10,11], [2,12], [12,13], [13,14], [2,1], [1,15], [15,17], \ # [1,16], [16,18]] # , [9,12] # limbSeq = [[3,4], [4,5], [6,7], [7,8], [9,10], \ # [10,11], [12,13], [13,14], [2,1], [1,15], [15,17], \ # [1,16], [16,18]] # limbSeq = [[2,3], [2,6], [3,4], [4,5], [6,7], [7,8], [2,9], [9,10], \ [10,11], [2,12], [12,13], [13,14], [2,1], [1,15], [15,17], \ [1,16], [16,18], [2,17], [2,18], [9,12], [12,6], [9,3], [17,18]] # indices = [] values = [] for limb in limbSeq: p0 = peaks[limb[0] -1] p1 = peaks[limb[1] -1] if 0!=len(p0) and 0!=len(p1): r0 = p0[0][1] c0 = p0[0][0] r1 = p1[0][1] c1 = p1[0][0] ind, val = _getSparseKeypoint(r0, c0, 0, height, width, radius, var, mode) indices.extend(ind) values.extend(val) ind, val = _getSparseKeypoint(r1, c1, 0, height, width, radius, var, mode) indices.extend(ind) values.extend(val) distance = np.sqrt((r0-r1)**2 + (c0-c1)**2) sampleN = int(distance/radius) # sampleN = 0 if sampleN>1: for i in xrange(1,sampleN): r = r0 + (r1-r0)*i/sampleN c = c0 + (c1-c0)*i/sampleN ind, val = _getSparseKeypoint(r, c, 0, height, width, radius, var, mode) indices.extend(ind) values.extend(val) shape = [height, width, 1] ## Fill body dense = np.squeeze(_sparse2dense(indices, values, shape)) ## TODO # im = Image.fromarray((dense*255).astype(np.uint8)) # im.save('xxxxx.png') # pdb.set_trace() dense = dilation(dense, square(5)) dense = erosion(dense, square(5)) return dense
def main(arguments): #Read input GeoTIFF file in_data = GeoRead(arguments['IN_FILE']) #--------------------------------------------------------------# # Alogirtihm # Read image -> Scale down to [-1,1] -> Mean_percentile -> #Erosion -> Scale up new image upto original maxima and minima #--------------------------------------------------------------# # Consider the sun spikes as noise print "Reading input GeoTIFF file..." noisy_image = in_data.arys[0] print "The maxima is %f & the minima is %f.\n" %(np.max(noisy_image), np.min(noisy_image)) # Scale array data to [-1,1] so that mean_percentile can implemented print "Scaling input data to [-1,1]..." noisy_image_scaled = scale_down(noisy_image, 1.0, -1.0) print "Done construction of scaled noisy_image.\n" #Disk size for implementing mean percentile #selem = disk(5) #Not good #selem = disk(10) #Can be better selem = disk(15) #selem = disk(20) #Not good #Applying mean percentile print "Applying Mean percentile with p0 = 0.1 & p1 = 0.9..." percentile_result = rank.mean_percentile(noisy_image_scaled, selem=selem, p0=.1, p1=.9) print "Done construction of percentile_result.\n" #Applying erosion. print "Applying erosion to remove the sun spikes..." sun_spikes_removed = erosion(percentile_result, selem) print "Done construction of sun spikes removed scaled down result.\n" #Scaling the final result to original scale print "Scaling the final output to maxima and minima of original image..." sun_spikes_removed_original_scale = scale_up(noisy_image, sun_spikes_removed) print "Process completed.\n" # Writing Output Screen_out = False print "Screen_output is %r." %(Screen_out) write_output(Screen_out, noisy_image, noisy_image_scaled, percentile_result, sun_spikes_removed, sun_spikes_removed_original_scale) #Plot data print "Generating plots..." plot_output(noisy_image, percentile_result, sun_spikes_removed, sun_spikes_removed_original_scale) print "Script completed successfully."
def _get_batches_of_transformed_samples(self, index_array): batch_x = [] batch_y = [] #print(index_array) for batch_index, image_index in enumerate(index_array): row = self.image_table.iloc[image_index] img_id = row.ImageId if img_id in exclude_list: continue img0 = cv2.imread(path.join(images_folder, '{0}'.format(img_id)), cv2.IMREAD_COLOR) mask_path = path.join(masks_folder, '{0}.png'.format(img_id[:-4])) if not os.path.exists(mask_path): msk0 = np.zeros((768, 768, 3)) lbl0 = np.zeros((768, 768)) else: msk0 = cv2.imread(mask_path, cv2.IMREAD_UNCHANGED) lbl0 = cv2.imread( path.join(labels_folder, '{0}.tif'.format(img_id[:-4])), cv2.IMREAD_UNCHANGED) if img0.shape[0] == 0 or msk0.shape[0] == 0 or lbl0.shape[ 0] == 0: img0 = np.zeros((768, 768, 3)) msk0 = np.zeros((768, 768, 3)) lbl0 = np.zeros((768, 768)) # print('mask_path', mask_path) # print('img_shape', img0.shape, 'mask_shape', msk0.shape) tmp = np.zeros_like(msk0[..., 0], dtype='uint8') tmp[1:-1, 1:-1] = msk0[1:-1, 1:-1, 0] good4copy = list( set(np.unique(lbl0[lbl0 > 0])).symmetric_difference( np.unique(lbl0[(lbl0 > 0) & (tmp == 0)]))) x0 = random.randint(0, img0.shape[1] - self.input_shape[1]) y0 = random.randint(0, img0.shape[0] - self.input_shape[0]) img = img0[y0:y0 + self.input_shape[0], x0:x0 + self.input_shape[1], :] msk = msk0[y0:y0 + self.input_shape[0], x0:x0 + self.input_shape[1], :] if len(good4copy) > 0 and random.random() > 0.75: num_copy = random.randrange(1, min(6, len(good4copy) + 1)) lbl_max = lbl0.max() for i in range(num_copy): lbl_max += 1 l_id = random.choice(good4copy) lbl_msk = lbl0 == l_id row, col = np.where(lbl_msk) y1, x1 = np.min(np.where(lbl_msk), axis=1) y2, x2 = np.max(np.where(lbl_msk), axis=1) lbl_msk = lbl_msk[y1:y2 + 1, x1:x2 + 1] lbl_img = img0[y1:y2 + 1, x1:x2 + 1, :] if random.random() > 0.5: lbl_msk = lbl_msk[:, ::-1, ...] lbl_img = lbl_img[:, ::-1, ...] rot = random.randrange(4) if rot > 0: lbl_msk = np.rot90(lbl_msk, k=rot) lbl_img = np.rot90(lbl_img, k=rot) x1 = random.randint( max(0, x0 - lbl_msk.shape[1] // 2), min(img0.shape[1] - lbl_msk.shape[1], x0 + self.input_shape[1] - lbl_msk.shape[1] // 2)) y1 = random.randint( max(0, y0 - lbl_msk.shape[0] // 2), min(img0.shape[0] - lbl_msk.shape[0], y0 + self.input_shape[0] - lbl_msk.shape[0] // 2)) tmp = erosion(lbl_msk, square(5)) lbl_msk_dif = lbl_msk ^ tmp tmp = dilation(lbl_msk, square(5)) lbl_msk_dif = lbl_msk_dif | (tmp ^ lbl_msk) lbl0[y1:y1 + lbl_msk.shape[0], x1:x1 + lbl_msk.shape[1]][lbl_msk] = lbl_max img0[y1:y1 + lbl_msk.shape[0], x1:x1 + lbl_msk.shape[1]][lbl_msk] = lbl_img[lbl_msk] full_diff_mask = np.zeros_like(img0[..., 0], dtype='bool') full_diff_mask[y1:y1 + lbl_msk.shape[0], x1:x1 + lbl_msk.shape[1]] = lbl_msk_dif img0[..., 0][full_diff_mask] = median( img0[..., 0], mask=full_diff_mask)[full_diff_mask] img0[..., 1][full_diff_mask] = median( img0[..., 1], mask=full_diff_mask)[full_diff_mask] img0[..., 2][full_diff_mask] = median( img0[..., 2], mask=full_diff_mask)[full_diff_mask] img = img0[y0:y0 + self.input_shape[0], x0:x0 + self.input_shape[1], :] lbl = lbl0[y0:y0 + self.input_shape[0], x0:x0 + self.input_shape[1]] msk = create_mask(lbl) # return img, msk data = self.random_transformers[0](image=img[..., ::-1], mask=msk) img = data['image'][..., ::-1] msk = data['mask'] msk = msk.astype('float') msk[..., 0] = (msk[..., 0] > 127) * 1 msk[..., 1] = (msk[..., 1] > 127) * (msk[..., 0] == 0) * 1 msk[..., 2] = (msk[..., 1] == 0) * (msk[..., 0] == 0) * 1 otp = msk img = np.concatenate([img, bgr_to_lab(img)], axis=2) batch_x.append(img) batch_y.append(otp) batch_x = np.array(batch_x, dtype="float32") batch_y = np.array(batch_y, dtype="float32") batch_x = preprocess_input(batch_x) return self.transform_batch_x(batch_x), self.transform_batch_y(batch_y)
def process_file(img_id): res_rows = [] msks = [] for pred_folder in pred_folders: msk = cv2.imread(path.join(pred_folder, img_id + '.png'), cv2.IMREAD_UNCHANGED) msk = msk.max(axis=2) if msk.shape[0] < 1306: msk = cv2.resize(msk, (1300, 1300)) msk = np.pad(msk, ((6, 6), (6, 6)), mode='reflect') else: msk = msk[6:1306, 6:1306] msk = np.pad(msk, ((6, 6), (6, 6)), mode='reflect') msks.append(msk) msks = np.asarray(msks) msk = msks.mean(axis=0) thr = 120 msk2 = 1 * (msk > thr) msk2 = msk2.astype(np.uint8) msk2 = dilation(msk2, square(5)) msk2 = erosion(msk2, square(5)) skeleton = skeletonize_3d(msk2) skeleton = skeleton[6:1306, 6:1306] lbl0 = label(skeleton) props0 = regionprops(lbl0) cnt = 0 crosses = [] for x in range(1300): for y in range(1300): if skeleton[y, x] == 1: if skeleton[max(0, y-1):min(1300, y+2), max(0, x-1):min(1300, x+2)].sum() > 3: cnt += 1 crss = [] crss.append((x, y)) for y0 in range(max(0, y-1), min(1300, y+2)): for x0 in range(max(0, x-1), min(1300, x+2)): if x == x0 and y == y0: continue if skeleton[max(0, y0-1):min(1300, y0+2), max(0, x0-1):min(1300, x0+2)].sum() > 3: crss.append((x0, y0)) crosses.append(crss) cross_hashes = [] for crss in crosses: crss_hash = set([]) for x0, y0 in crss: crss_hash.add(point_hash(x0, y0)) skeleton[y0, x0] = 0 cross_hashes.append(crss_hash) new_crosses = [] i = 0 while i < len(crosses): new_hashes = set([]) new_hashes.update(cross_hashes[i]) new_crss = crosses[i][:] fl = True while fl: fl = False j = i + 1 while j < len(crosses): if len(new_hashes.intersection(cross_hashes[j])) > 0: new_hashes.update(cross_hashes[j]) new_crss.extend(crosses[j]) cross_hashes.pop(j) crosses.pop(j) fl = True break j += 1 mean_p = np.asarray(new_crss).mean(axis=0).astype('int') if len(new_crss) > 1: t = KDTree(np.asarray(new_crss)) mean_p = new_crss[t.query(mean_p[np.newaxis, :])[1][0][0]] new_crosses.append([(mean_p[0], mean_p[1])] + new_crss) i += 1 crosses = new_crosses lbl = label(skeleton) props = regionprops(lbl) connected_roads = [] connected_crosses = [set([]) for p in props] for i in range(len(crosses)): rds = set([]) for j in range(len(crosses[i])): x, y = crosses[i][j] for y0 in range(max(0, y-1), min(1300, y+2)): for x0 in range(max(0, x-1), min(1300, x+2)): if lbl[y0, x0] > 0: rds.add(lbl[y0, x0]) connected_crosses[lbl[y0, x0]-1].add(i) connected_roads.append(rds) res_roads = [] tot_dist_min = 20 coords_min = 10 for i in range(len(props)): coords = props[i].coords crss = list(connected_crosses[i]) tot_dist = props0[lbl0[coords[0][0], coords[0][1]]-1].area if (tot_dist < tot_dist_min) or (coords.shape[0] < coords_min and len(crss) < 2): continue if coords.shape[0] == 1: coords = np.asarray([coords[0], coords[0]]) else: coords = get_ordered_coords(lbl, i+1, coords) for j in range(len(crss)): x, y = crosses[crss[j]][0] d1 = abs(coords[0][0] - y) + abs(coords[0][1] - x) d2 = abs(coords[-1][0] - y) + abs(coords[-1][1] - x) if d1 < d2: coords[0][0] = y coords[0][1] = x else: coords[-1][0] = y coords[-1][1] = x coords_approx = approximate_polygon(coords, 1.5) res_roads.append(coords_approx) hashes = set([]) final_res_roads = [] for r in res_roads: if r.shape[0] > 2: final_res_roads.append(r) for i in range(1, r.shape[0]): p1 = r[i-1] p2 = r[i] h1 = pair_hash(p1, p2) h2 = pair_hash(p2, p1) hashes.add(h1) hashes.add(h2) for r in res_roads: if r.shape[0] == 2: p1 = r[0] p2 = r[1] h1 = pair_hash(p1, p2) h2 = pair_hash(p2, p1) if not (h1 in hashes or h2 in hashes): final_res_roads.append(r) hashes.add(h1) hashes.add(h2) end_points = {} for r in res_roads: h = point_hash(r[0, 0], r[0, 1]) if not (h in end_points.keys()): end_points[h] = 0 end_points[h] = end_points[h] + 1 h = point_hash(r[-1, 0], r[-1, 1]) if not (h in end_points.keys()): end_points[h] = 0 end_points[h] = end_points[h] + 1 road_msk = np.zeros((1300, 1300), dtype=np.int32) road_msk = road_msk.copy() thickness = 1 for j in range(len(final_res_roads)): l = final_res_roads[j] for i in range(len(l) - 1): cv2.line(road_msk, (int(l[i, 1]), int(l[i, 0])), (int(l[i+1, 1]), int(l[i+1, 0])), j+1, thickness) connect_dist = 110 min_prob = 30 angles_to_check = [0, radians(5), radians(-5), radians(10), radians(-10), radians(15), radians(-15)] angles_to_check += [radians(20), radians(-20), radians(25), radians(-25)] add_dist = 30 add_dist2 = 6 con_r = 8 for i in range(len(final_res_roads)): h = point_hash(final_res_roads[i][0, 0], final_res_roads[i][0, 1]) if end_points[h] == 1: p1 = final_res_roads[i][1] p2 = final_res_roads[i][0] p3 = try_connect(p1, p2, 0, connect_dist, road_msk, min_prob, msk, final_res_roads, con_r) if p3 is not None: h1 = pair_hash(p2, p3) h2 = pair_hash(p3, p2) if not (h1 in hashes or h2 in hashes): r_id = road_msk[p3[0], p3[1]] - 1 final_res_roads[r_id], new_hashes = inject_point(final_res_roads[r_id], p3) hashes.update(new_hashes) tmp_road_msk = np.zeros((1300, 1300), dtype=np.int32) tmp_road_msk = tmp_road_msk.copy() cv2.line(tmp_road_msk, (p2[1], p2[0]), (p3[1], p3[0]), i+1, thickness) road_msk[road_msk == 0] = tmp_road_msk[road_msk == 0] road_msk = road_msk.copy() final_res_roads[i] = np.vstack((p3, final_res_roads[i])) hashes.add(h1) hashes.add(h2) end_points[point_hash(p3[0], p3[1])] = 2 h = point_hash(final_res_roads[i][-1, 0], final_res_roads[i][-1, 1]) if end_points[h] == 1: p1 = final_res_roads[i][-2] p2 = final_res_roads[i][-1] p3 = try_connect(p1, p2, 0, connect_dist, road_msk, min_prob, msk, final_res_roads, con_r) if p3 is not None: h1 = pair_hash(p2, p3) h2 = pair_hash(p3, p2) if not (h1 in hashes or h2 in hashes): r_id = road_msk[p3[0], p3[1]] - 1 final_res_roads[r_id], new_hashes = inject_point(final_res_roads[r_id], p3) hashes.update(new_hashes) tmp_road_msk = np.zeros((1300, 1300), dtype=np.int32) tmp_road_msk = tmp_road_msk.copy() cv2.line(tmp_road_msk, (p2[1], p2[0]), (p3[1], p3[0]), i+1, thickness) road_msk[road_msk == 0] = tmp_road_msk[road_msk == 0] road_msk = road_msk.copy() final_res_roads[i] = np.vstack((final_res_roads[i], p3)) hashes.add(h1) hashes.add(h2) end_points[point_hash(p3[0], p3[1])] = 2 for i in range(len(final_res_roads)): h = point_hash(final_res_roads[i][0, 0], final_res_roads[i][0, 1]) if end_points[h] == 1: p1 = final_res_roads[i][1] p2 = final_res_roads[i][0] p3 = None for a in angles_to_check: p3 = try_connect(p1, p2, a, connect_dist, road_msk, min_prob, msk, final_res_roads, con_r) if p3 is not None: break if p3 is not None: h1 = pair_hash(p2, p3) h2 = pair_hash(p3, p2) if not (h1 in hashes or h2 in hashes): r_id = road_msk[p3[0], p3[1]] - 1 final_res_roads[r_id], new_hashes = inject_point(final_res_roads[r_id], p3) hashes.update(new_hashes) tmp_road_msk = np.zeros((1300, 1300), dtype=np.int32) tmp_road_msk = tmp_road_msk.copy() cv2.line(tmp_road_msk, (p2[1], p2[0]), (p3[1], p3[0]), i+1, thickness) road_msk[road_msk == 0] = tmp_road_msk[road_msk == 0] road_msk = road_msk.copy() final_res_roads[i] = np.vstack((p3, final_res_roads[i])) hashes.add(h1) hashes.add(h2) end_points[point_hash(p3[0], p3[1])] = 2 else: p3 = get_next_point(p1, p2, add_dist) if not (p3[0] < 2 or p3[1] < 2 or p3[0] > 1297 or p3[1] > 1297): p3 = get_next_point(p1, p2, add_dist2) if (p3[0] != p2[0] or p3[1] != p2[1]) and (road_msk[p3[0], p3[1]] == 0): h1 = pair_hash(p2, p3) h2 = pair_hash(p3, p2) if not (h1 in hashes or h2 in hashes): final_res_roads[i] = np.vstack((p3, final_res_roads[i])) hashes.add(h1) hashes.add(h2) tmp_road_msk = np.zeros((1300, 1300), dtype=np.int32) tmp_road_msk = tmp_road_msk.copy() cv2.line(tmp_road_msk, (p2[1], p2[0]), (p3[1], p3[0]), i+1, thickness) road_msk[road_msk == 0] = tmp_road_msk[road_msk == 0] road_msk = road_msk.copy() end_points[point_hash(p3[0], p3[1])] = 2 h = point_hash(final_res_roads[i][-1, 0], final_res_roads[i][-1, 1]) if end_points[h] == 1: p1 = final_res_roads[i][-2] p2 = final_res_roads[i][-1] p3 = None for a in angles_to_check: p3 = try_connect(p1, p2, a, connect_dist, road_msk, min_prob, msk, final_res_roads, con_r) if p3 is not None: break if p3 is not None: h1 = pair_hash(p2, p3) h2 = pair_hash(p3, p2) if not (h1 in hashes or h2 in hashes): r_id = road_msk[p3[0], p3[1]] - 1 final_res_roads[r_id], new_hashes = inject_point(final_res_roads[r_id], p3) hashes.update(new_hashes) tmp_road_msk = np.zeros((1300, 1300), dtype=np.int32) tmp_road_msk = tmp_road_msk.copy() cv2.line(tmp_road_msk, (p2[1], p2[0]), (p3[1], p3[0]), i+1, thickness) road_msk[road_msk == 0] = tmp_road_msk[road_msk == 0] road_msk = road_msk.copy() final_res_roads[i] = np.vstack((final_res_roads[i], p3)) hashes.add(h1) hashes.add(h2) end_points[point_hash(p3[0], p3[1])] = 2 else: p3 = get_next_point(p1, p2, add_dist) if not (p3[0] < 2 or p3[1] < 2 or p3[0] > 1297 or p3[1] > 1297): p3 = get_next_point(p1, p2, add_dist2) if (p3[0] != p2[0] or p3[1] != p2[1]) and (road_msk[p3[0], p3[1]] == 0): h1 = pair_hash(p2, p3) h2 = pair_hash(p3, p2) if not (h1 in hashes or h2 in hashes): final_res_roads[i] = np.vstack((final_res_roads[i], p3)) hashes.add(h1) hashes.add(h2) tmp_road_msk = np.zeros((1300, 1300), dtype=np.int32) tmp_road_msk = tmp_road_msk.copy() cv2.line(tmp_road_msk, (p2[1], p2[0]), (p3[1], p3[0]), i+1, thickness) road_msk[road_msk == 0] = tmp_road_msk[road_msk == 0] road_msk = road_msk.copy() end_points[point_hash(p3[0], p3[1])] = 2 lines = [LineString(r[:, ::-1]) for r in final_res_roads] res_rows = [] if len(lines) == 0: res_rows.append({'ImageId': img_id, 'WKT_Pix': 'LINESTRING EMPTY'}) else: for l in lines: res_rows.append({'ImageId': img_id, 'WKT_Pix': dumps(l, rounding_precision=0)}) return res_rows
log("Labeling", logf) chan_file = path.join(out_exp_dir, "labs_{}.tif".format(chan_names[syn_type][0])) if not force and path.isfile(chan_file): labs = imread(chan_file) else: log(" " + chan_names[syn_type][0], logf) ran[0] = True imgs_0 = gaussian(imgs[:, :, :, 0], sigma=0.3) M = max(imgs_0.flatten()) labs_0 = remove_small_objects(label(imgs_0 > intens_range[0] * M), min_size=min_neur_marker_size, in_place=True) labs_0 = remove_large_objects(labs_0, max_neur_marker_size) labs_0 = erosion(labs_0, ones((5, 5, 5))) props = regionprops(labs_0) best_area = mean([e.area for e in props]) best_labs = array(labs_0) best_th = intens_range[0] * M log( " {}% ({:.2f}): {} (area={:.3f})".format( int(intens_range[0] * 100), intens_range[0] * M, len(props), best_area), logf) for cnt in range(1, len(intens_range)): labs_0 = remove_small_objects( label(imgs_0 > intens_range[cnt] * M), min_size=min_neur_marker_size, in_place=True) labs_0 = remove_large_objects(labs_0, max_neur_marker_size) props = regionprops(labs_0)
def grid_img(point_cloud, grid_size, loc, R, threshold, sigma=5): """ Sample the input point cloud using a uniform grid. Args: - point_cloud: an object of PointCloud class - grid_size: in meters - loc: center - R: diameter - sigma: gaussian distribution variance, in meters - threshold: minimum value to count the box as one Return: - results: ndarray, rectangular image. """ sample_points = [] sample_directions = [] min_easting = loc[0]-R max_easting = loc[0]+R min_northing = loc[1]-R max_northing = loc[1]+R n_grid_x = int((max_easting - min_easting)/grid_size + 0.5) n_grid_y = int((max_northing - min_northing)/grid_size + 0.5) print "Will generate image of size (%d, %d)"%(n_grid_x, n_grid_y) results = np.zeros((n_grid_x+1, n_grid_y+1)) if n_grid_x > 1E4 or n_grid_y > 1E4: print "ERROR! The sampling grid is too small!" sys.exit(1) three_sigma = 3*sigma/grid_size geo_hash = {} for pt_idx in range(0, len(point_cloud.locations)): pt = point_cloud.locations[pt_idx] px = int((pt[0] - min_easting) / grid_size) py = int((pt[1] - min_northing) / grid_size) if px<0 or px>=n_grid_x or py<0 or py>=n_grid_y: continue # Expand around neighbor pt_dir = point_cloud.directions[pt_idx] if np.linalg.norm(pt_dir) > 0.1: delta_x = np.dot(three_sigma*pt_dir, np.array([1.0, 0.0])) delta_y = np.sqrt(three_sigma**2 - delta_x**2) larger_one = max(abs(delta_x), abs(delta_y)) n_pt_to_add = int(larger_one*2 + 1.5) tmp_i = np.linspace(px-delta_x, px+delta_x, n_pt_to_add) tmp_j = np.linspace(py-delta_y, py+delta_y, n_pt_to_add) for s in range(0, n_pt_to_add): i = int(tmp_i[s]) j = int(tmp_j[s]) if i<0 or i>=n_grid_x or j<0 or j>n_grid_y: continue if geo_hash.has_key((i,j)): geo_hash[(i,j)] += 1.0 else: geo_hash[(i,j)] = 1.0 else: if geo_hash.has_key((px,py)): geo_hash[(px,py)] += 1.0 else: geo_hash[(px,py)] = 1.0 for key in geo_hash.keys(): if geo_hash[key] >= threshold: results[key[0], key[1]] = geo_hash[key] filtered_img = results>0.9 filtered_img = morphology.dilation(filtered_img, morphology.square(3)) filtered_img = morphology.erosion(filtered_img, morphology.square(3)) filtered_img = morphology.remove_small_objects(filtered_img, 10) results = filtered_img>0.9 return results
def classification(mask2, cols, rows, res_rotated, factor, small_px, large_px, h_base_px): category = '0' number_neighboring_pixels = 3 # plt.imshow(mask2, 'gray') # plt.title('thresh3-mask2') # plt.show() # **************************Pre-proccess******************* b, g, r = cv2.split(res_rotated) res_rotated = cv2.merge([r, g, b]) # plt.imshow(res_rotated, 'gray') # plt.title('FINAL') # plt.show() row, col = mask2.shape a = 0 # ***************************Get stem's side*********************** for c in range(col): a = np.append(a, (mask2[:, c] > 100).sum()) part20 = cols * 0.2 image20 = a[:int(part20)] image80 = a[-int(part20):] image20 = np.array(image20) image80 = np.array(image80) mean20 = image20.mean() mean80 = image80.mean() print 'mean20' print mean20 print 'mean80' print mean80 if mean20 < mean80: print 'Tallo a la izquierda' else: print 'Tallo a la derecha' mask2 = cv2.flip(mask2, 1) res_rotated = cv2.flip(res_rotated, 1) real_image_20 = mask2[:, :int(part20)] plt.imshow(real_image_20) plt.title('part20') plt.show() #ret, thresh2 = cv2.threshold(res_rotated[:, :, 1], 5, 255, cv2.THRESH_BINARY) im2, contours2, hierarchy2 = cv2.findContours(real_image_20, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) im2, contours, hierarchy = cv2.findContours(real_image_20, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) contours2 = sorted(contours2, key=cv2.contourArea, reverse=True) cnt2 = contours2[0] cv2.drawContours(real_image_20, [cnt2], 0, 255, cv2.FILLED) x, y, w, h = cv2.boundingRect(cnt2) dst_roi = res_rotated[y:y + h, x:x + w] thresh3 = real_image_20[y:y + h, x:x + w] cols, rows = dst_roi.shape[:2] if rows < cols: res_rotated = rotate_and_scale(dst_roi, 1, 90) thresh3 = rotate_and_scale(thresh3, 1, 90) cols, rows = dst_roi.shape[:2] #real_image_20 = erosion(real_image_20, rectangle(10, 1)) #real_image_20 = erosion(real_image_20, rectangle(10, 1)) #real_image_20 = erosion(real_image_20, rectangle(10, 1)) # thresh = dilation(thresh, rectangle(18, 1)) # props = regionprops(real_image_20) # cut_orientation = props[0]['orientation'] # print("Orientation is:"+str(cut_orientation)) # correct_image = rotate_and_scale(real_image_20, 1, -cut_orientation) # second_correct_image = scipy.misc.imrotate(real_image_20, -cut_orientation, interp='bilinear') plt.imshow(thresh3) plt.title('rotated_image_tallo') plt.show() # plt.imshow(thresh3) # plt.title('rotated_image_tallo_2') # plt.show() # **********To detect Hoja en Base******************************* # plt.imshow(mask2, 'gray') # plt.title('Well positioned') # plt.show() ret, binarize_image = cv2.threshold(mask2, 0, 1, cv2.THRESH_BINARY) binarize_image = erosion(binarize_image, square(3)) binarize_image = erosion(binarize_image, square(3)) binarize_image = erosion(binarize_image, square(3)) binarize_image = dilation(binarize_image, square(3)) binarize_image = dilation(binarize_image, square(3)) binarize_image = dilation(binarize_image, square(3)) # Get Skeleton of full image # skeleton = medial_axis(binarize_image, return_distance=False) skeleton = skeletonize_3d(binarize_image) flip_skel = np.rot90(skeleton, 1) flip_skel = cv2.flip(flip_skel, 0) #plt.imshow(flip_skel, 'gray') #plt.show() (i, j) = flip_skel.nonzero() first_white_pixel = i[0] print(first_white_pixel) print("printing some pixels") print(i) print(j) # Showing results of skeletonization #plt.imshow(skeleton, 'gray') # plt.title('Skeleton') # plt.show() bw_conv = signal.convolve2d(skeleton, np.ones((3, 3)), mode='same') # plt.imshow(bw_conv, 'gray') # plt.title('bw_conv') # plt.show() bw_conv = (bw_conv == number_neighboring_pixels + 1) & binarize_image # plt.imshow(bw_conv, 'gray') # plt.title('bw_conv') # plt.show() bw_sum = bw_conv.sum(axis=0) r = bw_sum.ravel().nonzero() # r[0][5] = 3 print("r = ") print(r) r = np.array(r) # ------------------replace flip_bw_conv = np.rot90(bw_conv, 1) flip_bw_conv = cv2.flip(flip_bw_conv, 0) # plt.imshow(flip_bw_conv, 'gray') # plt.show() (x_s, y_s) = flip_bw_conv.nonzero() first_branch_x = x_s[0] first_branch_y = y_s[0] # ---------------------------------bueno # v = np.ediff1d(r) # print("este es v: ") # print (v) # v = v.tolist() # max_difference = max(v) # index_x1 = v.index(max_difference) # x1_index = index_x1+1 # print("este es x1_index") # print(x1_index) # r = np.asarray(r) # print (r) # x1 = r[0][x1_index] # x2 = r[0][x1_index - 1] # y1 = bw_conv[:, x1] # y1_index = y1.nonzero() # y1 = y1_index[0][0] # --------------------------------------- Fin_ bueno max_difference = first_branch_x - first_white_pixel print("la mxima diferencia es:") print(max_difference) print("x1 es:" + str(first_white_pixel)) print("x2 es:" + str(first_branch_x)) print("y1 es:" + str(first_branch_y)) hojamm = (11.5 * max_difference / 345) * 10 # ----------------------CLASIFICACION FINAL ---------------------- flag_h_base = False if max_difference < h_base_px: category = '3' flag_h_base = True if cols < small_px: print 'corto' category = '1' elif (cols > large_px) & (flag_h_base == False): print 'largo' category = '2' elif (cols > small_px) & (cols < large_px): print 'ideal' category = 4 elif cols < 200: print 'nada' category = '0' x3 = first_white_pixel x2 = first_branch_x x1 = first_branch_x y1 = first_branch_y return res_rotated, bw_conv, skeleton, category, hojamm, x1, x2, y1, x3
def process(dicom_file): medical_image = dcmread(dicom_file) image = medical_image.pixel_array hu_image = transform_to_hu(medical_image, image) brain_image = window_image(hu_image, 80, 85) bone_image = window_image(hu_image, 230, 230) binary_image = bone_image > threshold_minimum(bone_image) edge_sobel_binary = sobel(binary_image) fill = segmentation.flood_fill( edge_sobel_binary, get_center(brain_image, image), 255) erosion = morphology.erosion(fill, morphology.disk(30)) otsu_image = brain_image > threshold_otsu(brain_image) edge_sobel_otsu = sobel(otsu_image) multiplication_images = erosion * edge_sobel_otsu mediam_filter = median(multiplication_images) process = [] process.append({ 'name': 'original_image', 'image': brain_image, 'contour': None, }) process.append({ 'name': 'part_1_otsu_binary', 'image': otsu_image, 'contour': None, }) process.append({ 'name': 'part_1_edge_otsu', 'image': edge_sobel_otsu, 'contour': None, }) process.append({ 'name': 'part_2_binary', 'image': binary_image, 'contour': None, }) process.append({ 'name': 'part_2_edges', 'image': edge_sobel_binary, 'contour': None, }) process.append({ 'name': 'part_2_fill', 'image': fill, 'contour': None, }) process.append({ 'name': 'part_2_erosion', 'image': erosion, 'contour': None, }) process.append({ 'name': 'multiplication_images', 'image': multiplication_images, 'contour': None, }) process.append({ 'name': 'mediam_filters', 'image': mediam_filter, 'contour': None, }) process.append({ 'name': 'segmentation', 'image': brain_image, 'contour': mediam_filter }) return process
Erosion ======= Morphological ``erosion`` sets a pixel at (i, j) to the *minimum over all pixels in the neighborhood centered at (i, j)*. The structuring element, ``selem``, passed to ``erosion`` is a boolean array that describes this neighborhood. Below, we use ``disk`` to create a circular structuring element, which we use for most of the following examples. """ from skimage.morphology import erosion, dilation, opening, closing, white_tophat from skimage.morphology import black_tophat, skeletonize, convex_hull_image from skimage.morphology import disk selem = disk(6) eroded = erosion(phantom, selem) plot_comparison(phantom, eroded, 'erosion') """ .. image:: PLOT2RST.current_figure Notice how the white boundary of the image disappears or gets eroded as we increase the size of the disk. Also notice the increase in size of the two black ellipses in the center and the disappearance of the 3 light grey patches in the lower part of the image. Dilation ======== Morphological ``dilation`` sets a pixel at (i, j) to the *maximum over all pixels in the neighborhood centered at (i, j)*. Dilation enlarges bright
# sns.distplot(middle.ravel(), ax=ax1) ax1.vlines(x=threshold, ymax=10, ymin=0) ax1.set_title('Threshold: %1.2F' % threshold) ax1.set_xticklabels([]) ''' # 展示阈值对图像切割的结果。小于阈值的点标注为 1 ,白色。大于阈值的点标注为 0 ,黑色。 ''' ax2 = fig.add_subplot(322) ax2.imshow(thresh_img, "gray") ax2.set_axis_off() ax2.set_title('Step1, using threshold as cutoff') ''' # 增大黑色部分(非 ROI )的区域,使之尽可能的连在一起 eroded = morphology.erosion(thresh_img, np.ones([4, 4])) ''' ax3 = fig.add_subplot(323) ax3.imshow(eroded, "gray") ax3.set_axis_off() ax3.set_title('Step2, erosion shrinks bright\nregions and enlarges dark regions.') ''' # 增大白色部分( ROI )的区域,尽可能的消除面积较小的黑色区域 dilation = morphology.dilation(eroded, np.ones([10, 10])) ''' ax4 = fig.add_subplot(324) ax4.imshow(dilation, "gray") ax4.set_axis_off() ax4.set_title('Step3, dilation shrinks dark\nregions and enlarges bright regions.') '''
def boundary_mask(footprint_msk=None, out_file=None, reference_im=None, boundary_width=3, boundary_type='inner', burn_value=255, **kwargs): """Convert a dataframe of geometries to a pixel mask. Note ---- This function requires creation of a footprint mask before it can operate; therefore, if there is no footprint mask already present, it will create one. In that case, additional arguments for :func:`footprint_mask` (e.g. ``df``) must be passed. By default, this function draws boundaries *within* the edges of objects. To change this behavior, use the `boundary_type` argument. Arguments --------- footprint_msk : :class:`numpy.array`, optional A filled in footprint mask created using :func:`footprint_mask`. If not provided, one will be made by calling :func:`footprint_mask` before creating the boundary mask, and the required arguments for that function must be provided as kwargs. out_file : str, optional Path to an image file to save the output to. Must be compatible with :class:`rasterio.DatasetReader`. If provided, a `reference_im` must be provided (for metadata purposes). reference_im : :class:`rasterio.DatasetReader` or `str`, optional An image to extract necessary coordinate information from: the affine transformation matrix, the image extent, etc. If provided, `affine_obj` and `shape` are ignored boundary_width : int, optional The width of the boundary to be created **in pixels.** Defaults to 3. boundary_type : ``"inner"`` or ``"outer"``, optional Where to draw the boundaries: within the object (``"inner"``) or outside of it (``"outer"``). Defaults to ``"inner"``. burn_value : `int`, optional The value to use for labeling objects in the mask. Defaults to 255 (the max value for ``uint8`` arrays). The mask array will be set to the same dtype as `burn_value`. Ignored if `burn_field` is provided. **kwargs : optional Additional arguments to pass to :func:`footprint_mask` if one needs to be created. Returns ------- boundary_mask : :class:`numpy.array` A pixel mask with 0s for non-object pixels and the same value as the footprint mask `burn_value` for the boundaries of each object. """ if out_file and not reference_im: raise ValueError( 'If saving output to file, `reference_im` must be provided.') if reference_im: reference_im = _check_rasterio_im_load(reference_im) # need to have a footprint mask for this function, so make it if not given if footprint_msk is None: footprint_msk = footprint_mask(reference_im=reference_im, burn_value=burn_value, **kwargs) # perform dilation or erosion of `footprint_mask` to get the boundary strel = square(boundary_width) if boundary_type == 'outer': boundary_mask = dilation(footprint_msk, strel) elif boundary_type == 'inner': boundary_mask = erosion(footprint_msk, strel) # use xor operator between border and footprint mask to get _just_ boundary boundary_mask = boundary_mask ^ footprint_msk # scale the `True` values to burn_value and return boundary_mask = boundary_mask > 0 # need to binarize to get burn val right output_arr = boundary_mask.astype('uint8') * burn_value if out_file: meta = reference_im.meta.copy() meta.update(count=1) meta.update(dtype='uint8') with rasterio.open(out_file, 'w', **meta) as dst: dst.write(output_arr, indexes=1) return output_arr
def segment_lungs(image: np.ndarray, display=False)->np.ndarray: row_size= image.shape[0] col_size = image.shape[1] mean = np.mean(image) std = np.std(image) image = (image-mean)/std # Find the average pixel value near the lungs # to renormalize washed out images middle = image[int(col_size/5):int(col_size/5*4), int(row_size/5):int(row_size/5*4)] mean = np.mean(middle) max_ = np.max(image) min_ = np.min(image) # To improve threshold finding, I'm moving the # underflow and overflow on the pixel spectrum image[image==max_] = mean image[image==min_] = mean # Using Kmeans to separate foreground (soft tissue / bone) and background (lung/air) kmeans = KMeans(n_clusters=2).fit(np.reshape(middle, [np.prod(middle.shape),1])) centers = sorted(kmeans.cluster_centers_.flatten()) threshold = np.mean(centers) thresh_image = np.where(image<threshold, 1.0, 0.0) # First erode away the finer elements, then dilate to include some of the pixels surrounding the lung. # We don't want to accidentally clip the lung. eroded_image = morphology.erosion(thresh_image,np.ones([2, 2])) dilated_image = morphology.dilation(eroded_image,np.ones([8, 8])) labels = measure.label(dilated_image, connectivity=2) label_vals = np.unique(labels) regions = measure.regionprops(labels) good_labels = [] for prop in regions: B = prop.bbox if (B[2]-B[0]<=row_size*1.0 and B[2]-B[0]>=row_size*0.4 and B[3]-B[1]<=col_size*0.8 and B[3]-B[1]>=col_size * 0.2 and B[0]>=row_size*0.00 and B[2]<=row_size*1.0): good_labels.append(prop.label) mask = np.ndarray([row_size,col_size],dtype=np.int8) mask[:] = 0 # After just the lungs are left, we do another large dilation # in order to fill in and out the lung mask for N in good_labels: mask = mask + np.where(labels==N, 1, 0) mask = morphology.dilation(mask,np.ones([18, 18])) if (display): fig, ax = plt.subplots(3, 2, figsize=[12, 12]) ax[0, 0].set_title("Original") ax[0, 0].imshow(image, cmap='gray') ax[0, 0].axis('off') ax[0, 1].set_title("Threshold") ax[0, 1].imshow(thresh_image, cmap='gray') ax[0, 1].axis('off') ax[1, 0].set_title("After Erosion and Dilation") ax[1, 0].imshow(dilated_image, cmap='gray') ax[1, 0].axis('off') ax[1, 1].set_title("Color Labels") ax[1, 1].imshow(labels) ax[1, 1].axis('off') ax[2, 0].set_title("Final Mask") ax[2, 0].imshow(mask, cmap='gray') ax[2, 0].axis('off') ax[2, 1].set_title("Apply Mask on Original") ax[2, 1].imshow(mask*image, cmap='gray') ax[2, 1].axis('off') plt.show() return mask*images
def make_lungmask(img, display=False): row_size= img.shape[0] col_size = img.shape[1] mean = np.mean(img) std = np.std(img) img = img-mean img = img/std # Find the average pixel value near the lungs # to renormalize washed out images middle = img[int(col_size/5):int(col_size/5*4),int(row_size/5):int(row_size/5*4)] mean = np.mean(middle) max = np.max(img) min = np.min(img) # To improve threshold finding, I'm moving the # underflow and overflow on the pixel spectrum img[img==max]=mean img[img==min]=mean # # Using Kmeans to separate foreground (soft tissue / bone) and background (lung/air) # kmeans = KMeans(n_clusters=2).fit(np.reshape(middle,[np.prod(middle.shape),1])) centers = sorted(kmeans.cluster_centers_.flatten()) threshold = np.mean(centers) thresh_img = np.where(img<threshold,1.0,0.0) # threshold the image # First erode away the finer elements, then dilate to include some of the pixels surrounding the lung. # We don't want to accidentally clip the lung. eroded = morphology.erosion(thresh_img,np.ones([3,3])) dilation = morphology.dilation(eroded,np.ones([8,8])) labels = measure.label(dilation) # Different labels are displayed in different colors label_vals = np.unique(labels) regions = measure.regionprops(labels) good_labels = [] for prop in regions: B = prop.bbox if B[2]-B[0]<row_size/10*9 and B[3]-B[1]<col_size/10*9 and B[0]>row_size/5 and B[2]<col_size/5*4: good_labels.append(prop.label) mask = np.ndarray([row_size,col_size],dtype=np.int8) mask[:] = 0 # # After just the lungs are left, we do another large dilation # in order to fill in and out the lung mask # for N in good_labels: mask = mask + np.where(labels==N,1,0) mask = morphology.dilation(mask,np.ones([10,10])) # one last dilation if (display): fig, ax = plt.subplots(3, 2, figsize=[12, 12]) ax[0, 0].set_title("Original") ax[0, 0].imshow(img, cmap='gray') ax[0, 0].axis('off') ax[0, 1].set_title("Threshold") ax[0, 1].imshow(thresh_img, cmap='gray') ax[0, 1].axis('off') ax[1, 0].set_title("After Erosion and Dilation") ax[1, 0].imshow(dilation, cmap='gray') ax[1, 0].axis('off') ax[1, 1].set_title("Color Labels") ax[1, 1].imshow(labels) ax[1, 1].axis('off') ax[2, 0].set_title("Final Mask") ax[2, 0].imshow(mask, cmap='gray') ax[2, 0].axis('off') ax[2, 1].set_title("Apply Mask on Original") ax[2, 1].imshow(mask*img, cmap='gray') ax[2, 1].axis('off') plt.show() return mask*img
def _get_batches_of_transformed_samples(self, index_array): batch_x = [] batch_y = [] for batch_index, image_index in enumerate(index_array): _idx = self.image_ids[image_index] img0 = all_images[_idx].copy() msk0 = all_masks[_idx].copy() lbl0 = all_labels[_idx].copy() good4copy = all_good4copy[_idx] x0 = random.randint(0, img0.shape[1] - input_shape[1]) y0 = random.randint(0, img0.shape[0] - input_shape[0]) img = img0[y0:y0 + input_shape[0], x0:x0 + input_shape[1], :] msk = msk0[y0:y0 + input_shape[0], x0:x0 + input_shape[1], :] if len(good4copy) > 0 and random.random() > 0.75: num_copy = random.randrange(1, min(6, len(good4copy) + 1)) lbl_max = lbl0.max() for i in range(num_copy): lbl_max += 1 l_id = random.choice(good4copy) lbl_msk = all_labels[_idx] == l_id row, col = np.where(lbl_msk) y1, x1 = np.min(np.where(lbl_msk), axis=1) y2, x2 = np.max(np.where(lbl_msk), axis=1) lbl_msk = lbl_msk[y1:y2 + 1, x1:x2 + 1] lbl_img = img0[y1:y2 + 1, x1:x2 + 1, :] if random.random() > 0.5: lbl_msk = lbl_msk[:, ::-1, ...] lbl_img = lbl_img[:, ::-1, ...] rot = random.randrange(4) if rot > 0: lbl_msk = np.rot90(lbl_msk, k=rot) lbl_img = np.rot90(lbl_img, k=rot) x1 = random.randint( max(0, x0 - lbl_msk.shape[1] // 2), min(img0.shape[1] - lbl_msk.shape[1], x0 + input_shape[1] - lbl_msk.shape[1] // 2)) y1 = random.randint( max(0, y0 - lbl_msk.shape[0] // 2), min(img0.shape[0] - lbl_msk.shape[0], y0 + input_shape[0] - lbl_msk.shape[0] // 2)) tmp = erosion(lbl_msk, square(5)) lbl_msk_dif = lbl_msk ^ tmp tmp = dilation(lbl_msk, square(5)) lbl_msk_dif = lbl_msk_dif | (tmp ^ lbl_msk) lbl0[y1:y1 + lbl_msk.shape[0], x1:x1 + lbl_msk.shape[1]][lbl_msk] = lbl_max img0[y1:y1 + lbl_msk.shape[0], x1:x1 + lbl_msk.shape[1]][lbl_msk] = lbl_img[lbl_msk] full_diff_mask = np.zeros_like(img0[..., 0], dtype='bool') full_diff_mask[y1:y1 + lbl_msk.shape[0], x1:x1 + lbl_msk.shape[1]] = lbl_msk_dif img0[..., 0][full_diff_mask] = median( img0[..., 0], mask=full_diff_mask)[full_diff_mask] img0[..., 1][full_diff_mask] = median( img0[..., 1], mask=full_diff_mask)[full_diff_mask] img0[..., 2][full_diff_mask] = median( img0[..., 2], mask=full_diff_mask)[full_diff_mask] img = img0[y0:y0 + input_shape[0], x0:x0 + input_shape[1], :] lbl = lbl0[y0:y0 + input_shape[0], x0:x0 + input_shape[1]] msk = create_mask(lbl) if 'ic100_' in all_ids[_idx] or 'gnf_' in all_ids[_idx]: data = self.random_transformers[1](image=img[..., ::-1], mask=msk) else: data = self.random_transformers[0](image=img[..., ::-1], mask=msk) img = data['image'][..., ::-1] msk = data['mask'] msk = msk.astype('float') msk[..., 0] = (msk[..., 0] > 127) * 1 msk[..., 1] = (msk[..., 1] > 127) * (msk[..., 0] == 0) * 1 msk[..., 2] = (msk[..., 1] == 0) * (msk[..., 0] == 0) * 1 otp = msk img = np.concatenate([img, bgr_to_lab(img)], axis=2) batch_x.append(img) batch_y.append(otp) batch_x = np.array(batch_x, dtype="float32") batch_y = np.array(batch_y, dtype="float32") batch_x = preprocess_inputs(batch_x) return self.transform_batch_x(batch_x), self.transform_batch_y(batch_y)
def segment_rw(roi, channel, beta=50.0, vmin=0.6, vmax=0.65, remove_small=None, erosion=None, blobs=None, get_labels=False): """Segments an image using the Random-Walker algorithm. Args: roi: Region of interest to segment. channel: Channel to pass to :func:``plot_3d.setup_channels``. beta: Random-Walker beta term. vmin: Values under which to exclude in markers; defaults to 0.6. Ignored if ``blobs`` is given. vmax: Values above which to exclude in markers; defaults to 0.65. Ignored if ``blobs`` is given. remove_small: Threshold size of small objects to remove; defaults to None to ignore. erosion: Structuring element size for erosion; defaults to None to ignore. blobs: Blobs to use for markers; defaults to None, in which case markers will be determined based on ``vmin``/``vmax`` thresholds. get_labels: True to measure and return labels from the resulting segmentation instead of returning the segmentations themselves; defaults to False. Returns: List of the Random-Walker segmentations for the given channels, If ``get_labels`` is True, the measured labels for the segmented regions will be returned instead of the segmentations themselves. """ print("Random-Walker based segmentation...") labels = [] walkers = [] multichannel, channels = plot_3d.setup_channels(roi, channel, 3) for i in channels: roi_segment = roi[..., i] if multichannel else roi if blobs is None: # mark unknown pixels as 0 by distinguishing known background # and foreground markers = np.zeros(roi_segment.shape, dtype=np.uint8) markers[roi_segment < vmin] = 2 markers[roi_segment >= vmax] = 1 else: # derive markers from blobs markers = _markers_from_blobs(roi_segment, blobs) # perform the segmentation; conjugate gradient with multigrid # preconditioner option (cg_mg), which is faster but req pyamg walker = segmentation.random_walker( roi_segment, markers, beta=beta, mode="cg_mg") # clean up segmentation #lib_clrbrain.show_full_arrays() walker = _carve_segs(walker, blobs) if remove_small: # remove artifacts walker = morphology.remove_small_objects(walker, remove_small) if erosion: # attempt to reduce label connections by eroding walker = morphology.erosion(walker, morphology.octahedron(erosion)) if get_labels: # label neighboring pixels to segmented regions # TODO: check if necessary; useful only if blobs not given? label = measure.label(walker, background=0) labels.append(label) #print("label:\n", label) walkers.append(walker) #print("walker:\n", walker) if get_labels: return labels return walkers
from skimage import morphology from skimage import io img = io.imread('image.png') eroded_img = morphology.erosion(img) io.imshow(eroded_img) io.show()
pic_array = np.array(picture) #plt.plot(pic_array[:,:,0]) plt.imshow(pic_array, cmap="gray") plt.show() pic_convolved = scipy.signal.fftconvolve(pic_array, gaussian[0], mode='same') mean = np.mean(pic_convolved) pic_layer1 = mp.dilation(pic_convolved > mean, mp.square(4)) mean = np.mean(pic_convolved[pic_layer1 == 0]) pic_layer2 = np.invert(mp.erosion(pic_convolved < mean, mp.square(4))) # plt.imshow(pic_layer1) # plt.show() # plt.imshow(pic_layer2) # plt.show() final_picture = pic_layer1 * 2 + pic_layer2 plt.imshow(final_picture, cmap='gray') plt.show() conn_comps_layer0 = mp.label(final_picture < 1, connectivity=1) conn_comps_layer1 = mp.label(final_picture == 1, connectivity=1) conn_comps_layer2 = mp.label(final_picture > 1, connectivity=1) layered_output_image = conn_comps_layer0\
def watershed(img_url): # set the parameters DapiThresh = 90 DapiMinSize = 5 DapiMinSep = 7 DapiMargin = 10 MinCellArea = 200 Dapi = cv2.imread(img_url, cv2.IMREAD_GRAYSCALE) lims = stretchlim(Dapi) # Dapi = _imadjust(Dapi) logger.info('Step 1') # STEP 1: Erode the image Dapi = imadjust2(Dapi, lims) ThresVal = np.percentile(Dapi[Dapi>0], DapiThresh) # kernel = disk(2) # image = cv2.erode(Dapi>ThresVal), kernel) # bwDapi = ndimage.binary_erosion(Dapi>ThresVal, structure=disk(2)).astype(int) bwDapi = morphology.erosion(Dapi>ThresVal, morphology.disk(2)).astype(int) logger.info('Step 2') # STEP 2: Compute the distance map dist = ndimage.distance_transform_edt(bwDapi) dist0 = dist.copy() dist0[dist < DapiMinSize] = 0 logger.info('Step 3') # STEP 3: Dilate to remove small patterns selem = morphology.disk(DapiMinSep) ddist = morphology.dilation(dist0, selem) logger.info('Step 4') # STEP 4: modify the image so that cells are -inf(basins for the watershed method below) markers = imregionalmax(ddist) # marks with 1s the cells, 0 for background impim = imimposemin(-dist0, markers) # returns an array with negative values apart from the locations of the markers logger.info('Watershed') L = segmentation.watershed(impim, watershed_line=True) bwDapi0 = bwDapi.copy() bwDapi0[L == 0] = 0 # % assign all pixels a label s = generate_binary_structure(2,2) labels, num_Features = label(bwDapi0, structure=s) d, _idx = ndimage.distance_transform_edt(bwDapi0 == 0, return_indices=True) idx = np.ravel_multi_index(_idx, bwDapi.shape) # % now expand the regions by a margin # CellMap0 = np.zeros(Dapi.shape).astype(np.uint32) Expansions = d < DapiMargin # CellMap0[Expansions] = labels[idx[Expansions]]; CellMap0 = np.take(labels.flatten(), idx) * Expansions rProps0 = regionprops(CellMap0) # BigEnough = np.array([x.area > 200 for x in rProps0 ]) # NewNumber = np.zeros(len(rProps0)) # NewNumber[~BigEnough] = 0 # NewNumber[BigEnough] = np.arange(1, 1+BigEnough.sum()) # CellMap = CellMap0 # CellMap[CellMap0 > 0] = NewNumber[CellMap0[CellMap0 > 0]] coo = coo_matrix(CellMap0) coo_data = coo.data.copy() to_remove = np.array([x.label for x in rProps0 if x.area <= MinCellArea]) coo_data[np.in1d(coo_data, to_remove)] = 0 _, res = np.unique(coo_data, return_inverse=True) coo.data = res return coo, CellMap0
def segmentation(img): # Threshold ret, thresh = cv2.threshold(img[:, :, 0], 50, 255, cv2.THRESH_BINARY_INV) image = thresh #----------------------- trying watershed ------------------------------- # Generate the markers as local maxima of the distance to the background # distance = ndi.distance_transform_edt(image) # local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)),labels=image) # markers = ndi.label(local_maxi)[0] # labels = watershed(-distance, markers, mask=image) # fig, axes = plt.subplots(ncols=3, figsize=(8, 2.7), sharex=True, sharey=True, # subplot_kw={'adjustable': 'box-forced'}) # ax0, ax1, ax2 = axes # ax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest') # ax0.set_title('Overlapping objects') # ax1.imshow(-distance, cmap=plt.cm.jet, interpolation='nearest') # ax1.set_title('Distances') # ax2.imshow(labels, cmap=plt.cm.spectral, interpolation='nearest') # ax2.set_title('Separated objects') # for ax in axes: # ax.axis('off') # fig.subplots_adjust(hspace=0.01, wspace=0.01, top=0.9, bottom=0, left=0, # right=1) # plt.show() # plt.imshow(distance, 'gray') # plt.show # ---------------- thresh = erosion(thresh, rectangle(18, 1)) thresh = dilation(thresh, rectangle(18, 1)) thresh = erosion(thresh, rectangle(1, 18)) thresh = dilation(thresh, rectangle(1, 18)) # se = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 1)) # thresh = cv2.erode(thresh, se, iterations=1) # thresh = cv2.dilate(thresh, se, iterations=1) # se = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 18)) # thresh = cv2.erode(thresh, se, iterations=1) # thresh = cv2.dilate(thresh, se, iterations=1) # --------------- # plt.imshow(thresh, 'gray') # plt.title('After dilate & erode') # plt.show() # --------------------------------------------------------------------------- im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) print("contours") print(contours) if not contours: thresh2 = img thresh3 = img cols = 100 rows = 100 res_rotated = img else: contours = sorted(contours, key=cv2.contourArea, reverse=True) cnt = contours[0] thresh[...] = 0 cv2.drawContours(thresh, [cnt], 0, 255, cv2.FILLED) true_image = cv2.drawContours(thresh, [cnt], 0, 255, cv2.FILLED) res = cv2.bitwise_and(img, img, mask=thresh) # getting edges-rotating edges center_contour, size_contour, theta = cv2.fitEllipse( cnt) # cv2.minAreaRect(cnt) res_rotated = rotate_and_scale(res, 1, theta) # Thresholding and getting edges again ret, thresh2 = cv2.threshold(res_rotated[:, :, 1], 5, 255, cv2.THRESH_BINARY) im2, contours2, hierarchy2 = cv2.findContours(thresh2, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) contours2 = sorted(contours2, key=cv2.contourArea, reverse=True) cnt2 = contours2[0] # thresh2[...] = 0 # plt.imshow(thresh2) # plt.show() cv2.drawContours(thresh2, [cnt2], 0, 255, cv2.FILLED) # plt.imshow(thresh2) # plt.title('Filled') # plt.show() #----------------------- image = true_image binarize_image = dilation(image, square(3)) binarize_image = dilation(binarize_image, square(3)) binarize_image = dilation(binarize_image, square(3)) binarize_image = erosion(binarize_image, square(3)) binarize_image = erosion(binarize_image, square(3)) image = erosion(binarize_image, square(3)) distance = ndi.distance_transform_edt(image) local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)), labels=image) markers = ndi.label(local_maxi)[0] labels = watershed(-distance, markers, mask=image) fig, axes = plt.subplots(ncols=3, figsize=(8, 2.7), sharex=True, sharey=True, subplot_kw={'adjustable': 'box-forced'}) ax0, ax1, ax2 = axes ax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest') ax0.set_title('Overlapping objects') ax1.imshow(-distance, cmap=plt.cm.jet, interpolation='nearest') ax1.set_title('Distances') ax2.imshow(labels, cmap=plt.cm.spectral, interpolation='nearest') ax2.set_title('Separated objects') for ax in axes: ax.axis('off') fig.subplots_adjust(hspace=0.01, wspace=0.01, top=0.9, bottom=0, left=0, right=1) plt.show() plt.imshow(distance, 'gray') plt.show #----------------------- x, y, w, h = cv2.boundingRect(cnt2) dst_roi = res_rotated[y:y + h, x:x + w] thresh3 = thresh2[y:y + h, x:x + w] cols, rows = dst_roi.shape[:2] if rows < cols: res_rotated = rotate_and_scale(dst_roi, 1, 90) thresh3 = rotate_and_scale(thresh3, 1, 90) cols, rows = dst_roi.shape[:2] return thresh2, thresh3, cols, rows, res_rotated
def crop_blocks(input, target, size_box=76, display=False, earlyStop=None, disk_size=1, channelsFirst=True, do_preprocess=False, offset=0): size_box = size_box if channelsFirst: num_hz_box = int(input.shape[1] / size_box) num_vt_box = int(input.shape[2] / size_box) else: num_hz_box = int(input.shape[0] / size_box) num_vt_box = int(input.shape[1] / size_box) cnt_img = 0 dict_input = {} dict_output = {} for box_h in range(num_hz_box): for box_v in range(num_vt_box): x = box_h * size_box y = box_v * size_box input_box = crop_img(input, x, y, size_box, size_box, channelsFirst) if do_preprocess: # Doing the min_max norm on the cropped data input_box = img_minmax_norm(input_box, channelsFirst) target_box = crop_img(target, x, y, size_box, size_box, channelsFirst) # erode the touching border if disk_size: target_box[1, :, :] = erosion(target_box[1, :, :], disk(disk_size)) dict_input[cnt_img + offset] = input_box dict_output[cnt_img + offset] = target_box cnt_img += 1 if cnt_img > earlyStop: break if display: print('img_%s_input.png' % cnt_img) input_box_rgb = get_rgb(input_box, channelsFirst) if not do_preprocess: input_box_rgb = img_minmax_norm(input_box_rgb, channelsFirst) if channelsFirst: input_box_rgb = np.moveaxis(input_box_rgb, 0, 2) f, axarr = plt.subplots(1, 5) axarr[0].imshow(input_box_rgb) axarr[1].imshow(target_box[0, :, :]) axarr[2].imshow(target_box[1, :, :]) axarr[3].imshow(target_box[2, :, :]) axarr[4].imshow(target_box[0, :, :] - target_box[2, :, :]) plt.show() if cnt_img > earlyStop: break return dict_input, dict_output
import matplotlib.patches as patches path_image = "/Users/StarShipIV/Google_Drive/Progetti/CELdek_Vision/Images/IMG_2041.JPG" # One used for prototyping # path_image = "/Users/StarShipIV/Google_Drive/Progetti/CELdek_Vision/Images/IMG_2043.JPG" # Test im = Image.open(path_image) im.show() im_grey = im.convert('L') im_grey.show() im_bin = 1 * (np.array(im_grey) < 100) plt.imshow(im_bin, interpolation='nearest') plt.show() imeroded = morphology.erosion(im_bin, np.ones((10, 10))) imdilated = morphology.dilation(im_bin, np.ones((10, 10))) label_list = measure.label(imdilated) feats = measure.regionprops(label_list) plt.imshow(label_list, interpolation='nearest') plt.show() maj_axis = feats[0].major_axis_length min_axis = feats[0].minor_axis_length length = maj_axis * 0.008389958386775592 height = min_axis * 0.008509512658515881 print(length, height)
def process_image(fn): scale = 4 #3 d = fn.split('mosaic_')[1] vals = df[(df['filename'] == fn)][['id', 'geometry']].values img = io.imread(path.join(train_dir, d, 'images_masked', fn + '.tif')) h, w = (np.asarray(img.shape[:2]) * scale).astype('int32') labels = np.zeros((h, w), dtype='uint16') border_msk = np.zeros_like(labels, dtype='uint8') tmp = np.zeros((h, w), dtype='bool') cur_lbl = 0 all_polys = [] all_areas = [] for i in range(vals.shape[0]): if vals[i, 0] >= 0: _p = loads(vals[i, 1]) all_polys.append(_p) all_areas.append(-1 * _p.area) all_areas, all_polys = zip( *sorted(zip(all_areas, all_polys), key=lambda pair: pair[0])) for p in all_polys: cur_lbl += 1 draw_polygon(p, labels, border_msk, scale, cur_lbl) labels = measure.label(labels, connectivity=2, background=0) cv2.imwrite(path.join(labels_dir, fn + '.tif'), labels) props = measure.regionprops(labels) msk = np.zeros((h, w), dtype='uint8') if cur_lbl > 0: border_msk = border_msk > 0 tmp = dilation(labels > 0, square(5)) tmp2 = watershed(tmp, labels, mask=tmp, watershed_line=True) > 0 tmp = tmp ^ tmp2 tmp = tmp | border_msk tmp = dilation(tmp, square(3)) msk0 = labels > 0 msk1 = np.zeros_like(labels, dtype='bool') border_add = np.zeros_like(labels, dtype='bool') for y0 in range(labels.shape[0]): for x0 in range(labels.shape[1]): if not tmp[y0, x0]: continue can_rmv = False if labels[y0, x0] == 0: sz = 2 else: sz = 1 can_rmv = True minor_axis_length = props[labels[y0, x0] - 1].minor_axis_length area = props[labels[y0, x0] - 1].area if minor_axis_length < 6 or area < 20: can_rmv = False if minor_axis_length > 25 and area > 150: #area sz = 2 if minor_axis_length > 35 and area > 300: sz = 3 uniq = np.unique( labels[max(0, y0 - sz):min(labels.shape[0], y0 + sz + 1), max(0, x0 - sz):min(labels.shape[1], x0 + sz + 1)]) # can_rmv = False if len(uniq[uniq > 0]) > 1: msk1[y0, x0] = True if labels[y0, x0] > 0: if can_rmv: msk0[y0, x0] = False else: border_add[y0, x0] = True if msk0[y0, x0] and sz > 1 and (0 in uniq): border_add[y0, x0] = True msk1 = 255 * msk1 msk1 = msk1.astype('uint8') new_border_msk = (erosion(msk0, square(3)) ^ msk0) | border_add msk0 = 255 * msk0 msk0 = msk0.astype('uint8') msk2 = 255 * new_border_msk msk2 = msk2.astype('uint8') msk = np.stack((msk0, msk1, msk2)) msk = np.rollaxis(msk, 0, 3) cv2.imwrite(path.join(masks_dir, fn + '.png'), msk, [cv2.IMWRITE_PNG_COMPRESSION, 5])
def segment_image(image, valid_region, show_imgs=False, thres=128, size_thres=64, relative_brightness=True, filtering=False): """Locate the target animal in each frame by image segmentation """ value_min, value_max = image.min(), image.max() image = image * valid_region image = np.clip(image, a_min=value_min, a_max=value_max) image = (image - image.min()) / (image.max() - image.min()) if filtering: image = gaussian(image, sigma=1, preserve_range=True) image = (image * 255).astype(np.uint8) if relative_brightness: temp = image.copy() temp_thres = (temp.max() + temp.mean()) // 2 binary = (image > temp_thres).astype(np.uint8) else: binary = (image > thres).astype(np.uint8) binary = binary * valid_region if binary.sum() > size_thres * 2: binary = erosion(binary) segmentation = label(binary) if len(np.unique(segmentation)) > 2 and binary.sum() > size_thres * 2: segmentation = remove_small_objects(segmentation, size_thres) indices, counts = np.unique(segmentation, return_counts=True) if len(indices) > 1 and indices[0] == 0: indices, counts = indices[1:], counts[1:] pos = [np.argmax(counts)] else: pos = [] if len(pos) >= 1: target_idx = indices[pos[0]] target = (segmentation == target_idx).astype(np.uint8) if target.sum() > size_thres * 2: target = erosion(target) foreground_coord = np.where(target != 0) # print(foreground_coord) center = [ int(foreground_coord[0].astype(float).mean()), int(foreground_coord[1].astype(float).mean()) ] if show_imgs: plt.figure(figsize=(20, 10)) plt.subplot(141) plt.imshow(binary * 255, cmap='gray') plt.title('binary') plt.axis('off') plt.subplot(142) plt.imshow(segmentation, cmap='tab20c') plt.title('segmentation') plt.axis('off') plt.subplot(143) plt.imshow(target, cmap='gray') plt.title('target') plt.axis('off') plt.subplot(144) plt.imshow(image, cmap='gray') plt.scatter(center[1], center[0], c='r', s=20) plt.title('tracking [%d %d]' % (center[1], center[0])) plt.axis('off') plt.show() else: center = [] if show_imgs: plt.figure(figsize=(20, 10)) plt.subplot(131) plt.imshow(image, cmap='gray') plt.title('image') plt.axis('off') plt.subplot(132) plt.imshow(binary * 255, cmap='gray') plt.title('binary') plt.axis('off') plt.subplot(133) plt.imshow(segmentation, cmap='tab20c') plt.title('segmentation') plt.axis('off') plt.show() return center
def compare_flats_to_stack(): lights_folder = 'F:/2020/2020-02-20/pleiades' # mean_lights_image = load_images(lights_folder) # clipped_display(mean_lights_image, z=5) cache_name = os.path.join(lights_folder, 'removed_stars_mean_image.cache') if os.path.exists(cache_name): sum_image = pickle.load(open(cache_name, 'rb')) else: sum_image = None filenames = list( filter(lambda s: s.endswith('.ARW'), os.listdir(lights_folder)))[:10] for filename in tqdm.tqdm(filenames): test_path = os.path.join(lights_folder, filename) test_image = load_raw_image(test_path).astype('float') if sum_image is None: sum_image = np.zeros_like(test_image) img_8bit = np.mean(test_image, axis=2) img_8bit = (img_8bit / (np.max(img_8bit) / 255)).astype('uint8') bw_image = np.mean(test_image, axis=2) thresh_niblack = threshold_niblack(bw_image, window_size=51, k=0.0) stars_mask = bw_image > (thresh_niblack + 250) for _ in range(5): stars_mask = dilation(stars_mask) mask_copy = stars_mask.copy() working_image = test_image.copy() while np.sum(mask_copy) > 0: mask_copy = erosion(mask_copy) for channel in range(3): working_image[:, :, channel] = erosion(working_image[:, :, channel]) if 0: plt.imshow(np.log(np.mean(test_image, axis=2))) plt.show() plt.imshow(np.log(np.mean(working_image, axis=2))) plt.show() filled_image = np.zeros_like(test_image) for channel in range(3): filled_image[:, :, channel] = test_image[:, :, channel] * ( 1 - stars_mask) + working_image[:, :, channel] * stars_mask sum_image += filled_image if 0: plt.imshow(np.log(np.mean(filled_image, axis=2))) plt.show() if 0: plt.subplot(3, 1, 1) # plt.imshow(img_8bit) # stars_thresh = cv2.adaptiveThreshold(img_8bit, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 201, 1) # plt.imshow(test_image / np.max(test_image)) plt.imshow(bw_image / np.max(bw_image)) # stars_thresh = threshold_adaptive(test_image, 201, offset = 10) # thresh_sauvola = threshold_sauvola(bw_image, window_size=21) # stars_thresh = bw_image > thresh_sauvola # print(thresh_sauvola) plt.subplot(3, 1, 2) plt.imshow(stars_mask / np.max(stars_mask)) plt.subplot(3, 1, 3) plt.imshow(filled_image / np.max(filled_image)) plt.show() sum_image /= len(filenames) pickle.dump(sum_image, open(cache_name, 'wb')) plt.imshow(sum_image[:, :, 0]) plt.show()
def plot_image_mask_hyper_out(label, out_mask, out_mask_true, path, suffix=None, label_rgb=False, gt=False): fig = plt.figure(figsize=(16,9), dpi=150) ax1 = plt.subplot2grid((3, 5), (0, 0), colspan=2, rowspan=3) ax2 = plt.subplot2grid((3, 5), (0, 2), colspan=1, rowspan=1) ax3 = plt.subplot2grid((3, 5), (1, 2), colspan=1, rowspan=1) ax4 = plt.subplot2grid((3, 5), (2, 2), colspan=1, rowspan=1) ax5 = plt.subplot2grid((3, 5), (0, 3), colspan=2, rowspan=3) with Image.open(os.path.join(path, label, 'images', '{}.png'.format(label))) as x_img: x_plot = x_img.convert(mode='L') # x_img = ImageOps.autocontrast(x_img) x_arr = np.array(x_img) save_shape = x_arr.shape # plt.subplot(221) ax1.imshow(x_arr) ax1.axis('off') ax1.set_title('Input Image') with Image.open(os.path.join(path, label, 'mask', '{}.png'.format(label))) as x_img: x_plot = x_img.convert(mode='L') # x_img = ImageOps.autocontrast(x_img) x_arr = np.array(x_img) # ax2.subplot(222) ax2.imshow(x_arr, cmap=cm.gray) ax2.axis('off') ax2.set_title('Mask (ground truth)') with Image.open(os.path.join(path, label, 'smashing_border', '{}.png'.format(label))) as x_img: x_plot = x_img.convert(mode='L') # x_img = ImageOps.autocontrast(x_img) x_arr = np.array(x_img) # plt.subplot(223) ax3.imshow(x_arr) ax3.axis('off') ax3.set_title('Borders') out_mask_p = out_mask * 255 # label_image = morphology.label(out_mask_p) # image_label_overlay = label2rgb(label_image, image=out_mask_p) # plt.subplot(224) ax4.imshow(out_mask_p, cmap=cm.gray, vmin=0, vmax=255) ax4.axis('off') ax4.set_title('Output') # print(np.max(out_mask_true), np.min(out_mask_true)) if label_rgb: out_mask_p = out_mask_true * 255 label_image = morphology.label(out_mask_p, background=0) # image_label_overlay = label2rgb(label_image, image=out_mask_p) out_mask_true = label_image out_mask_true = np.ma.masked_equal(out_mask_true, 0) import copy cmap = copy.copy(cm.prism) cmap.set_bad(color='black') ax5.imshow(out_mask_true, cmap=cmap) ax5.axis('off') ax5.set_title('Output (original size)') else: true_bord = x_arr true_bord[true_bord>0] = 1 true_bord = morphology.erosion(true_bord) true_bord = imresize(true_bord, size=(save_shape[0], save_shape[1])) true_bord = np.ma.masked_equal(true_bord, 0) ax5.imshow(out_mask_true, cmap=cm.gray) if gt: ax5.imshow(true_bord, cmap=cm.prism, alpha=.95) ax5.axis('off') ax5.set_title('Output (original size)') fig.savefig('testt/{0}img{1}.png'.format(label[:5], suffix),bbox_inches='tight') plt.close()
dst1=sm.dilation(img,sm.square(5)) #用边长为5的正方形滤波器进行膨胀滤波 dst2=sm.dilation(img,sm.square(15)) #用边长为15的正方形滤波器进行膨胀滤波 fig = plt.figure('morphology',figsize=(12,4)) fig.suptitle('dilation') plt.subplot(131) plt.title('origin image') plt.imshow(img,plt.cm.gray) plt.subplot(132) plt.title('morphological image') plt.imshow(dst1,plt.cm.gray) plt.subplot(133) plt.title('morphological image') plt.imshow(dst2,plt.cm.gray) plt.show() '''2、腐蚀(erosion)''' dst1=sm.erosion(img,sm.square(5)) #用边长为5的正方形滤波器进行膨胀滤波 dst2=sm.erosion(img,sm.square(25)) #用边长为25的正方形滤波器进行膨胀滤波 fig = plt.figure('morphology',figsize=(12,4)) fig.suptitle('erosion') plt.subplot(131) plt.title('origin image') plt.imshow(img,plt.cm.gray) plt.subplot(132) plt.title('morphological image') plt.imshow(dst1,plt.cm.gray) plt.subplot(133) plt.title('morphological image') plt.imshow(dst2,plt.cm.gray) plt.show() '''3、开运算(opening)''' img=color.rgb2gray(io.imread('mor.png'))
def prepareCervixAndChannelInfo(pimg, pRelChnSize=0.4, isDebug=False): # (1) prepare masks tmsk = pimg[:, :, 3] timg = pimg[:, :, :3] tmsk_chn = (tmsk == 128) tmsk_crv = (tmsk > 100) # rc - mean first-idx -> row, second-idx -> column, xy - mean first-idx -> column, second-idx -> row :) # (2) find channel cover-circle and center of this corcle rc_pts_channel = np.array(np.where(tmsk_chn)).transpose() (rc_channel_cnt, r_channel) = cv2.minEnclosingCircle(rc_pts_channel) dist_chn2cnt = calcDistArr2Point(rc_pts_channel, rc_channel_cnt) r_channel_good = rc_pts_channel[dist_chn2cnt < pRelChnSize * r_channel, :] #FIXME: Fill holes before this step!!! # (2) prepare cervix contour contour_crv = tmsk_crv & (~skmorph.erosion(tmsk_crv, skmorph.disk(1))) rc_crvContour = np.array(np.where(contour_crv)).transpose() dist_contour2cnt = calcDistArr2Point(rc_crvContour, rc_channel_cnt) r_cervix = np.min(dist_contour2cnt) # rcCrvRminArg = np.argmin(rcRContour) if r_cervix < r_channel: r_cervix = r_channel ret = { 'r_crv': r_cervix, 'r_chn': r_channel, 'r_chn_good': pRelChnSize * r_channel, 'cnt_chn': rc_channel_cnt, 'rc_chn': r_channel_good.copy() } if isDebug: retSize = 256 newScale = float(retSize) / (2. * r_cervix + 2.) xy_channel_cnt = rc_channel_cnt[::-1] timg_crop = buildImageWithRotScaleAroundCenter(timg, xy_channel_cnt, 45., newScale, (retSize, retSize), isDebug=False) # plt.subplot(2, 2, 1) plt.imshow(tmsk_chn) plt.gcf().gca().add_artist( plt.Circle(rc_channel_cnt[::-1], r_channel, edgecolor='r', fill=False)) plt.gcf().gca().add_artist( plt.Circle(rc_channel_cnt[::-1], r_cervix, edgecolor='g', fill=False)) plt.plot(r_channel_good[:, 1], r_channel_good[:, 0], 'y.') plt.subplot(2, 2, 2) plt.imshow(tmsk_crv) plt.gcf().gca().add_artist( plt.Circle(rc_channel_cnt[::-1], r_channel, edgecolor='r', fill=False)) plt.gcf().gca().add_artist( plt.Circle(rc_channel_cnt[::-1], r_cervix, edgecolor='g', fill=False)) plt.subplot(2, 2, 3) plt.imshow(timg) plt.gcf().gca().add_artist( plt.Circle(rc_channel_cnt[::-1], r_channel, edgecolor='r', fill=False)) plt.gcf().gca().add_artist( plt.Circle(rc_channel_cnt[::-1], r_cervix, edgecolor='g', fill=False)) plt.subplot(2, 2, 4) plt.imshow(timg_crop) plt.show() return ret
centers_all=[] pattern_arm_all=[] for i in xrange(len(listfiles)): patt = tc.opentiff(path+'/'+listfiles[i]) temp = patt.find_and_read(0) imObj = utilities.ExtractImage(temp, 6) img_adapteq = exposure.equalize_adapthist(imObj.smooth, clip_limit=0.03) img_adapteq /= (np.max(img_adapteq)/255.) hist,bins = np.histogram(img_adapteq,256,[0,256]) hist2=smooth(hist,40) histmax = argrelmax(hist2) ret, thresh=cv2.threshold(np.array(img_adapteq, dtype = np.uint8), (histmax[-1][-1]+255)/2, 255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) thresh[thresh == 0] = 1 thresh[thresh == 255] = 0 selem = disk(5) thresh = erosion(thresh, selem) label_image = label(thresh) rep = regionprops(label_image) centers = np.zeros((len(rep),2)) areas = np.zeros(len(rep)) for j in xrange(len(rep)): centers[j, :] = rep[j]['centroid'] areas[j] = rep[j]['area'] pattern_arm = np.round((np.percentile(areas, 95)/np.pi)**0.5+5) centers = np.delete(centers, np.concatenate([np.where(areas < np.median(areas)/4.)[0],np.where(areas > np.median(areas)*3.)[0]]), axis=0) areas = np.delete(areas, np.concatenate([np.where(areas < np.median(areas)/4.)[0],np.where(areas > np.median(areas)*3.)[0]])) areas = np.delete(areas, np.concatenate([np.where(centers[:, 0] < pattern_arm*2)[0], np.where(centers[:, 1] < pattern_arm*2)[0], np.where(thresh.shape[0]-centers[:, 0] < pattern_arm*2)[0], np.where(thresh.shape[1]-centers[:, 1] < pattern_arm*2)[0]])) centers = np.delete(centers, np.concatenate([np.where(centers[:, 0] < pattern_arm*2)[0], np.where(centers[:, 1] < pattern_arm*2)[0], np.where(thresh.shape[0]-centers[:, 0] < pattern_arm*2)[0], np.where(thresh.shape[1]-centers[:, 1] < pattern_arm*2)[0]]), axis=0)
def find_boards(img): boards = [] debug_img = ski.img_as_ubyte(img) img = ski.img_as_ubyte(img) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 40, 70) boards_img = ski.img_as_bool(edges) boards_img = mp.remove_small_holes(boards_img, 250) boards_img = mp.dilation(boards_img, mp.disk(1)) boards_img = mp.thin(boards_img) boards_img = ndi.binary_fill_holes(boards_img) squares = mp.erosion(boards_img, mp.disk(3)) squares = mp.remove_small_objects(squares, 45) squares = ski.img_as_ubyte(squares) contours, hierarchy = cv2.findContours(squares, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) potential_boards = [] for c in contours: peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.05 * peri, True) if len(approx) == 4: potential_boards.append(approx) # cv2.drawContours(img, approx, -1, (0, 0, 255), 5) for b in potential_boards: M = cv2.moments(b) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) rotated_rect = cv2.minAreaRect(b) (x, y), (w, h), angle = rotated_rect box = cv2.boxPoints(rotated_rect) box = np.int0(box) src_pts = box.astype("float32") src_pts = transform_src_pts(src_pts) dst_pts = np.array([[0, h], [0, 0], [w, 0], [w, h]], dtype="float32") dst_pts *= 3 M = cv2.getPerspectiveTransform(src_pts, dst_pts) bg_color = np.mean(img) warped = cv2.warpPerspective(img, M, (int(w * 1.8 * 3), int(h * 1.8 * 3)), borderMode=cv2.BORDER_CONSTANT, borderValue=(bg_color, bg_color, bg_color)) gray = cv2.cvtColor(warped, cv2.COLOR_RGB2GRAY) gray = mean_bilateral(ski.img_as_ubyte(gray), mp.disk(5), s0=10, s1=10) gray = ski.img_as_float(gray) gray = 1 - gray gray = cv2.resize(gray, (100, 100)) boards.append(ski.img_as_float(gray)) cv2.destroyAllWindows() # show_boards(boards) return boards
from scipy import ndimage as ndi import skimage as ski import skimage.morphology as morph from skimage.color import label2rgb from skimage.feature import canny import matplotlib.pyplot as plt img = ski.io.imread('Cap403border.png', as_gray=True) edges = canny(img, sigma=3.5) edges = morph.dilation(edges) filled = ndi.binary_fill_holes(edges) filled = morph.erosion(filled) filled = morph.remove_small_objects(filled, min_size=70) labeled, _ = ndi.label(filled) image_label_overlay = label2rgb(labeled, image=filled) fig, axes = plt.subplots(1, 2, figsize=(8, 3), sharey=True) axes[0].imshow(img, cmap=plt.cm.gray, interpolation='nearest') axes[0].contour(filled, [0.5], linewidths=1.2, colors='y') axes[1].imshow(image_label_overlay, interpolation='nearest') _, ax = plt.subplots(figsize=(4, 3)) ax.imshow(filled, cmap=plt.cm.gray, interpolation='nearest') ax.set_title('filling the holes') ax.axis('off') plt.show()
def erosion(img): # return greyscale morphological erosion of an image return mp.erosion(img, mp.square(2, dtype=np.uint8))
def THR(ivtNV, kernel, oroNV=None, high_terrain=600, verbose=True): '''Perform THR filtering process on 3d data Args: ivtNV (NCVAR): 3D or 4D input IVT data, with dimensions (time, lat, lon) or (time, level, lat, lon). kernel (list or tuple): list/tuple of integers specifying the shape of the kernel/structuring element used in the gray erosion process. Keyword Args: oroNV (NCVAR or None): 2D array, surface orographic data in meters. This optional surface height info is used to perform a separate reconstruction computation for areas with high elevations, and the results can be used to enhance the continent-penetration ability of landfalling ARs. Sensitivity in landfalling ARs is enhanced, other areas are not affected. Needs to have compatible (lat, lon) shape as <ivt>. If None, omit this process and treat areas with different heights all equally. New in v2.0. high_terrain (float): minimum orographic height (in m) to define as high terrain area, within which a separate reconstruction is performed. Only used if <oroNV> is not None. New in v2.0. verbose (bool): print some messages or not. Returns: ivtNV (NCVAR): 3D or 4D array, input <ivt>. ivtrecNV (NCVAR): 3D or 4D array, the reconstruction component from the THR process. ivtanoNV (NCVAR): 3D or 4D array, the difference between input <ivt> and <ivtrecNV>. ''' ivt=ivtNV.data ndim=np.ndim(ivt) ivt=np.squeeze(ivt) #-------------------3d ellipsoid------------------- ele=funcs.get3DEllipse(*kernel) #################### use a cube to speed up ############## # empirical if kernel[0]>=16 or kernel[1]>=6: ele=np.ones(ele.shape) ########################################################## # reconstruction element: a 6-connectivity element rec_ele=np.zeros([3,3,3]) rec_ele[0,1,1]=1 rec_ele[1,:,1]=1 rec_ele[1,1,:]=1 rec_ele[2,1,1]=1 if verbose: print('\n# <THR>: Computing erosion ...') lm=morphology.erosion(ivt, selem=ele) if verbose: print('\n# <THR>: Computing reconstruction ...') ivtrec=morphology.reconstruction(lm, ivt, method='dilation', selem=rec_ele) # perform an extra reconstruction over land if oroNV is not None: orodata=np.squeeze(oroNV.data) oro_rs=np.where(orodata>=high_terrain, 1, 0) oro_rs=oro_rs[None,...] oro_rs=np.repeat(oro_rs, len(ivt), axis=0) ivtrec_oro=morphology.reconstruction(lm*oro_rs, ivt, method='dilation', selem=rec_ele) ivtano=np.ma.maximum(ivt-ivtrec, (ivt-ivtrec_oro)*oro_rs) else: ivtano=ivt-ivtrec ivtrec=ivt-ivtano axislist=ivtNV.axislist #---------If inputs are 4d, also return 4d--------- if ndim==4: ivt=ivt[:,None,...] ivtrec=ivtrec[:,None,...] ivtano=ivtano[:,None,...] ivtrecNV=funcs.NCVAR(ivtrec, 'ivt_rec', axislist, {'name': 'ivt_rec', 'long_name': '%s, THR reconstruction' %(getattr(ivt, 'long_name', '')), 'standard_name': '%s, THR reconstruction' %(getattr(ivt, 'long_name', '')), 'units': getattr(ivt, 'units', '')}) ivtanoNV=funcs.NCVAR(ivtano, 'ivt_ano', axislist, {'name': 'ivt_ano', 'long_name': '%s, THR anomaly' %(getattr(ivt, 'long_name', '')), 'standard_name': '%s, THR anomaly' %(getattr(ivt, 'long_name', '')), 'units': getattr(ivt, 'units', '')}) return ivtNV, ivtrecNV, ivtanoNV