def check_workspace(self, config): # Set where we typically source our images, set output directory if os.path.isdir(config['image_directory']): self.images_path = config['image_directory'] else: while self.images_path is None: p = shell.Prompt("Path to images: ") if os.path.isdir(p.input): self.images_path = p.input if os.path.isdir(config['output_directory']): self.output_path = config['output_directory'] else: while self.output_path is None: p = shell.Prompt("Path to output: ") if os.path.isdir(p.input): self.output_path = p.input if os.path.isdir(config['data_directory']): self.data_path = config['data_directory'] # Save config config = { 'digit_recogniser': { 'image_directory': self.images_path, 'output_directory': self.output_path, 'data_directory': self.data_path } } ruamel.yaml.dump(config, open(sam_config_path, 'w'), Dumper=ruamel.yaml.RoundTripDumper)
def populate_gitlab_config(): config = {} config['secret'] = shell.Prompt("Enter your Gitlab secret key:").input config['url'] = shell.Prompt("Enter the gitlab instance URL:").input config['name'] = shell.Prompt("Enter this gitlab instance's unique name:", default="default").input return config
def test_prompt_options(self): # test options (non-numbered.. user inputs actual option) with mock.patch(INPUT, return_value='y'): p = shell.Prompt("Test Prompt", options=['y', 'n']) self.eq(p.input, 'y') # test default value with mock.patch(INPUT, return_value=''): p = shell.Prompt("Test Prompt", options=['y', 'n'], default='n') self.eq(p.input, 'n')
def choose_plot(self): x_axis_prompt = shell.Prompt("Choose X axis", options=self.datanames, numbered=True) x_choice = x_axis_prompt.input print(x_choice + ' chosen for x-axis') y_axis_prompt = shell.Prompt("Choose Y axis", options=self.datanames, numbered=True) y_choice = y_axis_prompt.input print(y_choice + ' chosen for y-axis') extent_choices = [ 'All catchments', 'Fault specific', 'Specific catchments' ] p1 = shell.Prompt("Data extent", options=extent_choices, numbered=True) if p1.input is 'Fault specific': fault_list = map(lambda x: 'fault ' + str(x), self.faults.keys()) p2 = shell.Prompt("Choose fault", options=fault_list, numbered=True) self.selected_fault = int(p2.input.replace('fault ', '')) self.title = 'Fault ' + str(self.selected_fault) f_x_data, x_label_id, x_unit_id = self.get_fault_data( x_choice, 'x') f_y_data, y_label_id, y_unit_id = self.get_fault_data( y_choice, 'y') s_x_data, s_y_data = self.sort_by_x(f_x_data, f_y_data) self.plot_data([s_x_data, x_label_id, x_unit_id], [s_y_data, y_label_id, y_unit_id]) elif p1.input is 'Specific catchments': # This is when we plot everything print('yo') else: print('All catchments!') self.title = 'All Catchments' r_x_data, x_label_id, x_unit_id = self.select_dataset( x_choice, 'x') r_y_data, y_label_id, y_unit_id = self.select_dataset( y_choice, 'y') f_x_data = r_x_data.values() f_y_data = r_y_data.values() s_x_data, s_y_data = self.sort_by_x(f_x_data, f_y_data) self.plot_data([s_x_data, x_label_id, x_unit_id], [s_y_data, y_label_id, y_unit_id])
def load_image(self): # Load image and prepare it for analysis image_choice = None while image_choice is None: p = shell.Prompt("Image: ") print 'Checking ' + self.images_path if os.path.exists(os.path.join(self.images_path, p.input)): image_choice = os.path.join(self.images_path, p.input) else: print 'Could not find ' + p.input im = cv2.imread(image_choice) height, width, channels = im.shape # Convert to grayscale and apply Gaussian filtering im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) im_gray = cv2.GaussianBlur(im_gray, (5, 5), 0) im_blank = np.asarray(PIL.Image.new("RGB", (width, height), "white")) im_check = im_blank.copy() im_blank = im.copy() ret, im_blank = cv2.threshold(im_blank, 90, 255, cv2.THRESH_BINARY_INV) # Threshold the image ret, im_th = cv2.threshold(im_gray, 90, 255, cv2.THRESH_BINARY_INV) # Find contours in the image ctrs, hier = cv2.findContours(im_th.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Get rectangles contains each contour rects = [cv2.boundingRect(ctr) for ctr in ctrs] return rects, im_blank, im, im_th, image_choice, im_check
def execute(self, bundle_name, paths, targets): if len(paths) < 1 or len(targets) < 1: self.log.error('Invalid rule: paths or targets is empty') rt_out_dir = self.out_dir + '/' + bundle_name if Path(rt_out_dir).exists(): print('Output directory exists. Files may be overwritten.') shell.Prompt("Press Enter To Continue", default='ENTER') else: Path(rt_out_dir).mkdir(parents=True) for path in paths: if not path.endswith('/'): path += '/' for target in targets: target.rstrip('/') if target != '*': target_path = path + target else: target_path = path.rstrip('/') self.log.debug('extracting: %s' % target_path, __name__) self.log.debug('to: %s' % rt_out_dir, __name__) cmd = ['adb', 'pull', '-a', target_path, rt_out_dir] stdout, stderr, exitcode = shell.exec_cmd(cmd) if exitcode != 0: print("error: failed to extract %s" % target_path, file=sys.stderr) print(stderr, file=sys.stderr) else: print('extracted: %s to %s' % (target_path, rt_out_dir))
def test_prompt_input_is_none(self): # test that self.input is none if no default, and no input with mock.patch(INPUT, return_value=''): p = shell.Prompt('Test Prompt', max_attempts=3, max_attempts_exception=False, ) self.eq(p.input, None)
def test_prompt_clear(self): # test with a non-clear command: with mock.patch(INPUT, return_value='Test Input'): p = shell.Prompt("Test Prompt", clear=True, clear_command='true', ) self.eq(p.input, 'Test Input')
def test_prompt_case_insensitive(self): with mock.patch(INPUT, return_value='NO'): p = shell.Prompt( "Test Prompt", options=['yes', 'no', 'maybe'], case_insensitive=True, ) self.eq(p.input, 'NO') with mock.patch(INPUT, return_value='NOT VALID'): p = shell.Prompt( "Test Prompt", options=['yes', 'no', 'maybe'], case_insensitive=True, max_attempts=3, max_attempts_exception=False, ) self.eq(p.input, None)
def test_prompt_numbered_options(self): # test numbered selection (user inputs number) with mock.patch(INPUT, return_value='3'): p = shell.Prompt("Test Prompt", options=['yes', 'no', 'maybe'], numbered=True, ) self.eq(p.input, 'maybe') # test default value with mock.patch(INPUT, return_value=''): p = shell.Prompt( "Test Prompt", options=['yes', 'no', 'maybe'], numbered=True, default='2', ) self.eq(p.input, 'no')
def default(self): try: while True: option = shell.Prompt( "What do you want to do?", options=[ c.MENU_FILTER_SSR, c.MENU_FILTER_PRID, c.MENU_GET_REPORT_PRID, c.MENU_GET_ROWS_ID_TO_DELETE, c.MENU_CLOSE ], numbered=True, ) if option.input == c.MENU_CLOSE: print 'good bye' break elif option.input == c.MENU_FILTER_SSR: f.find_aborted_ssr() elif option.input == c.MENU_FILTER_PRID: f.check_aborted_ssr() elif option.input == c.MENU_GET_ROWS_ID_TO_DELETE: print 'Please insert the filename to get all id rows selected.' file_name = '' while len(file_name) == 0: file_name = raw_input('file name: ') f.make_report_output(file_name, self.absolute_prids, self.partial_prids) elif option.input == c.MENU_GET_REPORT_PRID: self.absolute_prids = [] self.partial_prids = [] decision = DecisionPrompt( 'Do you want get only erasable prids?') erasable = False if decision.input.lower() == 'yes': erasable = True limit_days = int(os.getenv('DAYS_EXPIRES', 180)) question = 'do you want delete the prids with more than {0} days elapsed?'.format( limit_days) decision = DecisionPrompt(question) days_filter = False if decision.input.lower() == 'yes': days_filter = True prids = f.filter_prid_abortables(only_erasables=erasable, days_filter=days_filter, limit=limit_days) headers = [ 'PRID', 'Aborted SSR', 'Total SSR', 'Percentage', 'Days Elapsed', 'Erasable' ] self.app.render(prids, headers=headers) for p in prids: if p[-1]: self.absolute_prids.append(p[0]) else: self.partial_prids.append(p[0]) print('') except Exception as e: print type(e), e
def test_prompt_case_sensitive(): with mock.patch(INPUT, return_value='NO'): p = shell.Prompt( "Test Prompt", options=['yes', 'no', 'maybe'], case_insensitive=False, max_attempts=3, max_attempts_exception=False, ) assert p.input is None
def test_prompt_max_attempts(): # test that self.input is none if no default, and no input with mock.patch(INPUT, return_value=''): msg = "Maximum attempts exceeded getting valid user input" with raises(FrameworkError, match=msg): shell.Prompt( 'Test Prompt', max_attempts=3, max_attempts_exception=True, )
def test_prompt_index_and_value_errors(self): with mock.patch(INPUT, return_value='5'): p = shell.Prompt( "Test Prompt", options=['yes', 'no', 'maybe'], numbered=True, max_attempts=3, max_attempts_exception=False, ) self.eq(p.input, None)
def test_prompt_max_attempts(self): # test that self.input is none if no default, and no input with mock.patch(INPUT, return_value=''): try: p = shell.Prompt('Test Prompt', max_attempts=3, max_attempts_exception=True, ) except FrameworkError as e: self.eq(e.msg, "Maximum attempts exceeded getting valid user input", ) raise
def create(self): milestone = collections.OrderedDict() milestone['title'] = shell.Prompt("Enter the milestone title:").input milestone['description'] = MilestonesCreationDescriptionPrompt().input milestone['start_date'] = MilestonesCreationStartDatePrompt().input milestone['due_date'] = MilestonesCreationDueDatePrompt().input self.app.render([milestone.values()], headers=milestone.keys()) proceed = MilestonesCreationConfirmationPrompt().input if proceed == 'yes': for project in self.app.gl.projects.all(per_page=100): print("Creating milestone for project %s...." % project.name) project.milestones.create(milestone) else: print('Milestone creation canceled')
app.setup() app.run() # Using my own config for now sam_config_path = '/home/sb708/.sam' config_raw = ruamel.yaml.load(open(sam_config_path), ruamel.yaml.RoundTripLoader) config = {'image_directory': None, 'output_directory': None} if config_raw.has_key('digit_recogniser'): config = config_raw['digit_recogniser'] cont = True first_run = True while cont is True: if first_run is not True: p = shell.Prompt("Transcribe new image?", ['y', 'n']) if p.input is 'y': print("Running...") tsc = Transcriber(config) else: cont = False else: first_run = False print("Running...") tsc = Transcriber(config) print 'Finishing up...' app.close()
def get_meta(self, image_choice): # Context and data labels fan = None surface = None site = None name = None cover = None location = None meta_check = False if self.data_path: image_name = os.path.splitext(os.path.basename(image_choice))[0] print image_name print 'wolman_' + image_name + '.yml' if os.path.exists( os.path.join(self.data_path, 'wolman_' + image_name + '.yml')): image_data = ruamel.yaml.load( open( os.path.join(self.data_path, 'wolman_' + image_name + '.yml')), ruamel.yaml.RoundTripLoader) fan = image_data['fan'] surface = image_data['surface'] site = image_data['site'] name = image_data['name'] cover = image_data['cover'] location = image_data['location'] meta_check = True if meta_check is False: while fan is None: p = shell.Prompt("Fan: ") if p: fan = p.input while surface is None: p = shell.Prompt("Surface: ") if p: surface = p.input while site is None: p = shell.Prompt("Site: ") if p: site = p.input while name is None: p = shell.Prompt("Name: ") if p: name = p.input while cover is None: p = shell.Prompt("% cover: ") if p: cover = p.input while location is None: p = shell.Prompt("Location: ") if p: location = p.input self.meta = { 'fan': fan, 'surface': surface, 'site': site, 'cover': cover, 'name': name, 'location': location }
def transcribe(self, rects, im, im_th, im_blank, im_check): # Use human to tell us what digits are i = 0 im_orig = im.copy() im_points = im.copy() input_numbers = [] s_type = len(rects) data = {} mistakes = [] for rect in rects: # Draw the rectangles cv2.rectangle(im, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0, 255, 0), 3) cv2.rectangle(im_blank, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0, 255, 0), 3) # Make the rectangular region around the digit leng = int(rect[3] * 1.6) pt1 = int(rect[1] + rect[3] // 2 - leng // 2) pt2 = int(rect[0] + rect[2] // 2 - leng // 2) s_type = s_type - 1 print s_type if pt1 < 0: pt1 = 0 if pt2 < 0: pt2 = 0 roi = im_th[pt1:pt1 + leng, pt2:pt2 + leng] s = roi.shape roi_x_org = int(s[0] / 2) roi_y_org = int(s[1] / 2) i = i + 1 #if i > 10: #break; if roi.size > 100: labeled_array, num_features = nd.label(roi) loc = nd.find_objects(labeled_array) sums = [] labels = range(1, num_features + 1) for l in loc: a = labeled_array[l] am = np.ma.masked_greater(a, 0) sums.append(scipy.sum(am.mask)) # Sum of locations, whichever has the largest is our target target_label = sums.index(max(sums)) + 1 roi = self.select_label(labeled_array, target_label) x_org = rect[0] + (rect[2] / 2) y_org = rect[1] + (rect[3] / 2) digit_loc = im_orig.copy() cv2.rectangle(digit_loc, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0, 255, 0), 3) dh, dw, dc = digit_loc.shape hog_roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA) roi_hog_fd = hog(hog_roi, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualise=False) guess = clf.predict(np.array([roi_hog_fd], dtype=float))[0] digit_loc = cv2.resize(digit_loc, (int(dw * sf2), int(dh * sf2))) input_number = False #input_number = random.randint(0,9) label_choice = cycle(labels) v = label_choice.next() while input_number is False: rh, rw = roi.shape iP = imagePrompt(roi, rh, rw, guess) if iP.output == 'check': print 'Is digit correct?, [y, n]' dh, dw, dc = digit_loc.shape jP = imagePrompt(digit_loc, dh, dw) if jP.output == 'n': roi = self.select_label(labeled_array, label_choice.next()) hog_roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA) roi_hog_fd = hog(hog_roi, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualise=False) guess = clf.predict( np.array([roi_hog_fd], dtype=float))[0] elif iP.output == '.': print 'Cycling next label' roi = self.select_label(labeled_array, label_choice.next()) hog_roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA) roi_hog_fd = hog(hog_roi, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualise=False) guess = clf.predict(np.array([roi_hog_fd], dtype=float))[0] elif iP.output == '!': print 'Alerting possible mistake' if i > 1: mistakes.append(i - 1) elif iP.output == 'n': input_number = iP.output else: numbers = ''.join(c for c in iP.output if c.isdigit()) if len(numbers): input_number = numbers if iP.output == 'n': print 'Target discarded!' else: data.update({ i: { 'x_org': x_org, 'y_org': y_org, 'input': input_number, 'roi': roi } }) check = False print 'Mistakes:' print mistakes print data.keys() while check is False: p = shell.Prompt('Check values?', ['y', 'n']) intval = False num = re.sub(r'[^\d]+', '', p.input) if num: intval = int(re.sub(r'[^\d]+', '', p.input)) print intval if p.input == 'n': check = True elif intval in data.keys(): d = data[intval] dh, dw = d['roi'].shape jP = imagePrompt(d['roi'], dh, dw, d['input']) data.update({ intval: { 'x_org': d['x_org'], 'y_org': d['y_org'], 'input': int(jP.output), 'roi': d['roi'] } }) else: print 'Key not found' input_numbers = [] for k, v in data.iteritems(): self.point_ids.append(k) cv2.destroyAllWindows() self.number_input.update({k: v['input']}) self.x_points.append(v['x_org']) self.y_points.append(v['y_org']) cv2.putText(im_check, str(v['input']), (v['x_org'], v['y_org']), cv2.FONT_HERSHEY_SIMPLEX, 1.4, (0, 0, 0), 3) cv2.putText(im_blank, str(k), (v['x_org'], v['y_org']), cv2.FONT_HERSHEY_SIMPLEX, .7, (0, 0, 255), 2) cv2.putText(im_blank, str(k), (v['x_org'], v['y_org']), cv2.FONT_HERSHEY_SIMPLEX, .7, (0, 0, 255), 2) cv2.circle(im_points, (v['x_org'], v['y_org']), 7, (0, 0, 225), -1) self.taught_data.append(v['roi']) self.taught_labels.append(v['input']) input_numbers.append(v['input']) return im_points, im_check, im_blank, input_numbers
def test_prompt_simple(self): with mock.patch(INPUT, return_value='Test Input'): p = shell.Prompt("Test Prompt") self.eq(p.input, 'Test Input')
def connect_digits(self, points, image): # Human test to ensure multi-character digits are grouped, then automatically combine based on location print 'Connecting digits' all_distances = [] connections = [] for i in range(len(points.T)): row = [points[0][i], points[1][i], points[2][i]] a = np.array((row[1], row[2], 1)) distances = [] counter_points = [] for j in range(len(points.T)): row2 = [points[0][j], points[1][j], points[2][j]] if row2[0] != row[0]: b = np.array((row2[1], row2[2], 1)) distances.append(np.linalg.norm(a - b)) counter_points.append(row2[0]) # Nearest neighbour smallest_distance = min(distances) nn = counter_points[distances.index(smallest_distance)] all_distances.append(min(distances)) pv = np.where(points[0] == nn)[0] # Check bearing isn't vertical or sub-vertical angle = abs( degrees( atan2(points[2][pv][0] - row[2], points[1][pv][0] - row[1]))) angle_ranges = [(0, 45), (135, 225), (310, 360)] if any(lower <= angle <= upper for (lower, upper) in angle_ranges): connections.append([ row[1], row[2], points[1][pv][0], points[2][pv][0], smallest_distance, row[0], nn ]) distance_stdev = np.std(all_distances) distance_median = np.percentile(all_distances, 50) connection_threshold = distance_median + distance_stdev cT = connectionThresholder(connection_threshold, image, connections) cv2.destroyAllWindows() ok_connections = cT.current_connections groups = [] for c in ok_connections: groups.append([c[5], c[6]]) for g in groups: g = g.sort() # Remove duplicates groups = list(groups for groups, _ in itertools.groupby(groups)) height, width, channels = image.shape connection_image = cT.connection_image p = shell.Prompt('Select individual connections?', ['y', 'n']) if p.input != 'n': while True: app = connectionSelect(connection_image) app.mainloop() roi = [int(x * sf) for x in app.dimensions] # cv2.rectangle(image, (roi[0], roi[1]), (roi[2], roi[3]), (0, 255, 0), 3) # height, width, channels = image.shape # im2 = cv2.resize(image, (int(width*sf2), int(height*sf2))) # cv2.imshow('test', im2) # cv2.waitKey(0) if len(roi) > 0: points_in_roi = [] for i in range(len(points.T)): if roiCheck(roi, [points[1][i], points[2][i]]) is True: points_in_roi.append(points[0][i]) for pr in points_in_roi: for g in groups: for gi in g: if gi == pr: g.remove(gi) groups.append(points_in_roi) im_copy = image.copy() # Points in ROI # Reset connections for g in groups: # Create new distance lists if len(g) > 1: # For each group id p_points = [] c_points = [] for p in g: # List through other ids d = [] # Distances to original point e = [] # Point ids p_points.append(p) gt = np.where(points[0] == p)[0] a = np.array((points[1][gt], points[2][gt], 1)) for r in g: # If id is different if p != r: # Record distance pt = np.where(points[0] == r)[0] b = np.array( (points[1][pt], points[2][pt], 1)) d.append(np.linalg.norm(a - b)) e.append(r) nn = e[d.index(min(d))] c_points.append(nn) for m in range(len(c_points)): c1p = np.where(points[0] == p_points[m])[0] c2p = np.where(points[0] == c_points[m])[0] c1 = (points[1][c1p], points[2][c1p]) c2 = (points[1][c2p], points[2][c2p]) cv2.line(im_copy, c1, c2, (255, 0, 0), 3) connection_image = cv2.resize( im_copy, (int(width * sf2), int(height * sf2))) p = shell.Prompt('Select more regions?', ['y', 'n']) if p.input == 'n': break a = np.array(groups) a = np.hstack(a) connected_points = np.unique(a) singular_digits = np.setdiff1d(points[0], connected_points) connected_groups = [] # Group interconnected for g in groups: c = [g] for k in range(len(groups)): if not len(g) == len(np.setdiff1d(g, groups[k])): c.append(groups[k]) groups[k] = [] connected_groups.append(c) for m in range(len(connected_groups)): b = np.array(connected_groups[m]) b = np.hstack(b) connected_groups[m] = np.unique(b).tolist() # Remove empties connected_groups = [x for x in connected_groups if x] numlist = [] for s in singular_digits: numlist.append(int(self.number_input[s])) for g in connected_groups: num_string = '' # Reorder according to left-right position x_coords = [] print g for i in g: print i pv = np.where(points[0] == i)[0] # i if pv: x_coords.append([i, points[1][pv][0]]) g_x_coords = np.array(x_coords) l = g_x_coords[np.argsort(g_x_coords[:, 1])] for n in l: input_string = str(self.number_input[int(n[0])]) num_string += input_string numlist.append(num_string) final_numbers = map(int, numlist) return final_numbers
def boot(self): ec2_key_name = self.app.pargs.ec2_key_name or None log = self.app.log config_path = self.app.pargs.config should_prompt = not self.app.pargs.Y if not ec2_key_name: log.warning(""" You'll likely want to be able to log in or change dependencies of this cluster. Without a key that will not be possible. If this is a dev cluster, it's almost a certainty that you will want to specify a key. To create a key run: cluster_funk clusters create-ec2-key -n my-key-name """) if should_prompt: resp = shell.Prompt("Do you still want to create the cluster?", options=['yes', 'no'], numbered=True) if resp.input == 'no': log.info( "({input}) selected, please try again once you have create a ec2_key" .format(input=resp.input)) return try: table = self.app.db.table('users') user_id = table.all()[0]['id'] except IndexError: user_id = None if not os.path.exists(config_path): log.info( "Could not find the cluster configuration you entered. Please specify a valid path" ) return config = yaml.load(open(config_path).read()) # TODO: create a config validator maybe to help with config issues. config['Tags'] = config.get('Tags', {}) config['Tags']['user_id'] = user_id config['Ec2KeyName'] = self.app.pargs.ec2_key_name or None session = self._aws_session() booter = ClusterBooter(config, session) wait, resp = booter.boot() if wait: log.info( "Waiting for cluster to boot. This can take about 10 minutes. Feel free to grab a cup of ☕" ) wait() log.info("All set, cluster is fully booted.") table = self.app.db.table('history') table.insert({ 'action': 'cluster_boot', 'resp': resp, 'on': str(datetime.now()) })
def test_prompt_simple(): with mock.patch(INPUT, return_value='Test Input'): p = shell.Prompt("Test Prompt") assert p.input == 'Test Input'