def test_hessian_matrix(dtype): square = np.zeros((5, 5), dtype=dtype) square[2, 2] = 4 Hrr, Hrc, Hcc = hessian_matrix(square, sigma=0.1, order='rc', use_gaussian_derivatives=False) out_dtype = _supported_float_type(dtype) assert all(a.dtype == out_dtype for a in (Hrr, Hrc, Hcc)) assert_almost_equal( Hrr, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [2, 0, -2, 0, 2], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])) assert_almost_equal( Hrc, np.array([[0, 0, 0, 0, 0], [0, 1, 0, -1, 0], [0, 0, 0, 0, 0], [0, -1, 0, 1, 0], [0, 0, 0, 0, 0]])) assert_almost_equal( Hcc, np.array([[0, 0, 2, 0, 0], [0, 0, 0, 0, 0], [0, 0, -2, 0, 0], [0, 0, 0, 0, 0], [0, 0, 2, 0, 0]])) with expected_warnings(["use_gaussian_derivatives currently defaults"]): # FutureWarning warning when use_gaussian_derivatives is not # specified. hessian_matrix(square, sigma=0.1, order='rc')
def apply_filters(images, sigmas): """ Apply multiple filters to 'images' """ filtered_images = [] for img in images: filtered = [] for sigma in sigmas: for conv_filter in [ gaussian_filter, gaussian_laplace, gaussian_gradient_magnitude ]: filtered.append(conv_filter(img, sigma)) # *_eigenvals has changed from version 0.13 to 0.14. try: # v. 0.14 eigs_struc = structure_tensor_eigvals( *structure_tensor(img, sigma=sigma)) eigs_hess = hessian_matrix_eigvals( hessian_matrix(img, sigma=sigma, order="xy")) except TypeError as e: # v. 0.13 eigs_struc = structure_tensor_eigvals( *structure_tensor(img, sigma=sigma)) eigs_hess = hessian_matrix_eigvals( *hessian_matrix(img, sigma=sigma, order="xy")) for eig_h, eig_s in zip(eigs_struc, eigs_hess): filtered.append(eig_h) filtered.append(eig_s) filtered.append(equalize_hist(img)) #selem = disk(30) #filtered.append(equalize(img, selem=selem)) filtered_images.append(filtered) return np.array(filtered_images)
def ridge_filter_hessian(img, sigma=3): """ Apply Hessian filtering to enhance vessel-like structures Parameters ---------- img : numpy array (n_rows, n_cols) grayscale input image sigma : int width of the Gaussian used for smoothing gradients Returns ------- i2 : numpy array image same size image showing enhanced ridge like structures """ from skimage.feature import hessian_matrix, hessian_matrix_eigvals from skimage.filters import threshold_otsu from skimage.morphology import skeletonize hxx, hxy, hyy = hessian_matrix(img, sigma=sigma) i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy) i2 = i2 <= threshold_otsu(i2) i2 = skeletonize(i2) return i2
def remove_ridges(image, width=6, threshold=160, dilation=1, return_mask=False): """Detect ridges of width pixels using the highest eigenvector of the Hessian matrix, then create a binarized mask with threshold and remove it from image (set to black). Default values are optimized for text detection and removal. A dilation radius in pixels can be passed in to thicken the mask prior to being applied.""" gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # The value of sigma is calculated according to Steger's work: # An Unbiased Detector of Curvilinear Structures, # IEEE Transactions on Pattern Analysis and Machine Intelligence, # Vol. 20, No. 2, Feb 1998 # http://ieeexplore.ieee.org/document/659930/ sigma = (width / 2) / np.sqrt(3) hxx, hxy, hyy = feature.hessian_matrix(gray_image, sigma=sigma, order='xy') large_eigenvalues, _ = feature.hessian_matrix_eigvals(hxx, hxy, hyy) mask = convert(large_eigenvalues) mask = binarize_image(mask, method='boolean', threshold=threshold) if dilation: dilation = (2 * dilation) + 1 dilation_kernel = np.ones((dilation, dilation), np.uint8) mask = cv2.dilate(mask, dilation_kernel) return image, 255 - mask
def enhance_ridges(frame): """A ridge detection filter (larger hessian eigenvalue)""" blurred = filters.gaussian(frame, 2) sigma = 4.5 Hxx, Hxy, Hyy = feature.hessian_matrix(blurred, sigma=sigma, mode='nearest', order='xy') ridges = feature.hessian_matrix_eigvals(Hxx, Hxy, Hyy)[1] return np.abs(ridges)
def enhance_ridges(frame, mask=None): """Detect ridges (larger hessian eigenvalue)""" blurred = filters.gaussian_filter(frame, 2) Hxx, Hxy, Hyy = feature.hessian_matrix(blurred, sigma=4.5, mode="nearest") ridges = feature.hessian_matrix_eigvals(Hxx, Hxy, Hyy)[0] return np.abs(ridges)
def meijering(image, sigma, black_ridges=False): # sigma equals the radius of the ridge being emphasized print "Applying meijering filter ..." image = image.astype(np.float64) if black_ridges: image = -image value = np.zeros(image.shape) Hxx, Hxy, Hyy = hessian_matrix(image, sigma=sigma, order="rc") b1 = Hxx + Hyy b2 = Hxx - Hyy d = np.sqrt(4 * Hxy * Hxy + b2 * b2) L1 = (b1 + 2 * d) / 3.0 L2 = (b1 - 2 * d) / 3.0 vect1x = b2 + d vect2x = b2 - d vecty = 2 * Hxy vectx = np.array([vect1x, vect2x]) sortedL, sortedvectx = sortbyabs(np.array([L1, L2]), auxiliary=vectx) L = sortedL[1] vectx = sortedvectx[0] vectlen = np.sqrt(vectx**2 + vecty**2) vectx /= vectlen vecty /= vectlen valL = np.where(L > 0, 0, L) mask = np.abs(vecty) < np.cos( np.deg2rad(ALLOWED_ANGLE) ) # make sure to remove unnecessary signals oriented close to the y-axis valL[mask] = 0 valL = divide_nonzero(valL, np.min(valL)) vect = np.array([vectx, vecty]) print " -> complete!" return valL, vect
def enhance_ridges(frame, mask=None): """Detect ridges (larger hessian eigenvalue)""" blurred = filters.gaussian_filter(frame, 2) Hxx, Hxy, Hyy = feature.hessian_matrix(blurred, sigma=4.5, mode='nearest') ridges = feature.hessian_matrix_eigvals(Hxx, Hxy, Hyy)[0] return np.abs(ridges)
def detect_ridges(gray, sigma=3.0): # https://stackoverflow.com/questions/48727914/how-to-use-ridge-detection-filter-in-opencv hxx, hxy, hyy = hessian_matrix(gray, sigma) i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy) maxima_ridges = i1 minima_ridges = i2 return maxima_ridges, minima_ridges
def detect_ridges_concurrent(data, logging=True): """Detects sulcus-like "ravines" from 3d image using modified hessian ridge detection Args: data (ndarray): 3-dimensional image data array. logging (bool, optional): Process execution logging. Defaults to True. """ (xMax, _, _) = data.shape P_COUNT = 4 H_elems = hessian_matrix(data, sigma=1) with Pool(P_COUNT) as pool: width = math.ceil(xMax / P_COUNT) multi_res = [ pool.apply_async(p_main, (width * i, min(width * (i + 1), xMax), H_elems, logging)) for i in range(P_COUNT) ] results = [res.get(timeout=300) for res in multi_res] output_data = np.zeros(data.shape) for i in range(P_COUNT): output_data += results[i] if logging: print("\nall processes completed") return (output_data)
def meijering(image, black_ridges=True): # sigma equals the radius of the ridge being emphasized sigma = (FILAMENT_DIAMETER - FILAMENT_INNER_DIAMETER) / APIX / BIN / 2 image = image.astype(np.float64) if black_ridges: image = -image value = np.zeros(image.shape) Hxx, Hxy, Hyy = hessian_matrix(image, sigma=sigma, order="rc") b1 = Hxx + Hyy b2 = Hxx - Hyy d = np.sqrt(4 * Hxy * Hxy + b2 * b2) L1 = (b1 + 2 * d) / 3.0 L2 = (b1 - 2 * d) / 3.0 vect1x = b2 + d vect2x = b2 - d vecty = 2 * Hxy vectx = np.array([vect1x, vect2x]) sortedL, sortedvectx = sortbyabs(np.array([L1, L2]), auxiliary=vectx) L = sortedL[1] vectx = sortedvectx[0] vectlen = np.sqrt(vectx**2 + vecty**2) vectx /= vectlen vecty /= vectlen valL = np.where(L > 0, 0, L) valL = divide_nonzero(valL, np.min(valL)) vect = np.array([vectx, vecty]) return valL, vect
def enhance_ridges(frame): """A ridge detection filter (larger hessian eigenvalue)""" blurred = filters.gaussian_filter(frame, 2) sigma = 4.5 Hxx, Hxy, Hyy = feature.hessian_matrix(blurred, sigma=sigma, mode='nearest') ridges = feature.hessian_matrix_eigvals(Hxx, Hxy, Hyy)[0] return np.abs(ridges)
def preprocess_image(image, out_skeleton=False, out_branching_image=False): """ Performs preprocessing of keratin images. Returns: - normalized ridges; - branchings potential; - branchings forces; """ # 1) Compute hessian matrix and find its eigen values hxx, hxy, hyy = hessian_matrix(image, sigma=1.5) eigenval_large = hessian_matrix_eigvals(hxx, hxy, hyy)[1] # 2) Take largest eigenvalue and detect ridges ridges = 1.0 - exposure.rescale_intensity(eigenval_large) # 3) Normalize ridges # 3.1) Calculate intensity histogram hvals, hticks = exposure.histogram(ridges) th0 = hticks[np.argmax(hvals)] # 3.2) Rescale based on the peek-internsity (assumed to be background) ridges_rescale = (ridges - th0) * INTENSITY_SCALE # 3.3) Apply double-side thresholding ridges_norm = double_threshold(ridges_rescale, INTENSITY_THRESHOLD_MIN, INTENSITY_THRESHOLD_MAX) # 4) Calculate and process binary mask mask = ridges_norm > 0.1 # cv2.adaptiveThreshold(255 - (255 * ridges).astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) == 0 mask_denoised = remove_small_objects(mask, 50) mask_connected = remove_small_holes(mask_denoised, 3) # 5) Build skeleton skeleton = skeletonize(mask_connected) # skeleton = pruning(skeleton_raw, 15) # skeleton pruning # 6) Find branching points branching_points = np.logical_or( branchedPoints(skeleton) > 0, endPoints(skeleton) > 0) branching_props = measure.regionprops(measure.label(branching_points), cache=False) branching_coords = np.array([prop.centroid for prop in branching_props])[:, [1, 0]] # branching_indices = np.where(branching_points) # branching_coords = np.hstack([branching_indices[1].reshape(-1, 1), branching_indices[0].reshape(-1, 1)]) results = [ridges_norm, branching_coords, mask_connected] if out_skeleton: results.append(skeleton) if out_branching_image: results.append(branching_points) # Return results return tuple(results)
def track(self, frame1_grayscale_mat, frame2_grayscale_mat, pos1_rotation_mat, pos1_translation): print('track frame started') octaves = SiftTrackerVadimFarutin.generate_differences_of_gaussians( frame2_grayscale_mat) extrema = [] for octave in octaves: height, width = octave[0].shape scale_x = self.frame_size[0] / width scale_y = self.frame_size[1] / height for i in range(1, len(octave) - 1): Hxx, Hxy, Hyy = hessian_matrix(octave[i], order='rc') histograms = SiftTrackerVadimFarutin.histograms(octave[i]) for x in range(1, width - 1): for y in range(1, height - 1): hessian = [Hxx[y][x], Hxy[y][x], Hyy[y][x]] is_keypoint = SiftTrackerVadimFarutin.is_keypoint( octave[i - 1], octave[i], octave[i + 1], x, y, hessian) if is_keypoint: histogram = histograms[y][x][0][0] orientation = np.argmax(histogram) descriptor = SiftTrackerVadimFarutin.generate_descriptor( octave[i], x, y) extrema.append([ x * scale_x, y * scale_y, scale_x, scale_y, orientation, descriptor ]) # Keypoint localization, find subpixel extrema # Keypoint descriptor # Match features # keypoint_image = cv2.cvtColor(frame2_grayscale_mat, cv2.COLOR_GRAY2BGR) # for keypoint in extrema: # cv2.circle(keypoint_image, # (int(keypoint[0]), int(keypoint[1])), # 1, (0, 0, 255), 1) # while True: # cv2.imshow('keypoints', keypoint_image) # if cv2.waitKey(1) & 0xFF == ord('q'): # cv2.destroyAllWindows() # break pos2_rotation_mat = pos1_rotation_mat pos2_translation = pos1_translation print('track frame finished') return pos2_rotation_mat, pos2_translation
def _frangi_hessian_common_filter(idx, image, sigmas, beta1, beta2): """ See skimage implementation and documentation. Modified from skimage to facilitate intermediary caching and the exponential scale to improve performance of frangi when same images are being used multiple times. (As is the case when using CMA-ES optimisations). """ # pylint: disable=too-many-locals if np.any(np.asarray(sigmas) < 0.0): raise ValueError("Sigma values less than zero are not valid") beta1 = 2 * beta1**2 beta2 = 2 * beta2**2 filtered_array = np.zeros(sigmas.shape + image.shape) lambdas_array = np.zeros(sigmas.shape + image.shape) use_cache = idx is not None if use_cache: ensure_cache_dir_exists() # Disable naming warnings as this is skimage code that I don't have time to rewrite. # pylint: disable=invalid-name # Filtering for all sigmas for i, sigma in enumerate(sigmas): key = str(idx) + ':' + str(sigma) # idx of None implies do not use key if use_cache and is_in_lambda_cache(key): lambda1, rb, s2 = load_from_cache(key) else: # Make 2D hessian D = hessian_matrix(image, sigma, order='rc') # Correct for scale D = np.array(D) * (sigma**2) # Calculate (abs sorted) eigenvalues and vectors lambda1, lambda2 = hessian_matrix_eigvals(D) # Compute some similarity measures lambda1[lambda1 == 0] = 1e-10 rb = (lambda2 / lambda1)**2 s2 = lambda1**2 + lambda2**2 if use_cache: save_to_cache(key, (lambda1, rb, s2)) # Compute the output image filtered = np.exp( -rb / beta1) * (np.ones(np.shape(image)) - np.exp(-s2 / beta2)) # Store the results in 3D matrices filtered_array[i] = filtered lambdas_array[i] = lambda1 # pylint: enable=invalid-name # pylint: enable=too-many-locals return filtered_array, lambdas_array
def principal_directions(img, sigma, H=None): """ will ignore calculation of principal directions of masked areas despite the name, this function actually returns the theta corresponding to leading and trailing principal directions, i.e. angle w / x axis """ if H is None: H = hessian_matrix(img, sigma) Hxx, Hxy, Hyy = H # check if input image is masked try: mask = img.mask except AttributeError: masked = False else: masked = True dims = img.shape # where to store trailing_thetas = np.zeros_like(img) leading_thetas = np.zeros_like(img) # maybe implement a small angle correction for i, (xx, xy, yy) in enumerate(np.nditer([Hxx, Hxy, Hyy])): # grab the (x,y) coordinate of the hxx, hxy, hyy you're using subs = np.unravel_index(i, dims) # ignore masked areas (if masked array) if masked and img.mask[subs]: continue h = np.array([[xx, xy], [xy, yy]]) # per-pixel hessian l, v = eig(h) # eigenvectors as columns # reorder eigenvectors by (increasing) magnitude of eigenvalues v = v[:,np.argsort(np.abs(l))] # angle between each eigenvector and positive x-axis # arccos of first element (dot product with (1,0) and eigvec is already # normalized) trailing_thetas[subs] = np.arccos(v[0,0]) # first component of each leading_thetas[subs] = np.arccos(v[0,1]) # first component of each if masked: leading_thetas = ma.masked_array(leading_thetas, mask) trailing_thetas = ma.masked_array(trailing_thetas, mask) return trailing_thetas, leading_thetas
def multiscale_seed_sequence(prob, l1_threshold=0, grid_density=10): npoints = ((prob.shape[1] // grid_density) * (prob.shape[2] // grid_density)) seeds = np.zeros(prob.shape, dtype=int) for seed, p in zip(seeds, prob): hm = feature.hessian_matrix(p, sigma=3) l1, l2 = feature.hessian_matrix_eigvals(*hm) curvy = (l1 > l1_threshold) seed[:] = multiscale_regular_seeds(curvy, npoints) return seeds
def detect_ridges(self, image, sigma=3.0): pad = round(sigma * 3) padded = np.pad(image, pad, 'edge') hessian = hessian_matrix(padded, sigma, order="rc") hessian[0] = np.zeros(hessian[0].shape) hessian[1] = np.zeros(hessian[1].shape) i1, i2 = hessian_matrix_eigvals(hessian) i1 = i1[pad:image.shape[0] + pad, pad:image.shape[1] + pad] i2 = i2[pad:image.shape[0] + pad, pad:image.shape[1] + pad] return i1, i2
def test_hessian_matrix_3d(): cube = np.zeros((5, 5, 5)) cube[2, 2, 2] = 4 Hs = hessian_matrix(cube, sigma=0.1, order='rc') assert len(Hs) == 6, ("incorrect number of Hessian images (%i) for 3D" % len(Hs)) assert_almost_equal( Hs[2][:, 2, :], np.array([[0, 0, 0, 0, 0], [0, 1, 0, -1, 0], [0, 0, 0, 0, 0], [0, -1, 0, 1, 0], [0, 0, 0, 0, 0]]))
def derivatives(img, sigma): # ALL RETURN VALUES ARE ARRAYS SAME SIZE AS img # convolve with 0th derivative along axis 0 and 1st derivative along axis 1 gives us x-gradient # x is axis 1, y is axis 0 rx = gaussian_filter(img.astype(np.float64), sigma = sigma, order = (0,1)) # vice versa ry = gaussian_filter(img.astype(np.float64), sigma = sigma, order = (1,0)) # mode constant: used to handle image edges rxx, rxy, ryy = hessian_matrix(img, sigma = sigma, mode = 'constant', cval = 0) return rx, ry, rxx, rxy, ryy
def test_hessian_matrix_3d(): cube = np.zeros((5, 5, 5)) cube[2, 2, 2] = 4 Hs = hessian_matrix(cube, sigma=0.1, order='rc') assert len(Hs) == 6, ("incorrect number of Hessian images (%i) for 3D" % len(Hs)) assert_almost_equal(Hs[2][:, 2, :], np.array([[0, 0, 0, 0, 0], [0, 1, 0, -1, 0], [0, 0, 0, 0, 0], [0, -1, 0, 1, 0], [0, 0, 0, 0, 0]]))
def test_hessian_matrix_eigvals(): square = np.zeros((5, 5)) square[2, 2] = 1 Hxx, Hxy, Hyy = hessian_matrix(square, sigma=0.1) l1, l2 = hessian_matrix_eigvals(Hxx, Hxy, Hyy) assert_array_equal( l1, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) ) assert_array_equal( l2, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) )
def apply_filters(imDsets, lblDsets, sigma, gauss, gaussLaplace, gaussGradientMagnitude, structTensor, hessEigenvalues): for i in range(3): for j in range(len(sigma)): gauss.append(ndi.gaussian_filter(imDsets[i], sigma[j])) gaussLaplace.append(ndi.gaussian_laplace(imDsets[i], sigma[j])) gaussGradientMagnitude.append( ndi.gaussian_gradient_magnitude(imDsets[i], sigma[j])) structTensor.append(feat.structure_tensor(imDsets[i], sigma[j])) hessianMat = feat.hessian_matrix(imDsets[i], sigma[j])
def hessian_and_theta(data, margin_cut=1): # compute hessian matrices on the image Hxx, Hxy, Hyy = hessian_matrix(data, sigma=3, order='xy') lambda_plus = 0.5 * ((Hxx + Hyy) + np.sqrt((Hxx - Hyy)**2 + 4 * Hxy * Hxy)) lambda_minus = 0.5 * ( (Hxx + Hyy) - np.sqrt((Hxx - Hyy)**2 + 4 * Hxy * Hxy)) theta = 0.5 * np.arctan2(2 * Hxy, Hyy - Hxx) * 180 / np.pi # remove the margins lambda_minus = lambda_minus[margin_cut:-margin_cut, margin_cut:-margin_cut] lambda_plus = lambda_plus[margin_cut:-margin_cut, margin_cut:-margin_cut] theta = theta[margin_cut:-margin_cut, margin_cut:-margin_cut] return lambda_plus, lambda_minus, theta
def ridge_filter_3D(im, sigma=3): #crop = gaussian(crop, sigma=1) H_elems = hessian_matrix(im, sigma=sigma) #i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy) eigs = hessian_matrix_eigvals(H_elems) LambdaAbs1=abs(eigs[0]); LambdaAbs2=abs(eigs[1]); LambdaAbs3=abs(eigs[2]); return LambdaAbs1, LambdaAbs2, LambdaAbs3
def hessian_response(im, sigma=3, threshold=0.05): # # derivative in x direction of the image # imx = np.zeros(im.shape) # imxx = np.zeros(im.shape) # filters.gaussian_filter(im, (sigma, sigma), (0, 1), imx) # filters.gaussian_filter(imx, (sigma, sigma), (0, 1), imxx) # # # derivative in y direction of the image # imy = np.zeros(im.shape) # imyy = np.zeros(im.shape) # filters.gaussian_filter(im, (sigma, sigma), (1, 0), imy) # filters.gaussian_filter(imy, (sigma, sigma), (1, 0), imyy) # # imxy = np.zeros(im.shape) # filters.gaussian_filter(imx, (sigma, sigma), (1, 0), imxy) # # Wxx = filters.gaussian_filter(imxx, sigma) # Wxy = filters.gaussian_filter(imxy, sigma) # Wyy = filters.gaussian_filter(imyy, sigma) # # H = np.array([[Wxx, Wxy], # [Wxy, Wyy]]) # from numpy import linalg as LA from skimage.feature import hessian_matrix, hessian_matrix_eigvals Hxx, Hxy, Hyy = hessian_matrix(im, sigma=0.1) e_big, e_small = hessian_matrix_eigvals(Hxx, Hxy, Hyy) #eiglast = 0.5 * (Wxx + Wyy + np.sqrt(Wxx**2 + 4*Wxy**2 - 2*Wxx*Wyy + Wyy**2 )) # det_hes = Wxx * Wyy - Wxy ** 2 eiglast = e_big # get maxima of the determinant # det_thresh = eiglast.max() * threshold # det_bin = (eiglast >= det_thresh) * 1 # # coordinates = np.array(det_bin.nonzero()).T x = [p[0] for p in coordinates] y = [p[1] for p in coordinates] edges = np.zeros(im.shape) edges[x, y] = 1 pl.imshow(edges) pl.gray() pl.show() return
def hessian(img): scales = [] s = 2 k = math.pow(2,0.25) for i in range(12): image = hessian_matrix_det(img, sigma=1.2*i) # image = hessian_matrix_det(img, sigma=math.pow(k,i)*s) Hrr, Hrc, Hcc = hessian_matrix(integral_image(img), sigma=math.pow(k,i)*s, order='rc') det = Hrr*Hcc - np.power((0.9*Hrc),2) scales.append(image) keypts = keypt(scales) return keypts
def test_hessian_matrix_eigvals(): square = np.zeros((5, 5)) square[2, 2] = 4 H = hessian_matrix(square, sigma=0.1, order='rc') l1, l2 = hessian_matrix_eigvals(H) assert_almost_equal( l1, np.array([[0, 0, 2, 0, 0], [0, 1, 0, 1, 0], [2, 0, -2, 0, 2], [0, 1, 0, 1, 0], [0, 0, 2, 0, 0]])) assert_almost_equal( l2, np.array([[0, 0, 0, 0, 0], [0, -1, 0, -1, 0], [0, 0, -2, 0, 0], [0, -1, 0, -1, 0], [0, 0, 0, 0, 0]]))
def test_hessian_matrix(): square = np.zeros((5, 5)) square[2, 2] = 1 Hxx, Hxy, Hyy = hessian_matrix(square, sigma=0.1) assert_array_equal( Hxx, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) ) assert_array_equal( Hxy, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) ) assert_array_equal( Hyy, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) )
def test_hessian_matrix_eigvals(): square = np.zeros((5, 5)) square[2, 2] = 1 Hxx, Hxy, Hyy = hessian_matrix(square, sigma=0.1) l1, l2 = hessian_matrix_eigvals(Hxx, Hxy, Hyy) assert_array_equal( l1, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])) assert_array_equal( l2, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]))
def pre_process_image(self): ## self.image = cv.split(self.image) ## self.image = self.image[1] self.image = filters.median(self.image, disk(self.median_value)) self.image = filters.gaussian(self.image, sigma=self.gaussian_sigma) ## self.image = morphology.erosion(self.image, disk(4)) ## self.image = morphology.dilation(self.image, disk(2)) min = self.image.min() max = self.image.max() self.image = (self.image - min) / (max - min) * 255 self.image = self.image.astype(np.uint8) self.image = self.image.astype(np.uint8) hxx, hyy, hxy = hessian_matrix(self.image, 4.0, order="xy") i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy) i1 = self.normalize(i1) i2 = self.normalize(i2) i3 = i1 + self.invert_image(i2) i3 = self.normalize(i3) i3 = self.to_binary_image(i3, 0.3) self.expert_image = self.normalize(self.expert_image) self.expert_image = self.to_binary_image(self.expert_image, 0.5) result_matrix = self.compare_images(i3, self.expert_image) accuracy = self.get_accuracy(result_matrix) sensitivity = self.get_sensitivity(result_matrix) specificity = self.get_specificity(result_matrix) # i1 = self.to_binary_image(i1, 0.5) # i2 = self.to_binary_image(i2, 0.5) # i3 = self.to_binary_image(i3, 0.3) cv.imshow("i1", i1) cv.waitKey(0) cv.imshow("i2", i2) cv.waitKey(0) # i3 = morphology.dilation(i3, disk(self.dilation_value)) # i3 = morphology.erosion(i3, disk(self.erosion_value)) cv.imshow("i3", i3) cv.waitKey(0) cv.imshow("expert", self.expert_image) cv.waitKey(0)
def hessian_eigvals_abs_sorted(volume): N = volume.ndim H = hessian_matrix(volume) L = hessian_matrix_eigvals(H) sorting = np.argsort(np.abs(L), axis=0) res = [] for i in range(N): newL = np.zeros_like(L[0]) for j in range(N): newL[sorting[i, :] == j] = L[j, sorting[i, :] == j] res.append(newL) return res
def ridge_filter_hessian(img, sigma=3): from skimage.feature import hessian_matrix, hessian_matrix_eigvals from skimage.filters import threshold_otsu from skimage.morphology import skeletonize #assume you have an image img hxx, hxy, hyy = hessian_matrix(img, sigma=sigma) i1, i2 = hessian_matrix_eigvals(hxx, hxy, hyy) i2 = i2 <= threshold_otsu(i2) i2 = skeletonize(i2) return i2
def test_hessian_matrix_eigvals(dtype): square = np.zeros((5, 5), dtype=dtype) square[2, 2] = 4 H = hessian_matrix(square, sigma=0.1, order='rc') l1, l2 = hessian_matrix_eigvals(H) out_dtype = _supported_float_type(dtype) assert all(a.dtype == out_dtype for a in (l1, l2)) assert_almost_equal( l1, np.array([[0, 0, 2, 0, 0], [0, 1, 0, 1, 0], [2, 0, -2, 0, 2], [0, 1, 0, 1, 0], [0, 0, 2, 0, 0]])) assert_almost_equal( l2, np.array([[0, 0, 0, 0, 0], [0, -1, 0, -1, 0], [0, 0, -2, 0, 0], [0, -1, 0, -1, 0], [0, 0, 0, 0, 0]]))
def read_image(self, image_name, size=None): options = self.get_options() if size: im = np.array(Image.open(image_name).convert("L").resize(size)) else: im = np.array(Image.open(image_name).convert("L")) options["image"] = im H_elems = hessian_matrix(**options) feature = hessian_matrix_eigvals(H_elems)[0] # plt.imshow(feature) # plt.show() return feature.reshape((1, feature.shape[0] * feature.shape[1]))[0]
def test_hessian_matrix_eigvals(): square = np.zeros((5, 5)) square[2, 2] = 4 Hrr, Hrc, Hcc = hessian_matrix(square, sigma=0.1, order='rc') l1, l2 = hessian_matrix_eigvals(Hrr, Hrc, Hcc) assert_almost_equal(l1, np.array([[0, 0, 2, 0, 0], [0, 1, 0, 1, 0], [2, 0, -2, 0, 2], [0, 1, 0, 1, 0], [0, 0, 2, 0, 0]])) assert_almost_equal(l2, np.array([[0, 0, 0, 0, 0], [0, -1, 0, -1, 0], [0, 0, -2, 0, 0], [0, -1, 0, -1, 0], [0, 0, 0, 0, 0]]))
def _get_hessian_matrix_features(im, features_window_size, sigma_hm): features_arr = np.empty(0) center = im_center(im) Hxx, Hxy, Hyy = feature.hessian_matrix(im, sigma=sigma_hm) h1, h2 = feature.hessian_matrix_eigvals(Hxx, Hxy, Hyy) h1 = utils.extract_pad_image(input_img=h1, pt=center, window_size=features_window_size) h2 = utils.extract_pad_image(input_img=h2, pt=center, window_size=features_window_size) h1 = arr_to_vec(h1) h2 = arr_to_vec(h2) features_arr = np.append(features_arr, h1) features_arr = np.append(features_arr, h2) return features_arr
def principal_directions(img, sigma, H=None): """2D only, handles masked arrays""" if H is None: Hxx, Hxy, Hyy = hessian_matrix(img, sigma) try: mask = img.mask except AttributeError: masked = False else: masked = True dims = img.shape # where to store trailing_thetas = np.zeros_like(img) leading_thetas = np.zeros_like(img) # maybe implement a small angle correction for i, (xx, xy, yy) in enumerate(np.nditer([Hxx, Hxy, Hyy])): subs = np.unravel_index(i, dims) # ignore masked areas (if masked array) if masked and img.mask[subs]: continue h = np.array([[xx, xy], [xy, yy]]) # per-pixel hessian l, v = eig(h) # eigenvectors as columns # reorder eigenvectors by (increasing) magnitude of eigenvalues v = v[:,np.argsort(np.abs(l))] # angle between each eigenvector and positive x-axis # arccos of first element (dot product with (1,0) and eigvec is already # normalized) trailing_thetas[subs] = np.arccos(v[0,0]) # first component of each leading_thetas[subs] = np.arccos(v[0,1]) # first component of each if masked: leading_thetas = ma.masked_array(leading_thetas, img.mask) trailing_thetas = ma.masked_array(trailing_thetas, img.mask) return trailing_thetas, leading_thetas
def __init__(self, img=None, path=None, block_size=5): if path and not img: img = cv2.imread(path) #img = Preprocess().blur_image(img) self.block_size = block_size self.img_rgb = img.copy() self.img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) #self.img_ycbcr = cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb) self.img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) self.height, self.width, _ = img.shape self.Hxx, self.Hxy, self.Hyy = hessian_matrix(self.img_gray) #vector, self.hog = hog(self.img_gray, orientations=8, pixels_per_cell=(3, 3), # cells_per_block=(1, 1), visualise=True) neighours = disk(25) self.entropy = entropy(self.img_gray, neighours)
def test_hessian_matrix_eigvals_3d(im3d): H = hessian_matrix(im3d) E = hessian_matrix_eigvals(H) # test descending order: e0, e1, e2 = E assert np.all(e0 >= e1) and np.all(e1 >= e2) E0, E1, E2 = E[:, E.shape[1] // 2] # cross section row_center, col_center = np.array(E0.shape) // 2 circles = [draw.circle_perimeter(row_center, col_center, radius, shape=E0.shape) for radius in range(1, E0.shape[1] // 2 - 1)] response0 = np.array([np.mean(E0[c]) for c in circles]) response2 = np.array([np.mean(E2[c]) for c in circles]) # eigenvalues are negative just inside the sphere, positive just outside assert np.argmin(response2) < np.argmax(response0) assert np.min(response2) < 0 assert np.max(response0) > 0
def find_blobs_hessian(img): size = 20 img0 = np.zeros((img.shape[0]+ 2*size, img.shape[1]+ 2*size)) img0[size:size+img.shape[0], size:size+img.shape[1]] = img blobs = blob_doh(img0, max_sigma=10, num_sigma=10) true_blobs = [] for y0, x0, b0 in blobs: p0 = util.neighbour(img0, y0, x0, 1) y, x = np.unravel_index(p0.argmax(), p0.shape) y0 += y - 1 x0 += x - 1 p0 = util.neighbour(img0, y0, x0, 2*b0) if True: # method 1 (hessian diagonal) hs0, hs1, hs2 = hessian_matrix(p0, 0.5*b0) q0 = 0.5 *(hs0 + hs2) if b0 >= 2 \ and b0 <= 8 \ and q0[2*b0,2*b0] > 0.95*util.neighbour(q0,2*b0,2*b0,b0).max(): true_blobs.append([y0,x0,b0]) else: # method 2 (hessian determinant) q0 = hessian_matrix_det(p0, b0) print b0, q0[2*b0, 2*b0], util.neighbour(q0, 2*b0,2*b0,b0).max() if b0 >= 2 \ and b0 <= 8 \ and q0[2*b0,2*b0] > 0.8*util.neighbour(q0,2*b0,2*b0,b0).max(): true_blobs.append([y0, x0, b0]) if len(true_blobs) > 0: true_blobs = np.array(true_blobs) - [size, size, 0] if len(blobs) > 0: blobs = blobs - [size, size, 0] return true_blobs, blobs
def test_hessian_matrix(): square = np.zeros((5, 5)) square[2, 2] = 4 Hrr, Hrc, Hcc = hessian_matrix(square, sigma=0.1, order='rc') assert_almost_equal(Hrr, np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [2, 0, -2, 0, 2], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])) assert_almost_equal(Hrc, np.array([[0, 0, 0, 0, 0], [0, 1, 0, -1, 0], [0, 0, 0, 0, 0], [0, -1, 0, 1, 0], [0, 0, 0, 0, 0]])) assert_almost_equal(Hcc, np.array([[0, 0, 2, 0, 0], [0, 0, 0, 0, 0], [0, 0, -2, 0, 0], [0, 0, 0, 0, 0], [0, 0, 2, 0, 0]])) matrix2d = np.random.rand(3, 3) assert_warns(UserWarning, hessian_matrix, matrix2d, sigma=0.1)
#cv2.imshow('dst',img) plt.figure(1); plt.clf(); plt.subplot(1,2,1) plt.imshow(img); plt.subplot(1,2,2) plt.imshow(dst) #if cv2.waitKey(0) & 0xff == 27: # cv2.destroyAllWindows() hess= ftr.hessian_matrix(img) plt.figure(100); plt.clf(); for i in range(len(hess)): plt.subplot(1,len(hess), i +1); plt.imshow(hess[i]); import imageprocessing.active_worm as aw; img = exp.load_img(t = 500000) img = cv2.GaussianBlur(img, (5,5), 1); wm = aw.WormModel(); wm.from_image(img);
from skimage import io from skimage.feature import hessian_matrix, hessian_matrix_eigvals, hessian_matrix_det from skimage.filters import gaussian_filter from skimage.morphology import watershed, closing, opening from scipy.stats import logistic filename = "skeletons & matching cropped pics/cropped pics/v018-penn.9-1uB2D2-cropm.png" img = io.imread(filename) img = (img - np.mean(img)) / np.std(img) sigma = .75 Hxx, Hxy, Hyy = hessian_matrix(img, sigma=sigma, mode="wrap") e1, e2 = hessian_matrix_eigvals(Hxx, Hxy, Hyy) # How much bigger is the first eigenvalue's magnitude # compared with the second? log_condition = np.log(abs(e1/e2)) log_condition = log_condition / np.std(log_condition) out = logistic.cdf(log_condition) markers = np.zeros_like(out) markers[out < 0] = 1 markers[out > np.percentile(out, 90)] = 2
b = partial(plt.imshow, cmap=plt.cm.Blues) sp = partial(plt.imshow, cmap=plt.cm.spectral) s = plt.show import time img = get_preprocessed(mode='G') for sigma in [0.5, 1, 2, 3, 5, 10]: print('-'*80) print('σ=',sigma) print('calculating hessian H') tic = time.time() H = hessian_matrix(img, sigma=sigma) toc = time.time() print('time elapsed: ', toc - tic) tic = time.time() print('calculating hessian via FFT (F)') h = fft_hessian(img, sigma) toc = time.time() print('time elapsed: ', toc - tic) tic = time.time() print('calculating principal curvatures for σ={}'.format(sigma)) K1,K2 = principal_curvatures(img, sigma=sigma, H=H) toc = time.time() print('time elapsed: ', toc - tic) tic = time.time()
def principal_curvatures(img, sigma=1.0, H=None): """ Return the principal curvatures {κ1, κ2} of an image, that is, the eigenvalues of the Hessian at each point (x,y). The output is arranged such that |κ1| <= |κ2|. Input: img: An ndarray representing a 2D or multichannel image. If the image is multichannel (e.g. RGB), then each channel will be proccessed individually. Additionally, the input image may be a masked array-- in which case the output will preserve this mask identically. PLEASE ADD SOME INFO HERE ABOUT WHAT SORT OF DTYPES ARE EXPECTED/REQUIRED, IF ANY sigma: (optional) The scale at which the Hessian is calculated. H: (optional) provide sigma (else it will be calculated) Output: (K1, K2): A tuple where K1, K2 each are the exact dimension of the input image, ordered in magnitude such that |κ1| <= |κ2| in all locations. If *signed* option is used, then elements of K1, K2 may be negative. Example: >>> K1, K2 = principal_curvatures(img) >>> K1.shape == img.shape True >>> (K1 <= K2).all() True >> K1.mask == img.mask True """ # determine if multichannel multichannel = (img.ndim == 3) if not multichannel: # add a trivial dimension img = img[:,:,np.newaxis] K1 = np.zeros_like(img, dtype='float64') K2 = np.zeros_like(img, dtype='float64') for ic in range(img.shape[2]): channel = img[:,:,ic] # returns the tuple (Hxx, Hxy, Hyy) if H is None: H = hessian_matrix(channel, sigma=sigma) # returns tuple (l1,l2) where l1 >= l2 but this *includes sign* L = hessian_matrix_eigvals(*H) L = np.dstack(L) mag = np.argsort(abs(L), axis=-1) # just some slice nonsense ix = np.ogrid[0:L.shape[0], 0:L.shape[1], 0:L.shape[2]] L = L[ix[0], ix[1], mag] # now k2 is larger in absolute value, as consistent with Frangi paper K1[:,:,ic] = L[:,:,0] K2[:,:,ic] = L[:,:,1] try: mask = img.mask except AttributeError: pass else: K1 = ma.masked_array(K1, mask=mask) K2 = ma.masked_array(K2, mask=mask) # now undo the trivial dimension if not multichannel: K1 = np.squeeze(K1) K2 = np.squeeze(K2) return K1, K2