def __call__(self, frame): return HoughCircles(frame, HOUGH_GRADIENT, self.dp, self.minDist, param1=self.param1, param2=self.param2, minRadius=self.minRadius, maxRadius=self.maxRadius)
def show_circle(path): img = cv2.imread(path) output = img.copy() # 定义想要缩放后的图片大小 info = img.shape # 获取图片的宽 高 颜色通道信息 dst_width = int(info[1] * 0.2) dst_height = int(info[0] * 0.2) image = cv2.resize(img, (dst_width, dst_height), 0, 0) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # cv2.imshow("gray", gray) circles = HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 100) print(len(circles))
def findCentroid(self, image, minRadius, maxRadius, rowsMin, rowsMax, columnsMin, columnsMax): ''' Take a numpy array of an image and centroid the circles within ''' #Copy image output = copy(image[rowsMin:rowsMax, columnsMin:columnsMax]) print('Image dimensions: ', output.shape) #Find the circles (convert image from uint16 (FITS 16bit) to 8bit) circles = HoughCircles((output / 256).astype('uint8'), HOUGH_GRADIENT, 4, 100, 100, 100, minRadius, maxRadius) #WORKS 11/8/2017 #Ensure at least some circles were found if circles is not None: print('Found circles') #Convert the (x, y) coordinates and radius of the circles to integers circles = round(circles[0, :]).astype("float") #Find the circle closest to the center of the image #calculate the Euclidean distances between two 1-D arrays (circle centers and image center) eDist = [] [ eDist.append([ distance.euclidean( (output.shape[0] / 2, output.shape[1] / 2), (circles[ii][0], circles[ii][1])), ii ]) for ii in range(circles.shape[0]) ] minDist = min(eDist[:]) #min Euclidean distance correctCircle = circles[ minDist[1]][:] #circle corresponding to min Euclidean distance #Convert image to RGB #output.resize((output.shape[0], output.shape[1], 1)) #outputColor = repeat(output.astype(uint16), 3, 2) outputColor = cvtColor(output, COLOR_GRAY2RGB) #Draw the circle in the output image, then draw a rectangle corresponding to the center of the circle circle(outputColor, (int(correctCircle[0]), int(correctCircle[1])), int(correctCircle[2]), (9999, 9999, 9999), 4) rectangle(outputColor, (int(correctCircle[0]) - 3, int(correctCircle[1]) - 3), (int(correctCircle[0]) + 3, int(correctCircle[1]) + 3), (9999, 9999, 9999), -1) print("Centroid location: " + '(' + str(correctCircle[0] + rowsMin) + ',' + str(correctCircle[1] + columnsMin) + ') r=' + str(correctCircle[2])) #Save Image toimage(outputColor, cmin=0.0).save('outfile.png') #cmin=0.0 else: print('No circles found')
def preprocessAndTarget(): min_dist = 0 min_radius = 0 min_x, min_y = 0, 0 # Grab and preprocess screen image = sct.grab(entire) image = nparray(image) gray = cvtColor(image, COLOR_BGR2GRAY) gray = medianBlur(gray, 5) circles = HoughCircles(gray, HOUGH_GRADIENT, 1, 50, param1=100, param2=20, minRadius=20, maxRadius=100) if circles is not None: circles = np.round(circles[0, :]).astype("int") for (x, y, r) in circles: circle(image, (x, y), r, (0, 255, 0), 4) dist = floor(hypot(center_x_entire - x, center_y_entire - y)) if (min_dist == 0): min_dist = dist min_radius = floor(r) min_x, min_y = x, y elif (dist < min_dist): min_dist = dist min_radius = floor(r) min_x, min_y = x, y x_travel = center_x_entire - min_x y_travel = center_y_entire - min_y return x_travel, y_travel, min_dist, min_radius
def find_circle(segment): blured = GaussianBlur(segment.copy(), (3, 3), 1.5, sigmaY=1.5) min_distance = min(segment.shape) // 2 return HoughCircles(blured, HOUGH_GRADIENT, 1, min_distance, param1=80, param2=30, minRadius=0, maxRadius=0)
def find_possible_marks(frame_thresh, MinPixelWidth, MaxPixelWidth, MinPixelHeight, MaxPixelHeight, MinAspectRatio, MaxAspectRatio, MinPixelArea, MaxPixelArea, MinExtent, MaxExtent, MaxDrift, perspectiveMode, FindContoursMode, HoughParams, debugMode=False): """ Find all possible bracelet marks (finds all contours that could be representing marks) """ # Initialization: possible_marks_list = [] frame_thresh_copy = frame_thresh.copy() # Find all contours in the image: contours = [] if FindContoursMode == "Legacy": contours, _ = findContours(frame_thresh_copy, RETR_LIST, CHAIN_APPROX_SIMPLE) elif FindContoursMode == "Hough": circles = HoughCircles( image=frame_thresh_copy, # 8-bit, single channel image method= HOUGH_GRADIENT, # Defines the method to detect circles in images dp=HoughParams[0] if HoughParams[0] > 0 else 1, # Large dp values --> smaller accumulator array minDist=HoughParams[1] if HoughParams[1] > 0 else 60, # Min distance between the detected circles centers param1=HoughParams[2] if HoughParams[2] > 0 else 50, # Gradient value used to handle edge detection param2=HoughParams[3] if HoughParams[3] > 0 else 18, # Accumulator thresh val (smaller = more circles) minRadius=HoughParams[4] if HoughParams[4] > 0 else 20, # Minimum size of the radius (in pixels) maxRadius=HoughParams[5] if HoughParams[5] > 0 else 50 # Maximum size of the radius (in pixels) ) if circles is not None: for i in circles[0, :]: contours.append(circle_to_contour(i, 50, 0.7)) else: error("Unsupported FindContoursMode mode: %s" % FindContoursMode) # Create contours image: height, width = frame_thresh_copy.shape frame_contours = zeros((height, width, 3), uint8) drawContours(frame_contours, contours, -1, Colors.white) # Foreach contour, check if it describes a possible character: possible_marks_cntr = 0 for i in range(0, len(contours)): # Register the contour as a possible character (+calculate intrinsic metrics): possible_mark = PossibleMark(contours[i], MinPixelWidth, MaxPixelWidth, MinPixelHeight, MaxPixelHeight, MinAspectRatio, MaxAspectRatio, MinPixelArea, MaxPixelArea, MinExtent, MaxExtent) # If contour is a possible char, increment count of possible chars and add to list of possible chars: if possible_mark.check_if_possible_mark(): possible_marks_cntr += 1 possible_marks_list.append(possible_mark) if debugMode: print(possible_mark, possible_marks_cntr) if len(possible_marks_list) == 0: return possible_marks_list, 0 # Remove outliers in a PCA scheme, i.e. possible marks which are too faraway from the group or interiors: possible_marks_wo_outliers = remove_outliers(possible_marks_list, MaxDrift, debugMode) # Rotation and Perspective alignments: rotation_angle_deg = 0 if len(possible_marks_wo_outliers) > 0: # Rotation Alignment (SVD decomposition): rotation_angle_deg, centroid = rotation_alignment( possible_marks_wo_outliers, debugMode) # Perspective Alignment (Homography+PerspectiveWarp): possible_marks_final = deepcopy(possible_marks_wo_outliers) rect_src, rect_dst = perspective_alignment(possible_marks_final, perspectiveMode, rotation_angle_deg, debugMode) # -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. -- .. if debugMode: frame_possible_marks = zeros((height, width, 3), uint8) for possible_mark in possible_marks_wo_outliers: drawContours(frame_possible_marks, [possible_mark.contour], 0, Colors.white) frame_possible_marks[possible_mark.intCenterY - 3:possible_mark.intCenterY + 3, possible_mark.intCenterX - 3:possible_mark.intCenterX + 3, 2] = 255 frame_possible_marks[possible_mark.intCenterY_r - 3:possible_mark.intCenterY_r + 3, possible_mark.intCenterX_r - 3:possible_mark.intCenterX_r + 3, 0] = 255 for possible_mark in possible_marks_final: frame_possible_marks[possible_mark.intCenterY_r - 3:possible_mark.intCenterY_r + 3, possible_mark.intCenterX_r - 3:possible_mark.intCenterX_r + 3, 1:3] = 255 putText(frame_possible_marks, "Original", (10, 30), FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) putText(frame_possible_marks, "Rotation fix (SVD)", (10, 70), FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) putText(frame_possible_marks, "Centroid", (10, 110), FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) putText(frame_possible_marks, "Perspective fix", (10, 150), FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2) if perspectiveMode == 1: frame_possible_marks = polylines(frame_possible_marks, array([rect_src]), True, (255, 0, 0), 1, LINE_AA) frame_possible_marks = polylines(frame_possible_marks, array([rect_dst]), True, (0, 255, 255), 1, LINE_AA) if len(frame_possible_marks) > 0: X_xc, X_yc = centroid frame_possible_marks[X_yc - 3:X_yc + 3, X_xc - 3:X_xc + 3, 1] = 255 debug("Amount of detected contours: %d" % len(contours), True) debug("Amount of possible marks: %d" % possible_marks_cntr, True) debug( "Amount of possible marks w/o outliers: %d" % len(possible_marks_wo_outliers), True) debug("Rotation: %.2f" % rotation_angle_deg, True) imwrite("img_contours_all.jpg", frame_contours) imwrite("img_possible_marks_.jpg", frame_possible_marks) return possible_marks_final, rotation_angle_deg
def main_loop(pps_list, mirror, params_dict): virago_dir = '{}/v3-analysis'.format(os.getcwd()) vcount_dir = '{}/vcounts'.format(virago_dir) img_dir = '{}/processed_images'.format(virago_dir) histo_dir = '{}/histograms'.format(virago_dir) overlay_dir = '{}/overlays'.format(virago_dir) filo_dir = '{}/filo'.format(virago_dir) fluor_dir = '{}/fluor'.format(virago_dir) if not os.path.exists(virago_dir): os.makedirs(virago_dir) if not os.path.exists(img_dir): os.makedirs(img_dir) if not os.path.exists(histo_dir): os.makedirs(histo_dir) if not os.path.exists(fluor_dir): os.makedirs(fluor_dir) if not os.path.exists(filo_dir): os.makedirs(filo_dir) if not os.path.exists(overlay_dir): os.makedirs(overlay_dir) if not os.path.exists(vcount_dir): os.makedirs(vcount_dir) cam_micron_per_pix = params_dict['cam_micron_per_pix'] mag = params_dict['mag'] pix_per_um = mag / cam_micron_per_pix spacing = 1 / pix_per_um conv_factor = (cam_micron_per_pix / mag)**2 exo_toggle = params_dict['exo_toggle'] cv_cutoff = params_dict['cv_cutoff'] perc_range = params_dict['perc_range'] # IRISmarker = imread('/usr3/bustaff/ajdevaux/virago/images/IRISmarker_new.tif') IRISmarker = params_dict['IRISmarker'] # IRISmarker_exo = skio.imread('images/IRISmarker_v4_topstack.tif') # pps_list, mirror = vpipes.mirror_finder(pps_list) passes_per_spot = len(pps_list) spot_ID = pps_list[0][:-8] scans_counted = [int(file.split(".")[2]) for file in pps_list] first_scan = min(scans_counted) circle_dict, marker_dict, overlay_dict, shift_dict = {}, {}, {}, {} vdata_dict = vpipes.get_vdata_dict(exo_toggle, version="3.x") # missing_data = set(range(1,pass_counter+1)).difference(scans_counted) # # if missing_data != set(): # print("Missing image files... fixing...\n") # for scan in missing_data: # bad_scan = '{0}.{1}'.format(*(spot_ID, str(scan).zfill(3))) # vdata_dict.update({'img_name':bad_scan}) # # with open('{}/{}.vdata.txt'.format(vcount_dir,bad_scan),'w') as f: # for k,v in vdata_dict.items(): # f.write('{}: {}\n'.format(k,v)) # print("Writing blank data files for {}".format(bad_scan)) total_shape_df = pd.DataFrame() for scan in range( 0, passes_per_spot): ##Main Loop for image processing begins here. img_stack = tuple(file for file in pps_list if file.startswith(pps_list[scan])) fluor_files = [ file for file in img_stack if file.split(".")[-2] in 'ABC' ] if fluor_files: img_stack = tuple(file for file in img_stack if file not in fluor_files) print( "\nFluorescent channel(s) detected: {}\n".format(fluor_files)) topstack_img = img_stack[0] name_split = topstack_img.split('.') img_name = '.'.join(name_split[:-1]) spot_num, pass_num = map(int, name_split[1:3]) if name_split[-1] == 'tif': tiff_toggle = True else: tiff_toggle = False pic3D = vpipes.load_image(img_stack, tiff_toggle) print("{} Loaded\n".format(img_name)) validity = True # if convert_tiff == True: # vpipes.pgm_to_tiff(pic3D, img_name, img_stack, # tiff_compression=1, archive_pgm=True) # zslice_count, nrows, ncols = pic3D.shape total_pixels = nrows * ncols if mirror.size == total_pixels: pic3D = pic3D / mirror print("Applying mirror to image stack...\n") pic3D_norm = np.uint8(normalize(pic3D, None, 0, 255, NORM_MINMAX)) pic3D_clahe = vimage.cv2_clahe_3D(pic3D_norm, kernel_size=(1, 1), cliplim=4) pic3D_rescale = vimage.rescale_3D(pic3D_clahe, perc_range=perc_range) print("Contrast adjusted\n") #Many operations are on the Z-stack compressed image. #Several methods to choose, but Standard Deviation works well. # maxmin_proj_rescale = np.max(pic3D_rescale, axis = 0) - np.min(pic3D_rescale, axis = 0) sd_proj_rescale = np.std(pic3D_rescale, axis=0) #Convert to 8-bit for OpenCV comptibility sd_proj_rescale = np.uint8( normalize(sd_proj_rescale, None, 0, 255, NORM_MINMAX)) if pass_num == 1: marker = IRISmarker else: marker = found_markers if img_name not in marker_dict: marker_locs = vimage.marker_finder(pic3D_rescale[0], marker=marker, thresh=0.6) marker_dict[img_name] = marker_locs else: marker_locs = marker_dict[img_name] pos_plane_list = vquant.measure_focal_plane( pic3D_norm, marker_locs, exo_toggle, marker_shape=IRISmarker.shape) if pos_plane_list != []: pos_plane = max(pos_plane_list) else: pos_plane = zslice_count // 3 pic_rescale_pos = pic3D_rescale[pos_plane] overlay_dict['.'.join(img_name.split('.')[1:])] = sd_proj_rescale print("Using image {} from stack\n".format( str(pos_plane + 1).zfill(3))) # if pass_counter <= 15: # overlay_mode = 'series' # else: overlay_mode = 'baseline' if pass_num == first_scan: print("First Valid Scan\n") valid_shift = (0, 0) overlay_toggle = False else: prescan_img, postscan_img = vimage._dict_matcher(overlay_dict, spot_num, pass_num, mode=overlay_mode) overlay_toggle = True # if img_name in shift_dict: # valid_shift = shift_dict[img_name] # else: ORB_shift = vimage.measure_shift_ORB(prescan_img, postscan_img, ham_thresh=10, show=False) # for coord in ORB_shift: # if abs(coord) < 75: # valid_shift = ORB_shift # else: ##In case ORB fails to give a good value # # overlay_toggle = False # print("Using alternative shift measurement...\n") # mean_shift, overlay_toggle = vimage.measure_shift(marker_dict,pass_num, # spot_num,mode=overlay_mode # ) # valid_shift = mean_shift print("Valid Shift: {}\n".format(valid_shift)) img_overlay = vimage.overlayer(prescan_img, postscan_img, valid_shift) shape_mask = vimage.shape_mask_shift(shape_mask, valid_shift) img_overlay_difference = np.int16(img_overlay[:, :, 1]) - np.int16( img_overlay[:, :, 0]) median_overlay = np.median(img_overlay_difference) sd_overlay = np.std(img_overlay_difference) print(median_overlay, sd_overlay) # overlay_name = "{}_overlay_{}".format(img_name, overlay_mode) # vimage.gen_img_deets(img_overlay_difference, name=overlay_name, savedir=overlay_dir) if (overlay_toggle == False) & (pass_num != first_scan): validity = False print("No compatible markers, cannot compute shift") # # else: # print("Cannot overlay images\n") if spot_num in circle_dict: #Get the location of the Antibody spot spot_coords = circle_dict[spot_num] shift_x = spot_coords[0] + valid_shift[1] shift_y = spot_coords[1] + valid_shift[0] spot_coords = (shift_x, shift_y, spot_coords[2]) else: #Find the Antibody spot if it has not already been determined circles = None cannyMax = 200 cannyMin = 100 while type(circles) == type(None): circles = HoughCircles(sd_proj_rescale, HOUGH_GRADIENT, 1, minDist=500, param1=cannyMax, param2=cannyMin, minRadius=300, maxRadius=600) cannyMax -= 50 cannyMin -= 25 spot_coords = tuple(map(lambda x: round(x, 0), circles[0][0])) print("Spot center coordinates (row, column, radius): {}\n".format( spot_coords)) circle_dict[spot_num] = spot_coords row, col = np.ogrid[:nrows, :ncols] width = col - spot_coords[0] height = row - spot_coords[1] rad = spot_coords[2] - 25 disk_mask = (width**2 + height**2 > rad**2) marker_mask, found_markers = vimage.marker_masker( pic3D_rescale[0], marker_locs, marker) full_mask = disk_mask + marker_mask # vimage.image_details(pic3D_norm[pos_plane], pic3D_clahe[pos_plane], pic3D_rescale[pos_plane].copy(), pic_canny) # maxmin_proj_rescale_masked = np.ma.array(maxmin_proj_rescale, mask=full_mask).filled(fill_value=np.nan) # maxmin_median = np.nanmedian(maxmin_proj_rescale_masked) #*********************************************************************************************# # if pass_num > first_scan: # if overlay_toggle == True: # img_overlay = np.ma.array(img_overlay, mask=full_mask).filled(fill_value=np.nan) # if Ab_spot_mode == False: # pic_to_show = sd_proj_rescale # elif exo_toggle == True: # pic_to_show = sd_proj_rescale # else: if pass_num == 1: pic_to_show = sd_proj_rescale else: pic_to_show = img_overlay_difference #*********************************************************************************************# with warnings.catch_warnings(): ##RuntimeWarning ignored: invalid values are expected warnings.simplefilter("ignore") warnings.warn(RuntimeWarning) shapedex = shape_index(pic_rescale_pos) shapedex = np.ma.array(shapedex, mask=full_mask).filled(fill_value=np.nan) if pass_num > first_scan: shapedex = np.ma.array(shapedex, mask=shape_mask).filled(fill_value=-1) shapedex_gauss = gaussian_filter(shapedex, sigma=1) pix_area = np.count_nonzero(np.invert(np.isnan(shapedex))) area_sqmm = round((pix_area * conv_factor) * 1e-6, 6) ##Pixel topology classifications background = 0 ridge = 0.5 sphere = 1 bg_rows, bg_cols = zip(*vquant.classify_shape( shapedex, sd_proj_rescale, background, delta=0.25, intensity=0)) sd_proj_bg = sd_proj_rescale[bg_rows, bg_cols] sd_proj_bg_median = np.median(sd_proj_bg) ##Important sd_proj_bg_stdev = np.std(sd_proj_bg) print("Median intensity of spot background={}, SD={}".format( round(sd_proj_bg_median, 4), round(sd_proj_bg_stdev, 4))) # if Ab_spot_mode == True: # if exo_toggle == True: ridge_thresh = sd_proj_bg_median * 3.5 sphere_thresh = sd_proj_bg_median * 2.5 ridge_thresh_s = sd_proj_bg_median * 3.5 # else: # ridge_thresh = sd_proj_bg_median+sd_proj_bg_stdev*2 # sphere_thresh = sd_proj_bg_median+sd_proj_bg_stdev*2 # ridge_thresh_s = sd_proj_bg_median+sd_proj_bg_stdev*3 # else: # ridge_thresh = sd_proj_bg_median+sd_proj_bg_stdev*2.75 # sphere_thresh = sd_proj_bg_median+sd_proj_bg_stdev*2.75 # ridge_thresh_s = sd_proj_bg_median+sd_proj_bg_stdev*2.75 ridge_list = vquant.classify_shape(shapedex, sd_proj_rescale, ridge, delta=0.25, intensity=ridge_thresh) sphere_list = vquant.classify_shape(shapedex, sd_proj_rescale, sphere, delta=0.2, intensity=sphere_thresh) ridge_list_s = vquant.classify_shape(shapedex_gauss, sd_proj_rescale, ridge, delta=0.3, intensity=ridge_thresh_s) pix_list = ridge_list + sphere_list ridge_list_s = list(set(pix_list) - set(ridge_list_s)) pix_list = pix_list + ridge_list_s pic_binary = np.zeros_like(sd_proj_rescale, dtype=int) if not pix_list == []: rows, cols = zip(*pix_list) pic_binary[rows, cols] = 1 pic_binary = binary_fill_holes(pic_binary) #*********************************************************************************************# vdata_dict.update({ 'img_name': img_name, # 'spot_type': spot_type, 'area_sqmm': area_sqmm, 'valid_shift': valid_shift, 'overlay_mode': overlay_mode, 'pos_plane': pos_plane, 'spot_coords': spot_coords, 'marker_locs': marker_locs, 'classifier_median': round(sd_proj_bg_median, 4) }) #*********************************************************************************************# ##EXTRACT DATA FROM THE BINARY IMAGE prop_list = [ 'label', 'coords', 'area', 'centroid', 'moments_central', 'bbox', 'filled_image', 'major_axis_length', 'minor_axis_length' ] shape_df = vquant.binary_data_extraction(pic_binary, pic3D[pos_plane], prop_list, pix_range=(3, 500)) print('S') if not shape_df.empty: particle_mask = vquant.particle_masker(pic_binary, shape_df, pass_num, first_scan) if pass_num == first_scan: shape_mask = binary_dilation(particle_mask, iterations=3) else: shape_mask = np.add( shape_mask, binary_dilation(particle_mask, iterations=2)) shape_df['pass_number'] = [pass_num] * len(shape_df.index) shape_df['coords'] = shape_df.coords.apply( lambda a: [tuple(x) for x in a]) shape_df['bbox'] = shape_df.bbox.map(vquant.bbox_verts) print('R') else: print("----No valid particle shapes----\n") vdata_dict.update({'total_valid_particles': 0, 'validity': False}) print(shape_df) with open('{}/{}.vdata.txt'.format(vcount_dir, img_name), 'w') as f: for k, v in vdata_dict.items(): f.write('{}: {}\n'.format(k, v)) continue #*********************************************************************************************# filo_pts_tot, round_pts_tot = [], [] z_intensity_list, max_z_slice_list, max_z_stacks, shape_validity = [],[],[],[] greatest_max_list, sd_above_med_difference = [], [] intensity_increase_list = [] print('Measuring particle intensities...\n') for coord_array in shape_df.coords: coord_set = set(coord_array) filo_pts = len(coord_set.intersection(ridge_list)) filo_pts = filo_pts + (len(coord_set.intersection(ridge_list_s)) * 0.15) round_pts = len(coord_set.intersection(sphere_list)) filo_pts_tot.append(filo_pts) round_pts_tot.append(round_pts) # if pic3D.ndim > 2: all_z_stacks = np.array( [pic3D[:, coords[0], coords[1]] for coords in coord_array]) greatest_max = np.max(all_z_stacks) max_z_stack = all_z_stacks[np.where( all_z_stacks == np.max(all_z_stacks))[0][0]].tolist() if max_z_stack[0] >= max_z_stack[-1]: shape_validity.append(True) else: shape_validity.append(False) maxmax_z = max(max_z_stack) max_z_slice = max_z_stack.index(maxmax_z) z_intensity = (maxmax_z - min(max_z_stack)) * 100 std_z_stack = list(np.round(np.std(all_z_stacks, axis=0), 4)) max_z_slice_list.append(max_z_slice) max_z_stacks.append(max_z_stack) z_intensity_list.append(z_intensity) greatest_max_list.append(greatest_max) if (pass_num > first_scan) & (overlay_toggle == True): intensity_increase = max([ img_overlay_difference[coords[0], coords[1]] for coords in coord_array ]) intensity_increase_list.append(intensity_increase) else: intensity_increase_list = [np.nan] * len(shape_df) print('N') shape_df['max_z_slice'] = max_z_slice_list shape_df['max_z_stack'] = max_z_stacks shape_df['z_intensity'] = z_intensity_list shape_df['greatest_max'] = greatest_max_list shape_df['validity'] = shape_validity shape_df['filo_points'] = filo_pts_tot shape_df['round_points'] = round_pts_tot shape_df['intensity_increase'] = intensity_increase_list bbox_pixels = [ vquant.get_bbox_pixels(bbox, pic3D[z]) for i, z, bbox in shape_df[['max_z_slice', 'bbox']].itertuples() ] median_bg_list, shape_df['cv_bg'] = zip(*map( lambda x: (np.median(x), np.std(x) / np.mean(x)), bbox_pixels)) shape_df['perc_contrast'] = ( (shape_df['greatest_max'] - median_bg_list) * 100 / median_bg_list) shape_df.loc[shape_df.perc_contrast <= 0, 'validity'] = False shape_df.loc[shape_df.cv_bg > cv_cutoff, 'validity'] = False shape_df.loc[shape_df.intensity_increase < 40, 'validity'] = False # if len(shape_df) > 1: # regression = smapi.OLS(shape_df.z_intensity, shape_df.perc_contrast).fit() # outlier_df = regression.outlier_test() # shape_df.loc[outlier_df['bonf(p)'] < 0.5, 'validity'] = False shape_df = vquant.remove_overlapping_objs(shape_df, radius=10) #---------------------------------------------------------------------------------------------# ##Filament Measurements shape_df['circularity'] = list( map(lambda A, P: round((4 * np.pi * A) / (perimeter(P)**2), 4), shape_df.area, shape_df.filled_image)) shape_df['ellipticity'] = round(shape_df.major_axis_length / shape_df.minor_axis_length, 4) #max val = 1 shape_df['eccentricity'] = shape_df.moments_central.map( vquant.eccentricity) shape_df = shape_df[(shape_df['filo_points'] + shape_df['round_points']) >= 1] shape_df['filo_score'] = ( (shape_df['filo_points'] / shape_df['area']) - (shape_df['round_points'] / shape_df['area'])) shape_df['roundness_score'] = ((shape_df['round_points'] / shape_df['area'])) #---------------------------------------------------------------------------------------------# filolen_df = pd.DataFrame([ vfilo.measure_fiber_length(coords, spacing=spacing) for coords in shape_df.coords ], columns=['fiber_length', 'vertices'], index=shape_df.index) shape_df = pd.concat([shape_df, filolen_df], axis=1) shape_df['curl'] = (shape_df['major_axis_length'] * spacing) / shape_df['fiber_length'] total_particles = len(shape_df) shape_df['channel'] = ['V'] * total_particles valid_shape_df = shape_df[(shape_df['cv_bg'] < cv_cutoff) & (shape_df['validity'] == True)] total_valid_particles = len(valid_shape_df) #---------------------------------------------------------------------------------------------# #---------------------------------------------------------------------------------------------# kparticle_density = round(total_valid_particles / area_sqmm * 0.001, 2) if pass_num != first_scan: print("Particle density in {}: {} kp/sq.mm\n".format( img_name, kparticle_density)) else: print("Background density in {}: {} kp/sq.mm\n".format( img_name, kparticle_density)) # shape_df.reset_index(drop=True, inplace=True) total_shape_df = pd.concat([total_shape_df, shape_df], axis=0, sort=False) # total_shape_df.reset_index(drop=True, inplace=True) keep_data = [ 'label', 'area', 'centroid', 'pass_number', 'max_z_slice', 'eccentricity', 'ellipticity', 'curl', 'circularity', 'validity', 'z_intensity', 'perc_contrast', 'cv_bg', 'sd_above_med_difference', 'fiber_length', 'filo_score', 'roundness_score', 'channel', 'fl_intensity' ] vdata_dict.update({ 'total_valid_particles': total_valid_particles, 'validity': validity }) with open('{}/{}.vdata.txt'.format(vcount_dir, img_name), 'w') as f: for k, v in vdata_dict.items(): f.write('{}: {}\n'.format(k, v)) #---------------------------------------------------------------------------------------------# vgraph.gen_particle_image(pic_to_show, shape_df, spot_coords, pix_per_um=pix_per_um, show_particles=True, cv_cutoff=cv_cutoff, r2_cutoff=0, scalebar=15, markers=marker_locs, exo_toggle=exo_toggle) savefig('{}/{}.png'.format(img_dir, img_name), dpi=96) clf() close('all') print( "#******************PNG generated for {}************************#\n\n" .format(img_name)) #---------------------------------------------------------------------------------------------# total_shape_df.to_csv('{}/{}.particle_data.csv'.format( vcount_dir, spot_ID), columns=keep_data)
def __calibrateTransformation(self): ''' Calculates transformation values ''' if self._img == None: return self._gui.status("Calibrating transformation...") self.__calibrating = True img = self._img ''' Preprocessing image: ''' try: # get data th = self._gui.getObj("sliderThesholdCircles").value() cannyUp = self._gui.getObj("sliderCirclesCannyUp").value() thCircles = self._gui.getObj("sliderThesholdCircles2").value() minRadius = ( float(str(self._gui.getObj("txtCirclesRadiusMin").text())) / 100.0) * img.shape[0] maxRadius = ( float(str(self._gui.getObj("txtCirclesRadiusMax").text())) / 100.0) * img.shape[0] minDist = ( float(str(self._gui.getObj("txtCirclesDistanceMin").text())) / 100.0) * img.shape[0] blur = 5 # blur image for better result gimg = cvtColor(img, COLOR_RGB2GRAY) gimg = medianBlur(gimg, blur) # create binary image gimg = threshold(gimg, th, 255, THRESH_BINARY)[1] self.__imgSceneTh = gimg ''' Searching for circles by using Hough-Transformation: ''' circles = HoughCircles(gimg, CV_HOUGH_GRADIENT, 1, int(minDist), param1=cannyUp, param2=thCircles, minRadius=int(minRadius), maxRadius=int(maxRadius)) circles = around(circles).astype(int16) centers = circles[0][:, :3] ''' Identifying corners of playing field by evaluating centers of circles: Existence of 4 points are mandatory! ''' vlnr = argsort(centers[:, 0], ) pts_left = centers[vlnr[:2], :] pts_right = centers[vlnr[2:], :] # defining points for coordinate system # left: p00 = pts_left[argsort(pts_left[:, 1])[0], :] p01 = pts_left[argsort(pts_left[:, 1])[1], :] # right: p10 = pts_right[argsort(pts_right[:, 0])[0], :] p11 = pts_right[argsort(pts_right[:, 0])[1], :] # correcting axes with aritmethic mean. p00 and p11 are set # vertical: a_v1 = p01 - p00 a_v2 = p11 - p10 a_v = (a_v1 + a_v2) / 2 # horizontal: a_h1 = p10 - p00 a_h2 = p11 - p01 a_h = (a_h1 + a_h2) / 2 # correcting other corners p10c = p00 + a_h p01c = p11 - a_h # paint lines and circles circle(img, (p00[0], p00[1]), p00[2], (255, 0, 0), 2) circle(img, (p11[0], p11[1]), p11[2], (255, 0, 0), 2) circle(img, (p10[0], p10[1]), p10[2], (255, 0, 0), 2) circle(img, (p01[0], p01[1]), p01[2], (255, 0, 0), 2) line(img, (p00[0], p00[1]), (p01c[0], p01c[1]), (0, 255, 0), 2) line(img, (p00[0], p00[1]), (p10c[0], p10c[1]), (0, 255, 0), 2) line(img, (p10c[0], p10c[1]), (p11[0], p11[1]), (0, 255, 0), 2) line(img, (p01c[0], p01c[1]), (p11[0], p11[1]), (0, 255, 0), 2) self.__imgScene = img ''' Setting Offset and Basismatrix ''' self.__offset = array([p00[0], p00[1]]) self.__basisMatrix = array([[a_v[0], a_h[0]], [a_v[1], a_h[1]]]) except: self._gui.status("Error while calibrating transformation") self.__calibrating = False self._gui.status("Calibration finished.") pass