def _load_image(b): try: img = Image.open(io.BytesIO(b)) img = img.convert("RGB") return np.asarray(img) except: return None
def gmean(a, axis=0, dtype=None): # A copy/paste of scipy.stats.mstats.gmean function to # avoid the scipy dependency if not isinstance(a, np.ndarray): # if not an ndarray object attempt to convert it log_a = np.log(np.array(a, dtype=dtype)) elif dtype: # Must change the default dtype allowing array type if isinstance(a, np.ma.MaskedArray): log_a = np.log(np.ma.asarray(a, dtype=dtype)) else: log_a = np.log(np.asarray(a, dtype=dtype)) else: log_a = np.log(a) return np.exp(log_a.mean(axis=axis))
def draw_bboxes(x: List[torch.Tensor], bboxes: List[List[BoundingBox]], categories: List[str], orientation: str = 'vertical', width: float = 5, height: float = 5, directory: Optional[str] = None): assert len(x) == len(bboxes) n = len(x) if orientation == 'vertical': cols, rows = 1, n elif orientation == 'horizontal': cols, rows = n, 1 else: raise AssertionError(f'Invalid orientation: {orientation}') fig = plt.figure(figsize=(width * cols, height * rows)) for i in range(0, n): plt.subplot(rows, cols, i + 1) image = x[i].cpu() image = VTF.to_pil_image(image) image_arr = np.asarray(image) image_arr = cv2.cvtColor(image_arr, cv2.COLOR_RGB2BGR) for bbox in bboxes[i]: image_arr = cv2.rectangle(image_arr, bbox.pt_from, bbox.pt_to, (0, 0, 255), 2) image_arr = cv2.putText( image_arr, f'{categories[bbox.label]} - {bbox.score:.3f}', bbox.pt_from, cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255)) image_arr = cv2.cvtColor(image_arr, cv2.COLOR_BGR2RGB) image = Image.fromarray(image_arr) plt.grid(False) plt.axis('off') plt.imshow(image) if directory is not None: Path(directory).mkdir(parents=True, exist_ok=True) image.save(os.path.join(directory, f'image{i}.jpg')) return fig
def run_methods(self): results = defaultdict(list) # We only test the methods common to all converters # (The intended use is with a list of converters all # having the same methods, but different input files) methods = set(self.converters[0].available_methods[:]) # a copy ! for converter in self.converters[1:]: methods &= set(converter.available_methods[:]) methods = sorted(methods) if self.include_dummy: methods += ['dummy'] if self.to_include: methods = [x for x in methods if x in self.to_include] elif self.to_exclude: methods = [x for x in methods if x not in self.to_exclude] for method in methods: print("\nEvaluating method %s" % method) # key: converter.infile # value: list of times times = defaultdict(list) pb = Progress(self.N) for i in range(self.N): for converter in self.converters: with Timer(times[converter.infile]): converter(method=method) pb.animate(i + 1) # Normalize times so that each converter has comparable times mean_time = gmean(np.fromiter(chain(*times.values()), dtype=float)) # median of ratios to geometric mean (c.f. DESeq normalization) scales = { conv: np.median(np.asarray(conv_times) / mean_time) for conv, conv_times in times.items() } for (conv, conv_times) in times.items(): scale = scales[conv] results[method].extend( [conv_time / scale for conv_time in conv_times]) self.results = results
def evaluate(model, X_test, y_test): y_pred = model.predict(X_test) cf_matrix = confusion_matrix(y_test, y_pred) categories = ['Negative', 'Positive'] group_names = ['True Neg', 'False Pos', 'False Neg', 'True Pos'] group_percentages = [ '{0:.2%}'.format(value) for value in cf_matrix.flatten() / np.sum(cf_matrix) ] labels = [f'{v1}\n{v2}' for v1, v2 in zip(group_names, group_percentages)] labels = np.asarray(labels).reshape(2, 2) sns.heatmap(cf_matrix, annot=labels, cmap='Blues', fmt='', xticklabels=categories, ytick=categories) plt.xlabel("Predicted values", fontdict={'size': 14}, labelpad=10) plt.xlabel("Actual values", fontdict={'size': 14}, labelpad=10) plt.xlabel("Confusion Matrix", fontdict={'size': 18}, labelpad=10)
def __init__(self, pnt_file, name=None): self._pnt_file = pathlib.Path(pnt_file) # Load pnt file, returns header (dict) and raw samples self._pnt_header, pnt_samples = Pnt.load(self._pnt_file) # Get clean WGS84 coordinates (use +/- instead of N/E) self._latitude = self.pnt_header_value(Pnt.Header.GPS_WGS84_LATITUDE) self._longitude = self.pnt_header_value(Pnt.Header.GPS_WGS84_LONGITUDE) north = self.pnt_header_value(Pnt.Header.GPS_WGS84_NORTH) east = self.pnt_header_value(Pnt.Header.GPS_WGS84_EAST) if north.upper() != 'N': self._latitude = -self._latitude if east.upper() != 'E': self._longitude = -self._longitude if abs(self._latitude) > 90: log.warning('Latitude value {} invalid, replacing by None'.format( self._latitude)) self._latitude = None if abs(self._longitude) > 180: log.warning('Longitude value {} invalid, replacing by None'.format( self._longitude)) self._longitude = None # Get a proper timestamp by putting pnt entries together self._timestamp = None year = self.pnt_header_value(Pnt.Header.TIMESTAMP_YEAR) month = self.pnt_header_value(Pnt.Header.TIMESTAMP_MONTH) day = self.pnt_header_value(Pnt.Header.TIMESTAMP_DAY) hour = self.pnt_header_value(Pnt.Header.TIMESTAMP_HOUR) minute = self.pnt_header_value(Pnt.Header.TIMESTAMP_MINUTE) second = self.pnt_header_value(Pnt.Header.TIMESTAMP_SECOND) try: self._timestamp = datetime(year, month, day, hour, minute, second, tzinfo=pytz.UTC) log.info( 'Timestamp of profile as reported by pnt header is {}'.format( self.timestamp)) except ValueError: log.warning('Unable to build timestamp from pnt header fields') # Set name of profile (by default a entry from pnt header) self._name = self.pnt_header_value(Pnt.Header.FILENAME) if name: self._name = name # Get other important entries from header self._samples_count = self.pnt_header_value( Pnt.Header.SAMPLES_COUNT_FORCE) self._spatial_resolution = self.pnt_header_value( Pnt.Header.SAMPLES_SPATIALRES) self._overload = self.pnt_header_value(Pnt.Header.SENSOR_OVERLOAD) self._speed = self.pnt_header_value(Pnt.Header.SAMPLES_SPEED) self._smp_serial = str(self.pnt_header_value(Pnt.Header.SMP_SERIAL)) self._smp_firmware = str(self.pnt_header_value( Pnt.Header.SMP_FIRMWARE)) self._smp_length = self.pnt_header_value(Pnt.Header.SMP_LENGTH) self._smp_tipdiameter = self.pnt_header_value( Pnt.Header.SMP_TIPDIAMETER) self._gps_pdop = self.pnt_header_value(Pnt.Header.GPS_PDOP) self._gps_numsats = self.pnt_header_value(Pnt.Header.GPS_NUMSATS) self._amplifier_range = self.pnt_header_value( Pnt.Header.AMPLIFIER_RANGE) self._amplifier_serial = self.pnt_header_value( Pnt.Header.AMPLIFIER_SERIAL) self._sensor_serial = self.pnt_header_value(Pnt.Header.SENSOR_SERIAL) self._sensor_sensivity = self.pnt_header_value( Pnt.Header.SENSOR_SENSITIVITIY) # Create a pandas dataframe with distance and force distance_arr = np.arange( 0, self._samples_count) * self._spatial_resolution factor = self.pnt_header_value(Pnt.Header.SAMPLES_CONVFACTOR_FORCE) force_arr = np.asarray(pnt_samples) * factor stacked = np.column_stack([distance_arr, force_arr]) self._samples = pd.DataFrame(stacked, columns=('distance', 'force')) self._ini = configparser.ConfigParser() # Look out for corresponding ini file self._ini_file = self._pnt_file.with_suffix('.ini') if self._ini_file.exists(): log.info('Reading ini file {} for {}'.format(self._ini_file, self)) self._ini.read(self._ini_file) # Ensure a section called 'markers' does exist if not self._ini.has_section('markers'): self._ini.add_section('markers') # Check for invalid values (non floats) in 'markers' section for k, v in self._ini.items('markers'): try: float(v) log.info('Marker: {}={}'.format(k, v)) except ValueError: log.warning( 'Ignoring value {} for marker {}, not float value'.format( repr(v), repr(k))) self._ini.remove_option('markers', k)
def test_that_we_project_larger_image_to_smaller(self): image = Image([[[4, 4, 0]]], 4, 2) print(np.asarray([[1, 1], [1, 0]])) self.assertSequenceEqual([[1, 1], [1, 0]], image.BITMAP.tolist())