def test_log_path(): log.set_mode(log.Mode.LOG) log.set_path("check/") img = cv2.imread("tests/data/orange.png") log.image(log.Level.ERROR, img) assert os.path.exists('check/cvlog.html') is True log.set_path("log/")
def localise_phantom(im, threshold = None): """ Show the position of a phantom in an image. Originally written for circular phantoms. Works in 3d, expects dim order z, y, x """ if not threshold: threshold = im.mean() seg = im > threshold seg = binary_fill_holes(seg) seg = find_largest_segmented_object(seg) output = localise_segmented_object(seg) center = output['center'] #Create a debug image logging=False if logging: for x in output['x_range']: seg[:,x-2:x+2] = 1 for y in output['y_range']: seg[y-2:y+2,:] = 1 seg[center[0]-20:center[0]+20,center[1]-5:center[1]+5] = 0 seg[center[0]-5:center[0]+5,center[1]-20:center[1]+20] = 0 log.image(log.Level.INFO, seg*.99) return output
def test_log_image(): remove_dirs('log/') img = cv2.imread("tests/data/orange.png") log.set_mode(log.Mode.LOG) log.image(log.Level.ERROR, img) logitem = get_html('log/cvlog.html').select('.log-list .log-item') assert logitem[0].select('.log-type')[0].text == 'image' assert logitem[0]['logdata'] == read_file('tests/data/expected/image.txt')
def test_log_interruption(): remove_dirs('log/') log.set_mode(log.Mode.LOG) img = cv2.imread("tests/data/orange.png") log.image(log.Level.ERROR, img) assert os.path.exists('log/cvlog.html') is True remove_dirs('log/') log.image(log.Level.ERROR, img) assert os.path.exists('log/cvlog.html') is True
def test_message(): remove_dirs('log/') img = cv2.imread('tests/data/contour.jpg') log.set_mode(log.Mode.LOG) imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 127, 255, 0) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) message = 'Lorem ipsum dolor sit amet, ne persius reprehendunt mei. Ea summo elitr munere his, et consul offendit recteque sea, quis elit nam ut.' log.image(log.Level.ERROR, img) log.contours(log.Level.ERROR, contours, img, msg=message) logitem = get_html('log/cvlog.html').select('.log-list .log-item') assert logitem[0].select('.description') == [] assert logitem[1].select('.description')[0].text == message
def calculate_MTF_from_ROI(im_ROI): mask = iu.mask_point(im_ROI) mask = morphology.binary_opening(mask) log.image(log.Level.TRACE, im_ROI * mask) mask = morphology.binary_dilation(mask, iterations = 3) im_ROI = subtract_background(im_ROI, mask) localisation = iu.localise_segmented_object(mask) y, x = localisation['center'] y_vals = iu.get_nearby_integers(y) x_vals = iu.get_nearby_integers(x) log_text(x_vals, priority = 5) log_text(y_vals, priority = 5) h_LSF = make_LSF(im_ROI, y_vals, 1) v_LSF = make_LSF(im_ROI, x_vals, 0) h_MTF = iu.mtf_from_lsf(h_LSF) v_MTF = iu.mtf_from_lsf(v_LSF) return h_MTF, v_MTF
def catphan_select_wire_roi(im): """ Take an image of the contrast segment of a catphan. If the phantom is correctly oriented, the wire will be in a similar position relative to the phantom boundaries. """ #Based on phantom measurements made in ImageJ #y_min, y_max = 18.1, 219 #x_min, x_max = 16.9, 217.2 #w_x, w_y = 140.5, 120.4 #yratio = (w_y-y_min)/(y_max - y_min) #xratio = (w_x-x_min)/(x_max - x_min) yratio = 0.5092085614733699 xratio = 0.6170743884173739 #Threshold the phantom out p_shape = im > -900 log.image(log.Level.TRACE, im * p_shape) p_shape = morphology.binary_erosion(p_shape, iterations = 12) p_shape = morphology.binary_dilation(p_shape, iterations = 12) log.image(log.Level.TRACE, im * p_shape) p_y, p_x = np.where(p_shape==True) p_y.min(), p_x.max() #Select the position of the wire based on previous measurements ypos = yratio * (p_y.max() - p_y.min()) + p_y.min() xpos = xratio * (p_x.max() - p_x.min()) + p_x.min() r = np.array([int(xpos)-14, int(ypos)-14,28,28]) a = im[iu.Rslice(r)].copy() log.image(log.Level.INFO, a) return a
def align_line_profiles(ROI, midpoint=None): """ Align a set of line profiles arranged in columns, centering at the half-max Parameters ---------- ROI : np.array ROI containing line profiles. Returns ------- output : np.array ROI with profiles aligned at the half-maximum. """ if not midpoint: midpoint = (ROI.max() + ROI.min())/2 smoothed = np.apply_along_axis(wiener, 0, ROI) indexes = np.apply_along_axis(interp_first_index, 0, smoothed, midpoint) shifts = ROI.shape[0]//2 - indexes output = shift_columns_by_subpixel(ROI, shifts) log.image(log.Level.TRACE, apply_window(output)) return output
def log_all_level(img): log.image(log.Level.TRACE, img) log.image(log.Level.INFO, img) log.image(log.Level.ERROR, img)
def old_clinical_mtf(im, pixel_spacing, roi_size=(50, 30)): """ Calculate the MTF from a patient/phantom image. Requires air on the side of the patient corresponding to the zero direction of the y axis. Only use this function for 2d images, which are not currently covered by new clinical MTF Parameters ---------- im : np.array 2d or 3d axial CT image. im[Z, Y, X] pixel_spacing : tuple pixel size of (y, x) in mm. roi_size : tuple, Size of the ROI that the MTF will be calculated across. The default is (50, 30). Returns ------- output : dictionary Dictionary containing the key 'clinical', which contains 'MTF' and 'frequency' """ if im.ndim == 2: im = im[np.newaxis, ] mtfs = [] fs = [] for i in range(im.shape[0]): im_2d = im[i, :] #find head try: seg_data = iu.localise_phantom(im_2d, -300) if seg_data['anterior_point'][0] < 15: im_2d = np.pad(im_2d, 15, mode='constant', constant_values=-1024) seg_data = seg_data = iu.localise_phantom(im_2d, -300) except: continue y = seg_data['anterior_point'][0] x = seg_data['anterior_point'][1] roi = iu.extract_patch_around_point(im_2d, (y, x), roi_size) log.image(log.Level.TRACE, iu.apply_window(roi)) # find the index of array element with the highest rate of change roi = iu.align_line_profiles(roi, -500) w = 10 c = roi.shape[0]//2 esf = roi[c-w:c+w, :].mean(axis=1) #log_plot(range(len(esf)), esf) mtf = iu.mtf_from_esf(esf) mtf = mtf/mtf[0] f = pixel_spacing[0]/2*np.arange(mtf.shape[0]) mtfs.append(mtf) fs.append(f) mtf = np.array(mtfs) mtf = np.median(mtf, axis=0) f = np.array(fs) f = np.median(f, axis=0) output = {'Clinical': {'MTF': mtf, 'frequency': f}} return output