def contains(self, skycoord): """ Check whether the given (list of) sky coordinate(s) falls inside this sky patch (region). Parameters ---------- skycoord : `~astropy.coordinate.SkyCoord` or (lon, lat) tuple The (list of) sky coordinate(s) to check, or the (list of) longitudes and latitudes of sky coordinates [ deg ] Returns ------- inside : bool (list of) boolean values indicating whether the given sky coordinate(s) is inside this sky patch. """ if not isinstance(skycoord, SkyCoord): lon, lat = skycoord skycoord = SkyCoord(lon, lat, unit=au.deg) wcs = self.wcs pixcoord = PixCoord.from_sky(skycoord, wcs=wcs) center = PixCoord(x=self.xcenter, y=self.ycenter) region = RectanglePixelRegion(center=center, width=self.xsize, height=self.ysize) return region.contains(pixcoord)
def define_regions( hdu: iofits.hdu.image.PrimaryHDU, parameters: dict ) -> Dict[str, Union[CircleAnnulusPixelRegion, RectanglePixelRegion]]: regions = dict() pileup_region = read_pileup_region() rot_angle_deg = define_rotation_angle_deg(parameters) windel = parameters['win_start'] - 512 # source region regions['src'] = CircleAnnulusPixelRegion( center=pileup_region.center, inner_radius=pileup_region.inner_radius, outer_radius=RADII['3arcmin'], meta=SRC_REGION_META) # background region regions['bkg'] = CircleAnnulusPixelRegion(center=pileup_region.center, inner_radius=RADII['5arcmin'], outer_radius=RADII['7arcmin'], meta=BKG_REGION_META) # exclude region 1 ref = np.array([0, windel - 256.]) ref = convert_reference_coodinate(ref, parameters) regions['rct1'] = RectanglePixelRegion(center=PixCoord( float(ref[0][0]), float(ref[1][0])), width=1024., height=512., angle=Angle(rot_angle_deg, 'deg')) # exclude region 2 ref = np.array([0, windel + parameters['win_size'] + 256.]) ref = convert_reference_coodinate(ref, parameters) regions['rct2'] = RectanglePixelRegion(center=PixCoord( float(ref[0][0]), float(ref[1][0])), width=1024., height=512., angle=Angle(rot_angle_deg, 'deg')) # exclude region 3 ref = np.array([512. + 128., windel + parameters['win_size'] * 0.5]) ref = convert_reference_coodinate(ref, parameters) regions['rct3'] = RectanglePixelRegion( center=PixCoord(float(ref[0][0]), float(ref[1][0])), width=256., height=parameters['win_size'] + 1024., angle=Angle(rot_angle_deg, 'deg')) # exclude region 4 ref = np.array([-512 - 128, windel + parameters['win_size'] * 0.5]) ref = convert_reference_coodinate(ref, parameters) regions['rct4'] = RectanglePixelRegion( center=PixCoord(float(ref[0][0]), float(ref[1][0])), width=256., height=parameters['win_size'] + 1024., angle=Angle(rot_angle_deg, 'deg')) return regions
def __init__(self, x=None, y=None, width=None, length=None, *args, **kwargs): pixcoord = PixCoord(x, y) self._pix_region = RectanglePixelRegion(center=pixcoord, width=width, height=length) self._patch = self._pix_region.as_artist(edgecolor='red', facecolor='none') self._is_active = False
class RectanglePixelSlit(_RectangleSlitBase): """ Slit constructed using WCS and coords information. Utilizes `regions` package. Parameters ---------- x, y : float Center (x, y) of slit in pix. width, length : float width and length of slit in pix. """ def __init__(self, x=None, y=None, width=None, length=None, *args, **kwargs): pixcoord = PixCoord(x, y) self._pix_region = RectanglePixelRegion(center=pixcoord, width=width, height=length) self._patch = self._pix_region.as_artist(edgecolor='red', facecolor='none') self._is_active = False
def range_to_rect(data, ori, low, high): """ Converts a 1D range on a 2D glue Data set into an astropy regions RectangularPixelRegion. The region covers the entirety of the data along the axis not specified by the `ori` parameter. Parameters ---------- data : `glue.core.data.Data` The 2D glue Data object on which the range subset is defined. ori: 'x' or 'y' Specifies if the range limits are for the x-axis or y-axis respectively. low: `float` The lower limit of the range. high: `float` The upper limit of the range. """ if data.ndim != 2: raise NotImplementedError("Can only handle 2-d datasets") if ori == 'x': ymin = 0 ymax = data.shape[0] xmin = low xmax = high else: xmin = 0 xmax = data.shape[1] ymin = low ymax = high xcen = 0.5 * (xmin + xmax) ycen = 0.5 * (ymin + ymax) width = xmax - xmin height = ymax - ymin return RectanglePixelRegion(PixCoord(xcen, ycen), width, height)
def to_object(self, subset): data = subset.data if data.ndim != 2: raise NotImplementedError("Can only handle 2-d datasets at this time") subset_state = subset.subset_state if isinstance(subset_state, RoiSubsetState): if subset_state.xatt != data.pixel_component_ids[1]: raise ValueError('subset state xatt should be x pixel coordinate') if subset_state.yatt != data.pixel_component_ids[0]: raise ValueError('subset state yatt should be y pixel coordinate') roi = subset_state.roi if isinstance(roi, RectangularROI): xcen = 0.5 * (roi.xmin + roi.xmax) ycen = 0.5 * (roi.ymin + roi.ymax) width = roi.xmax - roi.xmin height = roi.ymax - roi.ymin return RectanglePixelRegion(PixCoord(xcen, ycen), width, height) elif isinstance(roi, PolygonalROI): return PolygonPixelRegion(PixCoord(roi.vx, roi.vy)) else: raise NotImplementedError("ROIs of type {0} are not yet supported".format(roi.__class__.__name__)) else: raise NotImplementedError("Subset states of type {0} are not supported".format(subset_state.__class__.__name__))
def plot_one_box(box, img, color=None, label=None, line_thickness=None): # Plots one bounding box on image img tl = line_thickness or round( 0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness color = color or [random.randint(0, 255) for _ in range(3)] x, y = int(box[0]), int(box[1]) width, height = int(box[2]), int(box[3]) angle = Angle(-int(180 * box[4] / np.pi), 'deg') center = PixCoord(x=x, y=y) reg = RectanglePixelRegion(center=center, width=width, height=height, angle=angle) patch = reg.as_artist() path = patch.get_path() vertices = path.vertices.copy() vertices = patch.get_patch_transform().transform(vertices) cv2.drawContours(img, [vertices.astype(int)], -1, color, tl) """
def odom_callback(self, msg): global switch global euler_z global button_1, button_3, button_4, button_5 pos_x = msg.pose.pose.position.x pos_y = msg.pose.pose.position.y pos_z = msg.pose.pose.position.z ori_x = msg.pose.pose.orientation.x ori_y = msg.pose.pose.orientation.y ori_z = msg.pose.pose.orientation.z ori_w = msg.pose.pose.orientation.w if (abs(pos_y) > self.deviation): self.deviation = abs(pos_y) euler_x, euler_y, euler_z = self.quaternion_to_euler_angle(ori_x, ori_y, ori_z, ori_w) if self.graph_switch == True: plt.rcParams["figure.figsize"] = [9,9] plt.rcParams['legend.numpoints'] = 1 plt.grid(alpha=0.2, color='k', linestyle='-.', dash_capstyle='butt', drawstyle='steps', linewidth=0.5) if switch == 0: plt.title('Obstacle Avoidance', loc='center') plt.xlabel('x-axis') plt.ylabel('y-axis') # ROBOT POSITION rp_x, rp_y, rp_z = vrep.simxGetObjectPosition(self.clientID, self.robot_handle, -1, vrep.simx_opmode_streaming)[1] # DYNAMIC OBSTACLE d_x, d_y, d_z = vrep.simxGetObjectPosition(self.clientID, self.d_obs_handle, -1, vrep.simx_opmode_streaming)[1] scale = self.calc_dis(d_x, d_y, rp_x, rp_y) #print(self.gradient(scale)) #print(scale) if scale <= 10: self.alpha = scale / 10 else: self.alpha = 1.0 # calculate distance between robot and obstacle if (scale >= 1): color = [ str(self.gradient(scale)) ] _color = (self.gradient(scale)/255, self.gradient(scale)/255, self.gradient(scale)/255) else: color = [255] _color = (1, 1, 1) if (d_x != 0 and d_y != 0): # # 장애물과 로봇 사이의 거리 # dis = self.calc_dis(rp_x, rp_y, 4.95, d_y) # if (dis <= 1.1): # coll_check1 = 'r' # coll_check2 = (1,0,0) # else: # coll_check1 = 'k' # coll_check2 = (0,0,0) # DYNAMIC OBSTACLE #plt.scatter(d_y, d_x, marker='o', s=300, edgecolors='k', facecolor='none', label='dynamic obstacle') # [1] DYNAMIC OBSTACLE SHAPE #plt.scatter(-d_y, d_x, marker='o', s=600, edgecolors=coll_check1, facecolor=_color, label='dynamic obstacle') # circle = plt.Circle((-d_y, d_x), 0.5, edgecolor=coll_check1, facecolor=_color) # plt.gca().add_patch(circle) # self.csv_container[3] = -d_y # self.csv_container[4] = d_x # # [2] DYNAMIC OBSTACLE TRACE # if (d_y > self._d_y): # dynamic_obstacle, = plt.plot( [-self._d_y, -d_y], [4.95, 4.95], marker=(3, 0, 90), markersize = 5, linewidth=1.0, color='b', label='dynamic obstacle') # else: # dynamic_obstacle, = plt.plot( [-self._d_y, -d_y], [4.95, 4.95], marker=(3, 0, -90), markersize = 5, linewidth=1.0, color='b', label='dynamic obstacle') # self._d_y = d_y # self._d_x = d_x # ROBOT POSITION WITH TRACE x, y = -rp_y, rp_x #-pos_y, pos_x width, height = 0.6, 0.83 angle = Angle(euler_z, 'deg') #Angle(euler_z, 'deg') center = PixCoord(x=x, y=y) reg = RectanglePixelRegion(center=center, width=width, height=height, angle=angle) patch = reg.as_artist(facecolor=_color, edgecolor='k', lw=1.0, fill=True) #, label='Holonomic Robot') plt.gca().add_patch(patch) # [2] ROBOT CENTER & TRACE robot_footprint, = plt.plot( [-self._pos_y, -rp_y], [self._pos_x, rp_x], marker=(3, 0, euler_z), markersize = 5, linewidth=1.0, color='r', label='ODG-PF') self._pos_y = rp_y #pos_y self._pos_x = rp_x #pos_x dis1 = self.calc_dis(-self.x_rand1, 2.6, -rp_y, rp_x) dis3 = self.calc_dis(-self.x_rand3, -0.6, -rp_y, rp_x) dis4 = self.calc_dis(-self.x_rand4, -2.95, -rp_y, rp_x) dis5 = self.calc_dis(-self.x_rand5, -5.8, -rp_y, rp_x) # obs 1 if (dis1 <= 1.2): coll_check_1_1 = 'r' coll_check_1_2 = (1,0,0) button_1 = True else: coll_check_1_1 = 'k' coll_check_1_2 = (0,0,0) button_1 = False # obs 3 if (dis3 <= 1.2): coll_check_3_1 = 'r' coll_check_3_2 = (1,0,0) button_3 = True else: coll_check_3_1 = 'k' coll_check_3_2 = (0,0,0) button_3 = False # obs 4 if (dis4 <= 1.2): coll_check_4_1 = 'r' coll_check_4_2 = (1,0,0) button_4 = True else: coll_check_4_1 = 'k' coll_check_4_2 = (0,0,0) button_4 = False # obs 5 if (dis5 <= 1.2): coll_check_5_1 = 'r' coll_check_5_2 = (1,0,0) button_5 = True else: coll_check_5_1 = 'k' coll_check_5_2 = (0,0,0) button_5 = False # STATIC OBSTACLE 1 if button_1 == False: center = PixCoord(x=-self.x_rand1, y = 6.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor='none', lw=1.0, fill=True) plt.gca().add_patch(patch) button_1 = True else: center = PixCoord(x=-self.x_rand1, y=6.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor='none', lw=1.0, fill=True) plt.gca().add_patch(patch) # STATIC OBSTACLE 3 if button_3 == False: center = PixCoord(x=-self.x_rand3, y=1.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor='none', lw=1.0, fill=True) plt.gca().add_patch(patch) button_3 = True else: center = PixCoord(x=-self.x_rand3, y=1.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor=coll_check_3_1, lw=1.0, fill=True) plt.gca().add_patch(patch) # STATIC OBSTACLE 4 if button_4 == False: center = PixCoord(x=-self.x_rand4, y=-2.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor='none', lw=1.0, fill=True) plt.gca().add_patch(patch) button_4 = True else: center = PixCoord(x=-self.x_rand4, y=-2.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor=coll_check_4_1, lw=1.0, fill=True) plt.gca().add_patch(patch) # STATIC OBSTACLE 5 if button_5 == False: center = PixCoord(x=-self.x_rand5, y=-5.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor='none', lw=1.0, fill=True) plt.gca().add_patch(patch) button_5 = True else: center = PixCoord(x=-self.x_rand5, y=-5.75) reg = RectanglePixelRegion(center=center, width=1, height=1) patch = reg.as_artist(facecolor='k', edgecolor=coll_check_5_1, lw=1.0, fill=True) plt.gca().add_patch(patch) #plt.grid() plt.xticks(np.arange(-10, 11, 1)) plt.yticks(np.arange(-10, 11, 1)) plt.draw() if switch < 2: try: static_obstacle = mpatches.Patch(hatch='', color='black', label="static obstacle") plt.legend(handles=[static_obstacle, dynamic_obstacle, robot_footprint]) switch += 1 except: static_obstacle = mpatches.Patch(hatch='', color='black', label="static obstacle") plt.legend(handles=[static_obstacle]) plt.pause(1) goal_dis = self.calc_dis(pos_x, pos_y, 9, 0) # V-REP 축이 뒤틀렸음 simulationTime=vrep.simxGetLastCmdTime(self.clientID) / 1000 # sec로 단위 변환 # f.close() if (goal_dis < 1.2 or simulationTime > 90): if (goal_dis) < 1.2: x, y = -pos_y, pos_x width, height = 0.6, 0.83 angle = Angle(euler_z, 'euler') # 원래는 Angle(euler_z, 'euler')였는데, 이렇게 바꾸면 인터넷 연결이 필요하던 Angle이 필요가 없어지게됨 center = PixCoord(x=x, y=y) reg = RectanglePixelRegion(center=center, width=width, height=height, angle=angle) patch = reg.as_artist(facecolor=_color, edgecolor='m', lw=1.5, fill=True, label='Goal Arrived') plt.gca().add_patch(patch) print("[INFO] EPISODE DONE") plt.savefig('/home/yu-bin/ODMGPF_EXPERIMENT/OD-MGPF_{}_{}_{}_{:.3f}.png'.format(d_threshold, gamma, k_holo, self.deviation, dpi = 300)) # RESULT TO CSV result = {'RESULT': [str(d_threshold)+" "+str(gamma)+" "+str(k_holo)], 'DEVIATION': [str(self.deviation)]} df = pd.DataFrame(result) if not os.path.exists('/home/yu-bin/ODMGPF_EXPERIMENT/output.csv'): df.to_csv('/home/yu-bin/ODMGPF_EXPERIMENT/output.csv', index=False, mode='w', encoding='utf-8-sig') else: df.to_csv('/home/yu-bin/ODMGPF_EXPERIMENT/output.csv', index=False, mode='a', encoding='utf-8-sig', header=False) rospy.signal_shutdown(self.myhook())
def get_subsets_from_viewer(self, viewer_reference, data_label=None): """ Returns the subsets of a specified viewer converted to astropy regions objects. It should be noted that the subset translation machinery lives in the glue-astronomy repository. Currently, the machinery only works on 2D data for cases like range selection. For e.g. a profile viewer that is ostensibly just a view into a 3D data set, it is necessary to first reduce the dimensions of the data, then retrieve the subset information as a regions object. This means that the returned y extents in the region are not strictly representative of the subset range in y. Parameters ---------- viewer_reference : str The reference to the viewer defined with the ``reference`` key in the yaml configuration file. data_label : str, optional Optionally provide a label to retrieve a specific data set from the viewer instance. Returns ------- data : dict A dict of the transformed Glue subset objects, with keys representing the subset name and values as astropy regions objects. """ viewer = self.get_viewer(viewer_reference) data = self.get_data_from_viewer(viewer_reference, data_label, cls=None) regions = {} for key, value in data.items(): if isinstance(value, Subset): # Range selection on a profile is currently not supported in # the glue translation machinery for astropy regions, so we # have to do it manually. Only data that is 2d is supported, # therefore, if the data is already 2d, simply use as is. if value.data.ndim == 2: region = value.data.get_selection_definition( format='astropy-regions') regions[key] = region continue # There is a special case for 1d data (which is also not # supported currently). We now eschew the use of the # translation machinery entirely and construct the astropy # region ourselves. elif value.data.ndim == 1: # Grab the data units from the glue-astronomy spectral axis # TODO: this needs to be much simpler; i.e. data units in # the glue component objects unit = value.data.coords.spectral_axis.unit hi, lo = value.subset_state.hi, value.subset_state.lo xcen = 0.5 * (lo + hi) width = hi - lo region = RectanglePixelRegion( PixCoord(xcen, 0), width, 0, meta={'spectal_axis_unit': unit}) regions[key] = region continue # Get the pixel coordinate [z] of the 3D data, repeating the # wavelength axis. This doesn't seem strictly necessary as it # returns the same data if the pixel axis is [y] or [x] xid = value.data.pixel_component_ids[0] # Construct a new data object collapsing over one of the # spatial dimensions. This is necessary because the astropy # region translation machinery in glue-astronomy does not # support non-2D data, even for range objects. stat_func = 'median' if hasattr(viewer.state, 'function'): stat_func = viewer.state.function # Compute reduced data based on the current viewer's statistic # function. This doesn't seem particularly useful, but better # to be consistent. reduced_data = Data(x=value.data.compute_statistic( stat_func, value.data.id[xid], subset_state=value.subset_state, axis=1)) # Instantiate a new data collection since we need to compose # the collapsed data with the current subset state. We use a # new data collection so as not to inference with the one used # by the application. temp_data_collection = DataCollection() temp_data_collection.append(reduced_data) # Get the data id of the pixel axis that will be used in the # range composition. This is the wavelength axis for the new # 2d data. xid = reduced_data.pixel_component_ids[1] # Create a new subset group to hold our current subset state subset_group = temp_data_collection.new_subset_group( label=value.label, subset_state=value.subset_state) # Set the subset state axis to the wavelength pixel coordinate subset_group.subsets[0].subset_state.att = xid # Use the associated collapsed subset data to get an astropy # regions object dependent on the extends of the subset. # **Note** that the y values in this region object are not # useful, only the x values are. region = subset_group.subsets[0].data.get_selection_definition( format='astropy-regions') regions[key] = region return regions
def to_object(self, subset): """ Convert a glue Subset object to a astropy regions Region object. Parameters ---------- subset : `glue.core.subset.Subset` The subset to convert to a Region object """ data = subset.data if data.pixel_component_ids[0].axis == 0: x_pix_att = data.pixel_component_ids[1] y_pix_att = data.pixel_component_ids[0] else: x_pix_att = data.pixel_component_ids[0] y_pix_att = data.pixel_component_ids[1] subset_state = subset.subset_state if isinstance(subset_state, RoiSubsetState): roi = subset_state.roi if isinstance(roi, RectangularROI): xcen = 0.5 * (roi.xmin + roi.xmax) ycen = 0.5 * (roi.ymin + roi.ymax) width = roi.xmax - roi.xmin height = roi.ymax - roi.ymin return RectanglePixelRegion(PixCoord(xcen, ycen), width, height) elif isinstance(roi, PolygonalROI): return PolygonPixelRegion(PixCoord(roi.vx, roi.vy)) elif isinstance(roi, CircularROI): return CirclePixelRegion(PixCoord(*roi.get_center()), roi.get_radius()) elif isinstance(roi, EllipticalROI): return EllipsePixelRegion(PixCoord(roi.xc, roi.yc), roi.radius_x, roi.radius_y) elif isinstance(roi, PointROI): return PointPixelRegion(PixCoord(*roi.center())) elif isinstance(roi, RangeROI): return range_to_rect(data, roi.ori, roi.min, roi.max) elif isinstance(roi, AbstractMplRoi): temp_sub = Subset(data) temp_sub.subset_state = RoiSubsetState(x_pix_att, y_pix_att, roi.roi()) try: return self.to_object(temp_sub) except NotImplementedError: raise NotImplementedError( "ROIs of type {0} are not yet supported".format( roi.__class__.__name__)) else: raise NotImplementedError( "ROIs of type {0} are not yet supported".format( roi.__class__.__name__)) elif isinstance(subset_state, RangeSubsetState): if subset_state.att == x_pix_att: return range_to_rect(data, 'x', subset_state.lo, subset_state.hi) elif subset_state.att == y_pix_att: return range_to_rect(data, 'y', subset_state.lo, subset_state.hi) else: raise ValueError( 'Range subset state att should be either x or y pixel coordinate' ) elif isinstance(subset_state, MultiRangeSubsetState): if subset_state.att == x_pix_att: ori = 'x' elif subset_state.att == y_pix_att: ori = 'y' else: message = 'Multirange subset state att should be either x or y pixel coordinate' raise ValueError(message) if len(subset_state.pairs) == 0: message = 'Multirange subset state should contain at least one range' raise ValueError(message) region = range_to_rect(data, ori, subset_state.pairs[0][0], subset_state.pairs[0][1]) for pair in subset_state.pairs[1:]: region = region | range_to_rect(data, ori, pair[0], pair[1]) return region elif isinstance(subset_state, PixelSubsetState): return PointPixelRegion(PixCoord(*subset_state.get_xy(data, 1, 0))) elif isinstance(subset_state, AndState): temp_sub1 = Subset(data=data) temp_sub1.subset_state = subset_state.state1 temp_sub2 = Subset(data=data) temp_sub2.subset_state = subset_state.state2 return self.to_object(temp_sub1) & self.to_object(temp_sub2) elif isinstance(subset_state, OrState): temp_sub1 = Subset(data=data) temp_sub1.subset_state = subset_state.state1 temp_sub2 = Subset(data=data) temp_sub2.subset_state = subset_state.state2 return self.to_object(temp_sub1) | self.to_object(temp_sub2) elif isinstance(subset_state, XorState): temp_sub1 = Subset(data=data) temp_sub1.subset_state = subset_state.state1 temp_sub2 = Subset(data=data) temp_sub2.subset_state = subset_state.state2 return self.to_object(temp_sub1) ^ self.to_object(temp_sub2) elif isinstance(subset_state, MultiOrState): temp_sub = Subset(data=data) temp_sub.subset_state = subset_state.states[0] region = self.to_object(temp_sub) for state in subset_state.states[1:]: temp_sub.subset_state = state region = region | self.to_object(temp_sub) return region else: raise NotImplementedError( "Subset states of type {0} are not supported".format( subset_state.__class__.__name__))
def plot_labels(labels, save_dir=Path(''), loggers=None): # plot dataset labels print('Plotting labels... ') c, b = labels[:, 0], labels[:, 1:].transpose() # classes, boxes nc = int(c.max() + 1) # number of classes colors = color_list() x = pd.DataFrame(b.transpose(), columns=['x', 'y', 'width', 'height', 'angle']) # seaborn correlogram sns.pairplot(x, corner=True, diag_kind='auto', kind='hist', diag_kws=dict(bins=50), plot_kws=dict(pmax=0.9)) plt.savefig(save_dir / 'labels_correlogram.jpg', dpi=200) plt.close() # matplotlib labels matplotlib.use('svg') # faster ax = plt.subplots(5, 1, figsize=(4, 20), tight_layout=True)[1].ravel() ax[0].hist(c, bins=np.linspace(0, nc, nc + 1) - 0.5, rwidth=0.8) ax[0].set_xlabel('classes') sns.histplot(x, x='x', y='y', ax=ax[2], bins=50, pmax=0.9) sns.histplot(x, x='width', y='height', ax=ax[3], bins=50, pmax=0.9) sns.histplot(x, x='angle', ax=ax[4], bins=50, pmax=0.9) # rectangles labels[:, 1:3] = 0.5 # center labels[:, 1:5] = labels[:, 1:5] * 2000 img = Image.fromarray(np.ones((2000, 2000, 3), dtype=np.uint8) * 255) for cls, *box in labels[:1000]: x, y = int(box[0]), int(box[1]) width, height = int(box[2]), int(box[3]) angle = Angle(-int(180 * box[4] / np.pi), 'deg') center = PixCoord(x=x, y=y) reg = RectanglePixelRegion(center=center, width=width, height=height, angle=angle) patch = reg.as_artist() path = patch.get_path() vertices = path.vertices.copy() vertices = patch.get_patch_transform().transform(vertices) vertices = vertices.astype(int) vertices = tuple(i for i in zip(*vertices.T)) ImageDraw.Draw(img).polygon(vertices, outline=colors[int(cls) % 10]) # plot ax[1].imshow(img) ax[1].axis('off') for a in [0, 1, 2, 3, 4]: for s in ['top', 'right', 'left', 'bottom']: ax[a].spines[s].set_visible(False) plt.savefig(save_dir / 'labels.jpg', dpi=200) matplotlib.use('Agg') plt.close() # loggers for k, v in loggers.items() or {}: if k == 'wandb' and v: v.log({ "Labels": [ v.Image(str(x), caption=x.name) for x in save_dir.glob('*labels*.jpg') ] })