def findIntersect(inside_set): if (len(inside_set)==0): return [(0,0),(x_max,0),(x_max,y_max),(0,y_max),(0,0)] elif (len(inside_set)==1): #print "In 1" p1=Polygon(inside_set[0]) return list(p1.exterior.coords) elif (len(inside_set)==2): #print "In 2" p1=Polygon(inside_set[0]) p2=Polygon(inside_set[1]) #if (p1.intersection(p2).area !=0): #print p1.intersection(p2).area return list(p1.intersection(p2).exterior.coords) #else: # return ([]) else: #print "In >2" p1=Polygon(inside_set[0]) p2=Polygon(inside_set[1]) a=inside_set.pop(0) b=inside_set.pop(0) #if (p1.intersection(p2).area !=0): #print p1.intersection(p2).area #explain_validity(p1.intersection(p2)) inside_set.insert(0,list(p1.intersection(p2).exterior.coords)) return findIntersect(inside_set)
def main(): results = open('results.txt','w') parser = argparse.ArgumentParser(description='Runs text detector on relevant images at window level') parser.add_argument('classifier_file', help='Path to classifier CLF') parser.add_argument('-l', '--limit', type=int, metavar='COUNT', required=False, help='Maximum number of images to use') parser.add_argument('-r', '--random', action="store_true", default=False, required=False, help='Fetch images ordered randomly if limit is active') args = parser.parse_args() parameters["classifier_file"] = args.classifier_file parameters["evaluate_windows"] = True i = rigor.runner.Runner('text', parameters, limit=args.limit, random=args.random) results.write("threshold\timageid\texpected\tdetected\n") for cascade_threshold in (.5,): parameters['cascade_threshold'] = cascade_threshold for result in i.run(): image_id = result[0] detected = result[1] undetected = result[2] expected_blob = Polygon() for expected in result[3]: expected_blob = expected_blob.union(Polygon(expected)) for dbox in detected: box = Polygon(dbox) intersection = expected_blob.intersection(box) if intersection and (intersection.area / box.area) > parameters["minimum_percent_overlap"]: results.write("{}\t{}\t1\t1\t\n".format(cascade_threshold,image_id)) else: results.write("{}\t{}\t1\t0\t\n".format(cascade_threshold,image_id)) for dbox in undetected: box = Polygon(dbox) intersection = expected_blob.intersection(box) if intersection and (intersection.area / box.area) > parameters["minimum_percent_overlap"]: results.write("{}\t{}\t0\t1\t\n".format(cascade_threshold,image_id)) else: results.write("{}\t{}\t0\t0\t\n".format(cascade_threshold,image_id))
def test_polygon_line(): ''' intersection between polygon and line ''' #------------------------------------------------- # inclusion #------------------------------------------------- poly = Polygon([(0,0),(0,1),(1,1),(1,0)]) line = LineString([(0,0), (0.5,0.5)]) iline = poly.intersection(line) equal(np.sqrt(2)*0.5, iline.length) a_equal(line, np.array(iline.coords)) #------------------------------------------------- # partially #------------------------------------------------- poly = Polygon([(0,0),(0,1),(1,1),(1,0)]) line = LineString([(0.5,0.5),(1.5,1.5)]) iline = poly.intersection(line) equal(np.sqrt(2)*0.5, iline.length) a_equal(LineString([(0.5,0.5),(1,1)]), np.array(iline.coords)) #------------------------------------------------- # not intersection #------------------------------------------------- poly = Polygon([(0,0),(0,1),(1,1),(1,0)]) line = LineString([(1,1),(2,2)]) iline = poly.intersection(line) equal(0, iline.length)
def draw1dResults(self, ws1dNames, ws1dElevations, levees): # print 1d water elevation for pID in range(len(ws1dElevations)): pID+=1 off_z = pID*self.dz xmin = self.xmin[pID] xmax = self.xmax[pID] zmin = self.zmin[pID] zmax = self.zmax[pID] profilepoints = self.bottompoints[pID] #legend n = len(ws1dElevations[pID]) h = (n+1.0+(n-1)*0.5)*0.75*self.textheight_bandtitle dh = 0.75*self.textheight_bandtitle self.msp.add_line((xmin+dh, off_z+zmin+dh),(xmin+dh, off_z+zmin+h+dh), dxfattribs={'layer': 'frame'}) self.msp.add_line((xmin+self.off_band_x+dh, off_z+zmin+dh),(xmin+self.off_band_x+dh, off_z+zmin+h+dh), dxfattribs={'layer': 'frame'}) self.msp.add_line((xmin+dh, off_z+zmin+dh),(xmin+self.off_band_x+dh, off_z+zmin+dh), dxfattribs={'layer': 'frame'}) self.msp.add_line((xmin+dh, off_z+zmin+h+dh),(xmin+self.off_band_x+dh, off_z+zmin+h+dh), dxfattribs={'layer': 'frame'}) for wID in range(len(ws1dElevations[pID])): wsElevation = ws1dElevations[pID][wID] layerName = ws1dNames[wID] layerColor = 2+wID # legend self.msp.add_line((xmin+dh+dh, off_z+zmin+h-(wID+1+wID*0.5)*dh+dh),(xmin+dh+h+dh, off_z+zmin+h-(wID+1+wID*0.5)*dh+dh), dxfattribs={'layer': layerName, 'color':layerColor}) text_M = self.msp.add_text(ws1dNames[wID] +" = %.{0}f m".format(self.dec)%wsElevation, dxfattribs={'height': 0.75*self.textheight_bandtitle}) text_M.set_pos((xmin+dh+h+dh+dh, off_z+zmin+h-(wID+1+wID*0.5)*dh+dh), align='MIDDLE_LEFT') tup = tuple([(xmin-1.0,off_z+zmax*self.superelev)] + profilepoints + [(xmax+1.0,off_z+zmax*self.superelev)]) bottomLine = Polygon(tup) wsLine = LineString([(xmin, off_z+wsElevation*self.superelev), (xmax, off_z+wsElevation*self.superelev)]) inters = bottomLine.intersection(wsLine) if inters.geom_type == "LineString": self.msp.add_line((inters.coords[:][0][0], off_z+wsElevation*self.superelev), (inters.coords[:][1][0], off_z+wsElevation*self.superelev), dxfattribs={'layer': layerName, 'color':layerColor}) if inters.geom_type == "MultiLineString": for i in range(len(inters)): ls = inters[i] self.msp.add_line((ls.coords[:][0][0], off_z+wsElevation*self.superelev), (ls.coords[:][1][0], off_z+wsElevation*self.superelev), dxfattribs={'layer': layerName, 'color':layerColor}) # print levees if pID in levees: for lID in range(len(levees[pID])): levee_x = levees[pID][lID][0]*xmax levee_z = levees[pID][lID][1] bottomLine = LineString(tup) levee = LineString([(levee_x, off_z+zmin), (levee_x, off_z+zmax)]) inters = bottomLine.intersection(levee) self.msp.add_line((levee_x, inters.y), (levee_x, off_z+levee_z*self.superelev), dxfattribs={'layer': 'levee', 'color':1})
def make_dsw_dict_ll2cs(self): cs_obj = self.cs_obj ll_obj = self.ll_obj dsw_dict = dict() # {dst:[(s,w),(s,w),...],...} for dst, (rlat,rlon) in enumerate(cs_obj.latlons): #print dst dst_xy_vertices, vor_obj = cs_obj.get_voronoi(dst) dst_poly = Polygon(dst_xy_vertices) idx1, idx2, idx3, idx4 = ll_obj.get_surround_idxs(rlat, rlon) candidates = set([idx1, idx2, idx3, idx4]) if -1 in candidates: candidates.remove(-1) used_srcs = set() dsw_dict[dst] = list() while len(candidates) > 0: #print '\t', used_srcs src = candidates.pop() ll_vertices = ll_obj.get_voronoi(src) src_xy_vertices = [latlon2xyp(lat,lon,rlat,rlon)[1] \ for lat,lon in ll_vertices] src_poly = Polygon(src_xy_vertices) ipoly = dst_poly.intersection(src_poly) area_ratio = ipoly.area/dst_poly.area if area_ratio > 1e-10: dsw_dict[dst].append( (src, area_ratio) ) used_srcs.add(src) nbrs = set(ll_obj.get_neighbors(src)) candidates.update(nbrs - used_srcs) return dsw_dict
def nms_discard(self, proposal, accepted_detections, dataframe): p_idx = proposal[0] p_label = proposal[1].index[0] p_xmin = dataframe.iloc[p_idx]['xmin'] p_xmax = dataframe.iloc[p_idx]['xmax'] p_ymin = dataframe.iloc[p_idx]['ymin'] p_ymax = dataframe.iloc[p_idx]['ymax'] p_poly = Polygon([(p_xmin,p_ymin), (p_xmax,p_ymin), (p_xmax,p_ymax), (p_xmin, p_ymax)]) for detection in accepted_detections: detection = accepted_detections[detection] d_idx = detection[0] d_label = detection[1].index[0] if d_label != p_label: # No point checking if it isn't the same class of object continue else: d_xmin = dataframe.iloc[d_idx]['xmin'] d_xmax = dataframe.iloc[d_idx]['xmax'] d_ymin = dataframe.iloc[d_idx]['ymin'] d_ymax = dataframe.iloc[d_idx]['ymax'] d_poly = Polygon([(d_xmin,d_ymin), (d_xmax,d_ymin), (d_xmax,d_ymax), (d_xmin, d_ymax)]) intersection = p_poly.intersection(d_poly) union = p_poly.union(d_poly) if intersection.area / union.area > 0.3: return True break return False
def box3d_intersection(box_a, box_b): """ A simplified calculation of 3d bounding box intersection. It is assumed that the bounding box is only rotated around Z axis (yaw) from an axis-aligned box. :param box_a, box_b: obstacle bounding boxes for comparison :return: intersection volume (float) """ # height (Z) overlap min_h_a = np.min(box_a[2]) max_h_a = np.max(box_a[2]) min_h_b = np.min(box_b[2]) max_h_b = np.max(box_b[2]) max_of_min = np.max([min_h_a, min_h_b]) min_of_max = np.min([max_h_a, max_h_b]) z_intersection = np.max([0, min_of_max - max_of_min]) if z_intersection == 0: return 0. # oriented XY overlap xy_poly_a = Polygon(zip(*box_a[0:2, 0:4])) xy_poly_b = Polygon(zip(*box_b[0:2, 0:4])) xy_intersection = xy_poly_a.intersection(xy_poly_b).area if xy_intersection == 0: return 0. return z_intersection * xy_intersection
class CircularAdapter: def __init__(self, rotation, size, radius): self._rotation = rotation self._size = size self._radius = radius points = [(0, 0)] count = max(2, math.ceil(self._size * 16 / 360)) angle = math.radians(self._rotation - self._size/2) size = math.radians(self._size) for i in range(count+1): x = math.cos(angle + i/count * size) * self._radius y = math.sin(angle + i/count * size) * self._radius points.append((x, y)) self._shape = Polygon(points) @property def area(self): return self._shape.area def intersection(self, other): result = self._shape.intersection(other._shape) return CircularWrapper(result) def union(self, other): result = self._shape.union(other._shape) return CircularWrapper(result) def distance(self, other): dist_a = (self._rotation - other._rotation) % 360 dist_b = (other._rotation - self._rotation) % 360 dist = min(dist_a, dist_b) - (self._size + other._size) / 2 return max(0, dist)
def partition(self): partition_by_station_dict = dict() population_by_station_dict = dict() station_coordinates = [] for station in self.stations.values(): station_coordinates.append([station.lon, station.lat]) points = np.array(station_coordinates) partitions = Voronoi(points) regions, vertices = LoadEstimator.voronoi_finite_polygons_2d(partitions) polygons = [] for region in regions: vertices_coordinates = [] for vertice_index in region: vertices_coordinates.append((vertices[vertice_index][0], vertices[vertice_index][1])) vertices_coordinates.append(vertices_coordinates[0]) partition_polygon = Polygon(vertices_coordinates) polygons.append(partition_polygon) for station in self.stations.values(): if Point(station.lon, station.lat).within(partition_polygon): partition_by_station_dict[str(station.id)] = partition_polygon.intersection(self.boundary) population_of_region = self.population_of_region(partition_polygon) self.root.info('Region of station %s has %s people', str(station.id), str(population_of_region)) population_by_station_dict[str(station.id)] = population_of_region break return partition_by_station_dict, population_by_station_dict
def iou_bbox_with_yaw(vol_a, box_a, vol_b, box_b): """ A simplified calculation of 3d bounding box intersection over union. It is assumed that the bounding box is only rotated around Z axis (yaw) from an axis-aligned box. :param vol_a, vol_b: precalculated obstacle volumes for comparison :param box_a, box_b: obstacle bounding boxes for comparison :return: iou float, intersection volume float """ # height (Z) overlap min_h_a = np.min(box_a[2]) max_h_a = np.max(box_a[2]) min_h_b = np.min(box_b[2]) max_h_b = np.max(box_b[2]) max_of_min = np.max([min_h_a, min_h_b]) min_of_max = np.min([max_h_a, max_h_b]) z_intersection = np.max([0, min_of_max - max_of_min]) if z_intersection == 0: return 0., 0. # oriented XY overlap xy_poly_a = Polygon(zip(*box_a[0:2, 0:4])) xy_poly_b = Polygon(zip(*box_b[0:2, 0:4])) xy_intersection = xy_poly_a.intersection(xy_poly_b).area if xy_intersection == 0: return 0., 0. intersection = z_intersection * xy_intersection union = vol_a + vol_b - intersection iou = intersection / union return iou, intersection
def compare_location_results(expected, found): true_positive = 0 false_positive = 0 false_negative = 0 ambiguous = 0 paired = [False]*len(found) for e in expected: p1=Polygon(reshape_list(e)) total_matched = 0 for idx,f in enumerate(found): p2=Polygon(reshape_list(f)) try: x = p1.intersection(p2) if x.area/p1.area > 0.1: paired[idx] = True total_matched += 1 true_positive += 1 except: pass # not sure what to do here if total_matched == 0: false_negative += 1 elif total_matched > 1: ambiguous += 1 for idx in range(len(found)): if not paired[idx]: false_positive += 1 return {"tp":true_positive,"fp":false_positive,"fn":false_negative,"ambiguous":ambiguous}
def padded_extent_to_shp( rst1, rst2, npixels, crs, output_shapefile ): ''' convert the extents of 2 overlapping rasters to a shapefile with an expansion of the intersection of the rasters extents by npixels rst1: rasterio raster object rst2: rasterio raster object npixels: tuple of 4 (left(-),bottom(-),right(+),top(+)) number of pixels to expand in each direction. for 5 pixels in each direction it would look like this: (-5. -5. 5, 5) or just in the right and top directions like this: (0,0,5,5). crs: epsg code or proj4string defining the geospatial reference system output_shapefile: string full path to the newly created output shapefile ''' import rasterio, os, sys from shapely.geometry import Polygon # rst to pols resolution = rst1.res[0] ext1 = bounds_to_extent( rst1.bounds ) ext2 = bounds_to_extent( rst2.bounds ) pol1 = Polygon( ext1 ) pol2 = Polygon( ext2 ) isect_ext_pol = pol1.intersection( pol2 ) new_bounds = [ bound+(expand*resolution) for bound, expand in zip( isect_ext_pol.bounds, npixels ) ] new_ext = bounds_to_extent( new_bounds ) return extent_to_shapefile( new_ext, output_shapefile, crs )
def normalize_footprint(footprint: List[Tuple[float, float]]) -> MultiPolygon: """Split footprints which cross the anti-meridian Most applications, including RasterFoundry, cannot handle a single polygon representation of anti-meridian crossing footprint. Normalizing footprints by splitting them over the anti-meridian fixes cases where scenes appear to span all longitudes outside their actual footprint. If a footprint covers the anti-meridian, the shape is shifted 360 degrees, split, then the split section is moved back. """ intersects = intersects_antimeridian(footprint) if not intersects: return MultiPolygon([Polygon(footprint)]) else: shifted_footprint = Polygon([shift_point(p, 0, Side.RIGHT, False, 360) for p in footprint]) left_hemisphere_mask = Polygon([(0, -90), (180, -90), (180, 90), (0, 90), (0, -90)]) left_split = shifted_footprint.intersection(left_hemisphere_mask) right_split = Polygon([ shift_point((x, y), 180, Side.LEFT, True, -360) for x, y in shifted_footprint.difference(left_hemisphere_mask).exterior.coords ]) if left_split.area > 0 and right_split.area > 0: return MultiPolygon([left_split, right_split]) elif left_split.area > 0: return MultiPolygon([left_split]) elif right_split.area > 0: return MultiPolygon([right_split]) else: return MultiPolygon([])
def intersect_line_polygon_shapely(line, vertices): """ Intersect a line segment with a polygon. INPUT: - ``line`` -- list of two points - ``vertices`` -- vertices of the polygon OUTPUT: Returns a numpy array of shape (2,). """ def in_line(p): for q in line: if abs(p[0] - q[0]) < 1e-5 and abs(p[1] - q[1]) < 1e-5: return True return False s_polygon = ShapelyPolygon(vertices) s_line = ShapelyLineString(line) try: coords = (array(p) for p in s_polygon.intersection(s_line).coords) coords = [p for p in coords if not in_line(p)] except NotImplementedError: coords = [] return coords
def decompose_further(cell_node): cell_polygon = Polygon(cell_node.polygon) coords = get_coords(cell_polygon) start_line = get_start_line(cell_polygon) end_line = get_end_line(cell_polygon) sorted_indices = sort_indices(coords, start_line) trap_nodes = [] for index in sorted_indices: point = Point(coords[index]) box = start_line.union(point).envelope new_polygon = box.intersection(cell_polygon) if isinstance(new_polygon, Polygon): trap_node = TrapNode(new_polygon, parent=cell_node) cell_node.add_child(trap_node) trap_nodes.append(trap_node) elif isinstance(new_polygon, GeometryCollection) or isinstance(new_polygon, MultiPolygon): for item in new_polygon: if isinstance(item, Polygon): trap_node = TrapNode(item, parent=cell_node) cell_node.add_child(trap_node) trap_nodes.append(trap_node) remainder_box = end_line.union(point).envelope cell_polygon = cell_polygon.intersection(remainder_box) return trap_nodes
def get_intersection(coords): """Given an input list of coordinates, find the intersection section of corner coordinates. Returns geojson of the interesection polygon. """ ipoly = None for coord in coords: if ipoly is None: ipoly = Polygon(coord) else: tmp = Polygon(coord) ipoly = ipoly.intersection(tmp) # close the polygon loop by adding the first coordinate again first_x = ipoly.exterior.coords.xy[0][0] first_y = ipoly.exterior.coords.xy[1][0] ipoly.exterior.coords.xy[0].append(first_x) ipoly.exterior.coords.xy[1].append(first_y) inter_coords = zip( ipoly.exterior.coords.xy[0], ipoly.exterior.coords.xy[1]) inter_gj = {"geometry": {"coordinates": [inter_coords], "type": "Polygon"}, "properties": {}, "type": "Feature"} return inter_gj, inter_coords
def poly(polygon_, bm=None, name="Polygon"): """ flattens polygons with holes to a mesh with only faces """ # bmesh management nolink = False if bm == None: bm = bmesh.new() else: nolink = True if len(polygon_.interiors) > 0: # find area between inner rings inner = polygon_.interiors[0] for i in range(1, len(polygon_.interiors)): inner = MultiPolygon([Polygon(inner),Polygon(polygon_.interiors[i])]) ch = inner.convex_hull bridge = ch.difference(inner) coords(bridge.exterior.coords, "FACE", bm) inner = ch.exterior # create two sides around all the interiors pb = polygon_.bounds triangle = Polygon((pb[:2],pb[2:],(pb[0],pb[3]))) donut = Polygon(polygon_.exterior.coords, [inner.coords]) half1 = donut.intersection(triangle) half2 = donut.difference(triangle) coords(half1.exterior.coords, "FACE", bm) coords(half2.exterior.coords, "FACE", bm) else: coords(polygon_.exterior.coords, "FACE", bm) if not nolink: link(bm, name)
def compute_voronoi(keypoints, intersection=None, geometry=False, s=30): # ADDED """ Creates a voronoi diagram for all edges in a graph, and assigns a given weight to each edge. This is based around voronoi polygons generated by scipy's voronoi method, to determine if an image has significant coverage. Parameters ---------- graph : object A networkx graph object clean_keys : list Of strings used to apply masks to omit correspondences s : int Offset for the corners of the image """ vor_keypoints = [] keypoints.apply(lambda x: vor_keypoints.append((x['x'], x['y'])), axis = 1) if intersection is None: keypoint_bounds = Polygon(vor_keypoints).bounds intersection = shapely.geometry.box(keypoint_bounds[0], keypoint_bounds[1], keypoint_bounds[2], keypoint_bounds[3]) scaled_coords = np.array(scale(intersection, s, s).exterior.coords) vor_keypoints = np.vstack((vor_keypoints, scaled_coords)) vor = Voronoi(vor_keypoints) # Might move the code below to its own method depending on feedback if geometry: voronoi_df = gpd.GeoDataFrame(data = keypoints, columns=['x', 'y', 'weight', 'geometry']) else: voronoi_df = gpd.GeoDataFrame(data = keypoints, columns=['x', 'y', 'weight']) i = 0 vor_points = np.asarray(vor.points) for region in vor.regions: region_point = vor_points[np.argwhere(vor.point_region==i)] if not -1 in region: polygon_points = [vor.vertices[i] for i in region] if len(polygon_points) != 0: polygon = Polygon(polygon_points) intersection_poly = polygon.intersection(intersection) voronoi_df.loc[(voronoi_df["x"] == region_point[0][0][0]) & (voronoi_df["y"] == region_point[0][0][1]), 'weight'] = intersection_poly.area if geometry: voronoi_df.loc[(voronoi_df["x"] == region_point[0][0][0]) & (voronoi_df["y"] == region_point[0][0][1]), 'geometry'] = intersection_poly i += 1 return voronoi_df
def findIntersect(inside_set): if (len(inside_set)==0): return [(0,0),(x_max,0),(x_max,y_max),(0,y_max),(0,0)] elif (len(inside_set)==1): p1=Polygon(inside_set[0]) return list(p1.exterior.coords) elif (len(inside_set)==2): p1=Polygon(inside_set[0]) p2=Polygon(inside_set[1]) return list(p1.intersection(p2).exterior.coords) else: p1=Polygon(inside_set[0]) p2=Polygon(inside_set[1]) a=inside_set.pop(0) b=inside_set.pop(0) inside_set.insert(0,list(p1.intersection(p2).exterior.coords)) return findIntersect(inside_set)
def extract(mergedPopulationFile, mappedSiteFile, intersectionFile): PopulationXML = ET.ElementTree(file=mergedPopulationFile) EvacuationXML = ET.ElementTree(file=mappedSiteFile) PopRoot = PopulationXML.getroot() EvaRoot = EvacuationXML.getroot() Schnittmenge = [] for evaArea in EvaRoot.findall("./poly[0]"): koordinatenStr = evaArea.attrib["shape"] koordinatenList = [tuple(map(float, x.split(','))) for x in koordinatenStr.split()] evacuationArea = Polygon(koordinatenList) for PopArea in PopRoot.findall("./poly"): koordinatenStr = PopArea.attrib["shape"] koordinatenList = [tuple(map(float, x.split(','))) for x in koordinatenStr.split()] Gemeinde = Polygon(koordinatenList) if Gemeinde.intersection(evacuationArea): for Inhab in PopArea.findall("./param"): if Inhab.attrib["key"] == "INHABITANTS": Einwohner = int((Inhab.attrib["value"])) Einwohner *= Gemeinde.intersection( evacuationArea).area / Gemeinde.area Einwohner = str(Einwohner) Schnittmenge.append( (Gemeinde.intersection(evacuationArea), Einwohner)) print("merge!") root = ET.Element('additional') ET.ElementTree(root) i = 1 for G in Schnittmenge: poly = ET.SubElement(root, 'poly') exterior = G[0].exterior.coords OutExterior = '' for elem in exterior: OutExterior += str(elem[0]) + "," + str(elem[1]) + " " identity = "Schnittflache" + str(i) poly.attrib = { "id": identity, "shape": OutExterior, "inhabitants": G[1]} i += 1 outstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ") with open(intersectionFile, 'w') as out: out.write(outstr)
def quarter_polygon(geom_poly): #https://pcjericks.github.io/py-gdalogr-cookbook/geometry.html#quarter-polygon-and-create-centroids (min_x, min_y, max_x, max_y) = geom_poly.bounds ''' coord0----coord1----coord2 | | | coord3----coord4----coord5 | | | coord6----coord7----coord8 ''' coord0 = min_x, max_y coord1 = min_x+(max_x-min_x)/2, max_y coord2 = max_x, max_y coord3 = min_x, min_y+(max_y-min_y)/2 coord4 = min_x+(max_x-min_x)/2, min_y+(max_y-min_y)/2 coord5 = max_x, min_y+(max_y-min_y)/2 coord6 = min_x, min_y coord7 = min_x+(max_x-min_x)/2, min_y coord8 = max_x, min_y polyTopLeft = Polygon([coord0,coord1,coord4,coord3,coord0]) polyTopRight = Polygon([coord1,coord2,coord5,coord4,coord1]) polyBottomLeft = Polygon([coord3,coord4,coord7,coord6,coord3]) polyBottomRight = Polygon([coord4,coord5,coord8,coord7,coord4]) quarterPolyTopLeft = polyTopLeft.intersection(geom_poly) quarterPolyTopRight = polyTopRight.intersection(geom_poly) quarterPolyBottomLeft = polyBottomLeft.intersection(geom_poly) quarterPolyBottomRight = polyBottomRight.intersection(geom_poly) multipolys = [quarterPolyTopLeft, quarterPolyTopRight, quarterPolyBottomLeft, quarterPolyBottomRight] polys = [] for geom in multipolys: if geom.geom_type in ['MultiPolygon', 'GeometryCollection'] : for geom_part in geom: if geom_part.geom_type == 'Polygon': polys.append(geom_part) else: polys.append(geom) return polys
def main(): results = open("results.txt", "w") parser = argparse.ArgumentParser(description="Runs text detector on relevant images") parser.add_argument("classifier_file", help="Path to classifier CLF") parser.add_argument( "-l", "--limit", type=int, metavar="COUNT", required=False, help="Maximum number of images to use" ) parser.add_argument( "-r", "--random", action="store_true", default=False, required=False, help="Fetch images ordered randomly if limit is active", ) args = parser.parse_args() parameters["classifier_file"] = args.classifier_file # database_mapper = DatabaseMapper(Database.instance()) # unused!? results.write("threshold\texpected\tdetected\texpected_box\tdetected_box\n") # for cascade_threshold in (.1,.2,.3,.4,.5,.6,.7,.8,.9): for cascade_threshold in (0.5, 0.6): parameters["cascade_threshold"] = cascade_threshold i = rigor.runner.Runner("text", parameters, limit=args.limit, random=args.random) for result in i.run(): detected = result[1] expected = result[2] for ebox in expected: expected_box = Polygon(ebox) closest_detected = None closest_intersection = None closest_distance = None # find the closest/most overlapping from detected for dbox in detected: detected_box = Polygon(dbox) intersection = detected_box.intersection(expected_box) if intersection: distance = detected_box.centroid.distance(expected_box.centroid) if distance < closest_distance or not closest_distance: closest_detected = dbox closest_intersection = intersection closest_distance = detected_box.centroid.distance(expected_box.centroid) # if found, print out as hit, remove from expected and detected if closest_detected: results.write( "{}\t1\t1\t{}\t{}\n".format(cascade_threshold, expected_box, Polygon(closest_detected)) ) detected.remove(closest_detected) # if not found, print out as false negative else: results.write("{}\t1\t0\t{}\t{}\n".format(cascade_threshold, expected_box, None)) for bbox in detected: # detected should be pruned by now, so these are all false positives results.write("{}\t0\t1\t{}\t{}\n".format(cascade_threshold, None, Polygon(bbox)))
def overlaps(points1, points2): print 'points1',points1 print 'points2',points2 from shapely.geometry import Polygon overlap_area = 0 polygon1 = Polygon(points1) polygon2 = Polygon(points2) overlap_area = polygon1.intersection(polygon2).area print "overlap: ", overlap_area print 'epsilon ', epsilon return overlap_area > epsilon
def calcCurveErr(workspace,poly,mean,sigma,level): # see: http://toblerity.org/shapely/manual.html boundaryestimate = getLevelSet (workspace, mean, level) # GroundTruth = np.vstack((poly,poly[0])) GroundTruth=Polygon(GroundTruth) boundaryestimate=Polygon(boundaryestimate) mislabeled=boundaryestimate.symmetric_difference(GroundTruth) # mislabeled data () boundaryestimate.difference(GroundTruth) #mislabeled as tumor--extra that would be removed GroundTruth.difference(boundaryestimate) # mislbaled as not-tumor--would be missed and should be cut out correct=boundaryestimate.intersection(GroundTruth) #correctly labeled as tumor return correct.area, mislabeled.area
def getIntersection(self,polygonA,B,R,plot=False): if not SHAPELY: sys.exit("unable to compute intersections without shapely package") if(len(B) < 3): return polygonA RB = (B*R) polygonB = Polygon([(RB[i,0],RB[i,2]) for i in range(4)]) intersection = polygonA-polygonB.intersection(polygonA) if(plot): plotIntersections(polygonA,polygonB,intersection) return intersection
def get_useful_building_list(community_border_list, building_border): # community_border_list 转换为 polygon 的对象 tmp = [] for i in community_border_list: tmp.append([i[0],i[1]]) community_polygon_obj = Polygon(tmp) # ============= center_lng = list(community_polygon_obj.centroid.coords)[0][0] center_lat = list(community_polygon_obj.centroid.coords)[0][1] tmp_building_border = building_border[(building_border['point_lat']<center_lat+0.02)& (building_border['point_lat']>center_lat-0.02)& (building_border['point_lng']<center_lng+0.02)& (building_border['point_lng']>center_lng-0.02)] # ============= useful_building_list = [] # len_buildings = len(tmp_building_border) num = 0 building_coverage_area = 0 building_plot_area = 0 for index,row in tmp_building_border.iterrows(): num += 1 # print (str(num)+'/'+str(len_buildings)) p_list = row[3] p_floor = row[1] building_polygon_obj = Polygon(p_list) point_lng = list(building_polygon_obj.centroid.coords)[0][0] point_lat = list(building_polygon_obj.centroid.coords)[0][1] p_point = Point([point_lng,point_lat]) # 建筑物中心点落在小区内,同时建筑物在小区内的面积占建筑物面积的百分之五十以上的,记录下来 try: if community_polygon_obj.contains(p_point) and community_polygon_obj.intersection(building_polygon_obj).area / building_polygon_obj.area > 0.5: useful_building_list.append([p_floor,p_list]) building_coverage_area += building_polygon_obj.area building_plot_area += building_polygon_obj.area * p_floor except TopologicalError: pass # 小区建筑覆盖率低于 0.05 的直接排除 # plot ratio # coverage ratio coverage_ratio = building_coverage_area / community_polygon_obj.area plot_ratio = building_plot_area / community_polygon_obj.area if coverage_ratio < 0.1 or len(useful_building_list) < 2: useful_building_list = [] elif plot_ratio < 1: if len(useful_building_list) < 20: useful_building_list = [] return coverage_ratio, plot_ratio, useful_building_list
def ploy_overlap(gt, pred): gt_pts = [(gt[i], gt[i + 1]) for i in range(0, len(gt), 2)] gt_poly = Polygon(gt_pts) gt_area = gt_poly.area pred_pts = [(pred[i], pred[i + 1]) for i in range(0, len(pred), 2)] pred_poly = Polygon(pred_pts) pred_area = pred_poly.area intersection = gt_poly.intersection(pred_poly).area iou = intersection / (gt_area + pred_area - intersection) if math.isnan(iou): iou = 0 return iou
def estimate_object_by_countor(self, contour): if type(contour) is bool: return area = cv2.contourArea(contour) current_rect = cv2.minAreaRect(contour) current_box = cv2.cv.BoxPoints(current_rect) (vx, vy), (x, y), angle = current_rect prvs_rect = cv2.minAreaRect(self.tracking_data_list[0].get('contour')) prvs_box = cv2.cv.BoxPoints(prvs_rect) p1 = Polygon(prvs_box) p2 = Polygon(current_box) overlap_ratio = p1.intersection(p2).area/(p1.area + p2.area - p1.intersection(p2).area) image_ratio = (x * y)/(self.frame_width*self.frame_height) if self.debug: print('area: %d, angle: %f, y/x: %f, overlap_ratio: %f'%(area, abs(angle), float(y)/float(x), overlap_ratio)) if (area > 600 and image_ratio < 0.9): return True else: return False
def find_free_position(self, polygon, number=10, step=5): ''' Checks for collisions with self.conflict_area and in case returns nearest x, y coord-tuple (minx, miny) where the given polygon does not collide with self.conflict_area. Only tries to move polygon a certain times and returns None if no free position could be found. :param polygon: :class:`shapely.geometry.Polygon` :param number: the number of movements as int or float :param step: int or float specifying the step which the polygon is moved at each iteration ''' number += 1 x, y = polygon.bounds[:2] # list containing all "visited" bounds prev_bounds = [] shifts = ((step, 0), (0, step), (-step, 0), (0, -step)) for _ in xrange(number): minx, miny, maxx, maxy = polygon.bounds # only shift if cur area does not collide with self.area # and is within visual map if ( polygon.within(self.map_area) and polygon.intersection(self.conflict_area).area == 0 ): return x, y cur_area = polygon.intersection(self.conflict_area).area bestdx = bestdy = 0 best_polygon = polygon #: shift polygon in all directions and search for minimum intersection for dx, dy in shifts: coords = utils.translate_coords(polygon.exterior.coords, dx, dy) shifted = Polygon(tuple(coords)) minx, miny, maxx, maxy = shifted.bounds # position already "visited" or not within visual map if shifted.bounds in prev_bounds or not shifted.within(self.map_area): continue shifted_area = shifted.intersection(self.conflict_area).area if shifted_area <= cur_area: best_polygon = shifted cur_area = shifted_area bestdx, bestdy = dx, dy polygon = best_polygon x += bestdx y += bestdy prev_bounds.append(polygon.bounds)
def localizationAccuracy(truth, pred): truth = Polygon(truth) pred = Polygon(pred) inter = truth.intersection(pred) union = truth.union(pred) lr = inter.area / union.area print '' print 'tr points -> {0}'.format(truth) print 'pr points -> {0}'.format(pred) print '' print 'inter {0}'.format(inter.area) print 'union {0}'.format(union.area) print 'IR {0}'.format(lr) print '' return lr
poly1 = Polygon(a).convex_hull #python四边形对象,会自动计算四个点,最后四个点顺序为:左上 左下 右下 右上 左上 print(Polygon(a).convex_hull) #可以打印看看是不是这样子 line2=[923,308,758,342,741,262,907,228] b=np.array(line2).reshape(4, 2) poly2 = Polygon(b).convex_hull print(Polygon(b).convex_hull) union_poly = np.concatenate((a,b)) #合并两个box坐标,变为8*2 #print(union_poly) print(MultiPoint(union_poly).convex_hull) #包含两四边形最小的多边形点 if not poly1.intersects(poly2): #如果两四边形不相交 iou = 0 else: try: inter_area = poly1.intersection(poly2).area #相交面积 print(inter_area) #union_area = poly1.area + poly2.area - inter_area union_area = MultiPoint(union_poly).convex_hull.area print(union_area) if union_area == 0: iou= 0 #iou = float(inter_area) / (union_area-inter_area) #错了 iou=float(inter_area) / union_area # iou=float(inter_area) /(poly1.area+poly2.area-inter_area) # 源码中给出了两种IOU计算方式,第一种计算的是: 交集部分/包含两个四边形最小多边形的面积 # 第二种: 交集 / 并集(常见矩形框IOU计算方式) except shapely.geos.TopologicalError: print('shapely.geos.TopologicalError occured, iou set to 0') iou = 0
Line((width + height * 1j) * px_to_cm / 2, -(width - height * 1j) * px_to_cm / 2) ] bounding_box = Polygon([[p.start.real, p.start.imag] for p in bounds_lines]) for element in tiling.elements: points = [element.A, element.B, element.C, element.D] points = [point * scale_factor for point in points] center_point = average(points) new_points = [ margins * point + (1 - margins) * center_point for point in points ] element_poly = Polygon([[p.real, p.imag] for p in new_points]) test_shape = bounding_box.intersection(element_poly) if test_shape.is_empty: continue x, y = test_shape.exterior.coords.xy new_points = [x[i] + y[i] * 1j for i in range(len(x))] path_string += "M {} {}".format(new_points[0].real, new_points[0].imag) for point in new_points[1:] + new_points[:1]: path_string += "L {} {}".format(point.real, point.imag) margins = 1 x_min = width / 2 + margins y_min = -height * 2 + margins y_max = y_min + height * 2 + margins * 4
def project_extents(extents, src_proj, dest_proj, tol=1e-6): x1, y1, x2, y2 = extents if (isinstance(src_proj, ccrs.PlateCarree) and not isinstance(dest_proj, ccrs.PlateCarree) and src_proj.proj4_params['lon_0'] != 0): xoffset = src_proj.proj4_params['lon_0'] x1 = x1 - xoffset x2 = x2 - xoffset src_proj = ccrs.PlateCarree() # Limit latitudes cy1, cy2 = src_proj.y_limits if y1 < cy1: y1 = cy1 if y2 > cy2: y2 = cy2 # Offset with tolerances x1 += tol x2 -= tol y1 += tol y2 -= tol # Wrap longitudes cx1, cx2 = src_proj.x_limits if isinstance(src_proj, ccrs._CylindricalProjection): lons = wrap_lons(np.linspace(x1, x2, 10000), -180., 360.) x1, x2 = lons.min(), lons.max() else: if x1 < cx1: x1 = cx1 if x2 > cx2: x2 = cx2 domain_in_src_proj = Polygon([[x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]]) boundary_poly = Polygon(src_proj.boundary) dest_poly = src_proj.project_geometry(Polygon(dest_proj.boundary), dest_proj).buffer(0) if src_proj != dest_proj: # Erode boundary by threshold to avoid transform issues. # This is a workaround for numerical issues at the boundary. eroded_boundary = boundary_poly.buffer(-src_proj.threshold) geom_in_src_proj = eroded_boundary.intersection( domain_in_src_proj) try: geom_clipped_to_dest_proj = dest_poly.intersection( geom_in_src_proj) except: geom_clipped_to_dest_proj = None if geom_clipped_to_dest_proj: geom_in_src_proj = geom_clipped_to_dest_proj try: geom_in_crs = dest_proj.project_geometry(geom_in_src_proj, src_proj) except ValueError: src_name =type(src_proj).__name__ dest_name =type(dest_proj).__name__ raise ValueError('Could not project data from %s projection ' 'to %s projection. Ensure the coordinate ' 'reference system (crs) matches your data ' 'and the kdims.' % (src_name, dest_name)) else: geom_in_crs = boundary_poly.intersection(domain_in_src_proj) return geom_in_crs.bounds
def __call__(self, img, boxes, segments, labels): ''' apply transform when calling :param img: numpy.ndarray,(h,w,c) :param boxes: numpy.ndarray,(n,4), x1,y1,x2,y2 :param segments: list(list),(n)(x),x is variant :param labels: numpy.ndarray,(n) :return: ''' h, w, c = img.shape while True: mode = random.choice(self.sample_mode) if mode == 1: return img, boxes, segments, labels min_iou = mode for i in range(50): new_w = random.uniform(self.min_crop_size * w, w) new_h = random.uniform(self.min_crop_size * h, h) # h / w in [0.5, 2] if new_h / new_w < 0.5 or new_h / new_w > 2: continue left = random.uniform(w - new_w) top = random.uniform(h - new_h) patch = np.array( (int(left), int(top), int(left + new_w), int(top + new_h))) overlaps = bbox_overlaps(patch.reshape(-1, 4), boxes.reshape(-1, 4)).reshape(-1) if overlaps.min() < min_iou: continue # center of boxes should inside the crop img center = (boxes[:, :2] + boxes[:, 2:]) / 2 mask = (center[:, 0] > patch[0]) * ( center[:, 1] > patch[1]) * (center[:, 0] < patch[2]) * ( center[:, 1] < patch[3]) if not mask.any(): continue # adjust boxes img = img[patch[1]:patch[3], patch[0]:patch[2]] # box here is not valid enough # we shound use mask to generate the new box # boxes[:, 2:] = boxes[:, 2:].clip(max=patch[2:]) # boxes[:, :2] = boxes[:, :2].clip(min=patch[:2]) # boxes -= np.tile(patch[:2], 2) boxes = [] out_segments = [] out_labels = [] for j, segment in enumerate(segments): if not mask[j]: continue segment = np.array(segment).reshape(-1, 2) segment = Polygon(segment) bound = patch.copy() bound = bound + np.array([1, 1, -1, -1]) bound = np.vstack((bound[[0, 2, 2, 0]], bound[[1, 1, 3, 3]])).transpose() bound = Polygon(bound) segment = bound.intersection(segment) try: segment = np.array(segment.exterior.coords) except Exception as e: print(e) continue segment -= patch[:2] x1, y1 = np.min(segment, 0) x2, y2 = np.max(segment, 0) boxes.append([x1, y1, x2, y2]) out_labels.append(labels[j]) out_segments.append(list(segment.reshape(-1))) boxes = np.array(boxes).astype(np.int32) return img, boxes, out_segments, np.array(out_labels)
# -*- coding: utf-8 -*- """ Created on Sat Jan 4 10:41:21 2020 @author: alber """ import pandas as pd from shapely.geometry import Polygon polygon = Polygon([(3, 3), (5, 3), (5, 5), (3, 5)]) other_polygon = Polygon([(1, 1), (4, 1), (4, 3.5), (1, 3.5)]) intersection = polygon.intersection(other_polygon) print(intersection.area) p = Polygon([[1,1,1],[2,1,1],[2,2,1],[2,1,2], [2,2,2],[1,2,2],[1,2,1],[1,1,2]]) q = Polygon([[2.5,1.5,2.5],[2.5,2.5,2.5],[1.5,1.5,2.5],[1.5,2.5,2.5], [1.5,1.5,1.5],[1.5,2.5,1.5],[2.5,2.5,1.5],[2.5,1.5,1.5]]) intersection = p.intersection(q) print(intersection.area) polygon = Polygon([(1, 1), (2, 1), (2, 2), (1, 2)]) other_polygon = Polygon([(1.5, 1.5), (3, 1.5), (1.5, 0.5), (1.5, 0.5)]) intersection = polygon.intersection(other_polygon) print(intersection.area)
def draw_field(camera): field_points2d = project_field_to_image(camera) h, w = camera.height, camera.width # Check if the entities are 15 assert len(field_points2d) == 15 img_polygon = Polygon([(0, 0), (w - 1, 0), (w - 1, h - 1), (0, h - 1)]) canvas = np.zeros((h, w, 3), dtype=np.uint8) mask = np.zeros((h, w, 3), dtype=np.uint8) # Draw the boxes for i in range(3): # And make a new image with the projected field linea = LineString([(field_points2d[i][0, :]), (field_points2d[i][1, :])]) lineb = LineString([(field_points2d[i][1, :]), (field_points2d[i][2, :])]) linec = LineString([(field_points2d[i][2, :]), (field_points2d[i][3, :])]) lined = LineString([(field_points2d[i][3, :]), (field_points2d[i][0, :])]) if i == 0: polygon0 = Polygon([(field_points2d[i][0, :]), (field_points2d[i][1, :]), (field_points2d[i][2, :]), (field_points2d[i][3, :])]) intersect0 = img_polygon.intersection(polygon0) if not intersect0.is_empty: pts = np.array(list(intersect0.exterior.coords), dtype=np.int32) pts = pts[:, :].reshape((-1, 1, 2)) cv2.fillConvexPoly(mask, pts, (255, 255, 255)) intersect0 = img_polygon.intersection(linea) if not intersect0.is_empty: pts = np.array(list(list(intersect0.coords)), dtype=np.int32) if pts.shape[0] < 2: continue cv2.line(canvas, (pts[0, 0], pts[0, 1]), (pts[1, 0], pts[1, 1]), (255, 255, 255)) intersect0 = img_polygon.intersection(lineb) if not intersect0.is_empty: pts = np.array(list(list(intersect0.coords)), dtype=np.int32) if pts.shape[0] < 2: continue cv2.line(canvas, (pts[0, 0], pts[0, 1]), (pts[1, 0], pts[1, 1]), (255, 255, 255)) intersect0 = img_polygon.intersection(linec) if not intersect0.is_empty: pts = np.array(list(list(intersect0.coords)), dtype=np.int32) if pts.shape[0] < 2: continue cv2.line(canvas, (pts[0, 0], pts[0, 1]), (pts[1, 0], pts[1, 1]), (255, 255, 255)) intersect0 = img_polygon.intersection(lined) if not intersect0.is_empty: pts = np.array(list(list(intersect0.coords)), dtype=np.int32) if pts.shape[0] < 2: continue cv2.line(canvas, (pts[0, 0], pts[0, 1]), (pts[1, 0], pts[1, 1]), (255, 255, 255)) # lines for i in range(3, 8): line1 = LineString([(field_points2d[i][0, :]), (field_points2d[i][1, :])]) intersect1 = img_polygon.intersection(line1) if not intersect1.is_empty: pts = np.array(list(list(intersect1.coords)), dtype=np.int32) pts = pts[:, :].reshape((-1, 1, 2)) cv2.fillConvexPoly( canvas, pts, (255, 255, 255), ) # Circles for ii in range(8, 15): for i in range(field_points2d[ii].shape[0] - 1): line2 = LineString([(field_points2d[ii][i, :]), (field_points2d[ii][i + 1, :])]) intersect2 = img_polygon.intersection(line2) if not intersect2.is_empty: pts = np.array(list(list(intersect2.coords)), dtype=np.int32) pts = pts[:, :].reshape((-1, 1, 2)) cv2.fillConvexPoly( canvas, pts, (255, 255, 255), ) return canvas[:, :, 0] / 255., mask[:, :, 0] / 255.
def assembly_interfaces_numpy(assembly, nmax=10, tmax=1e-6, amin=1e-1, lmin=1e-3, face_face=True, face_edge=False, face_vertex=False): """Identify the interfaces between the blocks of an assembly. Parameters ---------- assembly : compas_assembly.datastructures.Assembly An assembly of discrete blocks. nmax : int, optional Maximum number of neighbours per block. Default is ``10``. tmax : float, optional Maximum deviation from the perfectly flat interface plane. Default is ``1e-6``. amin : float, optional Minimum area of a "face-face" interface. Default is ``1e-1``. lmin : float, optional Minimum length of a "face-edge" interface. Default is ``1e-3``. face_face : bool, optional Test for "face-face" interfaces. Default is ``True``. face_edge : bool, optional Test for "face-edge" interfaces. Default is ``False``. face_vertex : bool, optional Test for "face-vertex" interfaces. Default is ``False``. References ---------- The identification of interfaces is discussed in detail here [Frick2016]_. Examples -------- .. code-block:: python pass """ # replace by something proper assembly.edge = {} assembly.halfedge = {} for key in assembly.vertices(): assembly.edge[key] = {} assembly.halfedge[key] = {} key_index = assembly.key_index() index_key = assembly.index_key() blocks = [assembly.blocks[key] for key in assembly.vertices()] nmax = min(nmax, len(blocks)) block_cloud = assembly.get_vertices_attributes('xyz') block_nnbrs = _find_nearest_neighbours(block_cloud, nmax) # k: key of the base block # i: index of the base block # block: base block # nbrs: list of indices of the neighbouring blocks # frames: list of frames for each of the faces of the base block # f0: key of the current base face # A: uvw base frame of f0 # o: origin of the base frame of f0 # xyz0: xyz coordinates of the vertices of f0 # rst0: local coordinates of the vertices of f0, with respect to the frame of f0 # p0: 2D polygon of f0 in local coordinates # j: index of the current neighbour # n: key of the current neighbour # nbr: neighbour block # k_i: key index map for the vertices of the nbr block # xyz: xyz coorindates of all vertices of nbr # rst: local coordinates of all vertices of nbr, with respect to the frame of f0 # f1: key of the current neighbour face # rst1: local coordinates of the vertices of f1, with respect to the frame of f0 # p1: 2D polygon of f1 in local coordinates for k in assembly.vertices(): i = key_index[k] block = assembly.blocks[k] nbrs = block_nnbrs[i][1] frames = block.frames() if face_face: # parallelise? # exclude faces with parallel normals # e.g. exclude overlapping top faces of two neighbouring blocks in same row for f0, (origin, uvw) in frames.items(): A = array(uvw, dtype=float64) o = array(origin, dtype=float64).reshape((-1, 1)) xyz0 = array(block.face_coordinates(f0), dtype=float64).reshape((-1, 3)).T rst0 = solve(A.T, xyz0 - o).T.tolist() p0 = Polygon(rst0) for j in nbrs: n = index_key[j] if n == k: continue if k in assembly.edge and n in assembly.edge[k]: continue if n in assembly.edge and k in assembly.edge[n]: continue nbr = assembly.blocks[n] k_i = {key: index for index, key in enumerate(nbr.vertices())} xyz = array(nbr.get_vertices_attributes('xyz'), dtype=float64).reshape((-1, 3)).T rst = solve(A.T, xyz - o).T.tolist() rst = {key: rst[k_i[key]] for key in nbr.vertices()} for f1 in nbr.faces(): rst1 = [rst[key] for key in nbr.face_vertices(f1)] if any(fabs(t) > tmax for r, s, t in rst1): continue p1 = Polygon(rst1) if p1.area < amin: continue if p0.intersects(p1): intersection = p0.intersection(p1) area = intersection.area if area >= amin: coords = [[x, y, 0.0] for x, y, z in intersection.exterior.coords] coords = global_coords_numpy(o, A, coords) attr = { 'interface_type': 'face_face', 'interface_size': area, 'interface_points': coords.tolist()[:-1], 'interface_origin': origin, 'interface_uvw': uvw, } assembly.add_edge(k, n, attr_dict=attr)
def split_regions(slide_path, img_level=2, cnt_level=3): s_img, mask, cnts = find_tissue_cnt(slide_path, cnt_level) img_cnt_ratio = 2**(cnt_level - img_level) wsi_dim = [ele * img_cnt_ratio for ele in s_img.shape[:2]] slide_head = openslide.OpenSlide(slide_path) wsi_img = slide_head.read_region((0, 0), img_level, wsi_dim) wsi_img = np.array(wsi_img)[:, :, :3] RAW_SIZE = 256 SIZE1, SIZE2, SIZE4 = int(RAW_SIZE / 4), int(RAW_SIZE / 2), RAW_SIZE split_arr, patch_list = [], [] for c_ind in range(len(cnts)): cur_cnt = cnts[c_ind] * img_cnt_ratio cur_cnt = np.squeeze(cur_cnt) w_coors = [int(round(ele)) for ele in cur_cnt[:, 0].tolist()] h_coors = [int(round(ele)) for ele in cur_cnt[:, 1].tolist()] w_min, w_max = min(w_coors), max(w_coors) h_min, h_max = min(h_coors), max(h_coors) # Width range to crop start_w = (w_min - SIZE1) if (w_min - SIZE1) > 0 else 0 num_w = int(math.ceil((w_max - start_w - SIZE2) / SIZE2)) # Height range to crop start_h = (h_min - SIZE1) if (h_min - SIZE1) > 0 else 0 num_h = int(math.ceil((h_max - start_h - SIZE2) / SIZE2)) poly_cnt = Polygon(cur_cnt) if poly_cnt.is_valid == False: continue for iw in range(0, num_w): for ih in range(0, num_h): # determine current rectangular is inside the contour or not cur_coors = [ (start_w + iw * SIZE2, start_h + ih * SIZE2), (start_w + iw * SIZE2 + SIZE4, start_h + ih * SIZE2), (start_w + iw * SIZE2 + SIZE4, start_h + ih * SIZE2 + SIZE4), (start_w + iw * SIZE2, start_h + ih * SIZE2 + SIZE4) ] if start_w + iw * SIZE2 + SIZE4 >= wsi_img.shape[ 1] or start_h + ih * SIZE2 + SIZE4 > wsi_img.shape[0]: continue patch_cnt = Polygon(cur_coors) try: inter_flag = poly_cnt.intersects(patch_cnt) if inter_flag == False: continue else: inter_cnt = poly_cnt.intersection(patch_cnt) if inter_cnt.area > patch_cnt.area * 0.5: split_arr.append( (start_h + ih * SIZE2, start_w + iw * SIZE2)) split_patch = wsi_img[start_h + ih * SIZE2:start_h + ih * SIZE2 + SIZE4, start_w + iw * SIZE2:start_w + iw * SIZE2 + SIZE4, :] patch_list.append(split_patch) except: print("Error in Polygon relationship") return split_arr, patch_list, wsi_dim, s_img, mask
class FloorPlan: def __init__(self, PLS, parametersOnly=False): self.PLS = PLS self.objects = None self.combinerLength = self.PLS.latticeElementList[ self.PLS.combinerIndex].Length self.parameters = None # to hold the parameters used in the last build self.combinerWidth = .3 rCombiner = self.PLS.latticeElementList[self.PLS.combinerIndex].r0 self.combinerInputAngle = np.arcsin( self.combinerLength / rCombiner) * 180 / np.pi #Half angle seperation #between 2 incoming beams, deg self.combinerInputSep = 2 * self.combinerLength**2 / (2 * rCombiner) self.bendingRadius = None self.rOuterBender = .15 self.benderPoints = 50 self.TL1 = None # tracklength 1 self.TL2 = None # trackLength 2 self.wallSpacing = .3 #Minimum distance between wall and any component of the ring. meters self.focusToWallDistance = 4.4 #distance from focus of the collector magnet to the wall along the nozzle axis, meters self.Lm4 = None self.rOuter4 = None self.Lm3 = None self.rOuter3 = None self.Lm1 = None self.rOuter1 = None self.Lm2 = None self.rOuter2 = None self.rOuterRatio = 6.5 # outer dimension of lens to bore self.airGap1 = .01 # extra lens spacing for coils self.airGap2 = .01 # extra lens spacing for coils self.airGap3 = .01 # extra lens spacing for coils self.airGap4 = .01 # extra lens spacing for coils self.coilGapRatio = 2 #ratio between required coil spacing and bore radius # injector stuff self.LiMin = self.combinerLength + .2 self.LiMax = 3 self.LmMin = .025 self.LmMax = .5 self.LoMin = .05 self.LoMax = .2 self.Lo = None self.Lm = None self.Li = None self.rOuterShaper = .15 # shaper magnet yoke radius self.rVacuumTube = .02 # total floorplan stuff self.distanceFromObjectMax = 4.2 # maximum distance from object of injector to wall self.combinerLen1Sep = .2 # 20 cm between output of combiner and lens1 self.combiner = None self.lensShaper = None self.bender1 = None self.bender2 = None self.lens1 = None self.lens2 = None self.lens3 = None self.lens4 = None self.lens4VacuumTube = None self.shaperVacuumTube = None # make floorplan list func self.floorPlanArgListFunc = None if parametersOnly == False: if self.PLS.combinerIndex != None: temp = [] temp.append( self.PLS.trackLength - (self.PLS.latticeElementList[self.PLS.combinerIndex].S + self.PLS.latticeElementList[self.PLS.combinerIndex].Length / 2)) # # tracklength 1 temp.append( self.PLS.latticeElementList[self.PLS.combinerIndex].S + self.PLS.latticeElementList[self.PLS.combinerIndex].Length / 2) # tracklength 2 temp.append(self.PLS.latticeElementList[ self.PLS.lensIndices[3]].Length) # lens lengths temp.append(self.PLS.latticeElementList[ self.PLS.lensIndices[0]].Length) # lens lengths temp.append(self.PLS.latticeElementList[ self.PLS.lensIndices[1]].Length) # lens lengths temp.append(self.PLS.latticeElementList[ self.PLS.lensIndices[2]].Length) # lens lengths temp.append( self.PLS.latticeElementList[self.PLS.benderIndices[0]].r0 ) # bender radius, same for both as of now temp.append(self.PLS.latticeElementList[ self.PLS.combinerIndex].Length) # length of combiner temp.append(self.PLS.injector.Lo) temp.append(self.PLS.injector.Lm) temp.append(self.PLS.injector.Li) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[1]].rp * self.rOuterRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[2]].rp * self.rOuterRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[3]].rp * self.rOuterRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[0]].rp * self.rOuterRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[3]].rp * self.coilGapRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[0]].rp * self.coilGapRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[1]].rp * self.coilGapRatio) temp.append( self.PLS.latticeElementList[self.PLS.lensIndices[2]].rp * self.coilGapRatio) args = self.PLS.sympyVarList.copy() args.extend(self.PLS.injector.sympyVarList) self.floorPlanArgListFunc = sym.lambdify(args, temp) def load_Paramters(self, args): self.parameters = self.floorPlanArgListFunc(*args) self.TL1 = self.parameters[0] self.TL2 = self.parameters[1] self.Lm1 = self.parameters[2] self.Lm2 = self.parameters[3] self.Lm3 = self.parameters[4] self.Lm4 = self.parameters[5] self.bendingRadius = self.parameters[6] self.combinerLength = self.parameters[7] self.Lo = self.parameters[8] self.Lm = self.parameters[9] self.Li = self.parameters[10] self.rOuter1 = self.parameters[11] self.rOuter2 = self.parameters[12] self.rOuter3 = self.parameters[13] self.rOuter4 = self.parameters[14] self.airGap1 = self.parameters[15] self.airGap2 = self.parameters[16] self.airGap3 = self.parameters[17] self.airGap4 = self.parameters[18] def build(self, args, reloadParams=True): if reloadParams == True: # don't bother refilling the parameters list if I already di self.load_Paramters(args) self.objects = [] self.combiner = Polygon([(0, 0), (0, self.combinerWidth), (self.combinerLength, self.combinerWidth), (self.combinerLength, 0)]) self.combiner = translate(self.combiner, yoff=-self.combinerWidth / 2) self.objects.append(self.combiner) angle = 180 angleArr = np.linspace(-angle / 2, angle / 2, num=self.benderPoints) x1 = (self.bendingRadius - self.rOuterBender) * np.cos( angleArr * np.pi / 180) y1 = (self.bendingRadius - self.rOuterBender) * np.sin( angleArr * np.pi / 180) angleArr = np.linspace(angle / 2, -angle / 2, num=self.benderPoints) x2 = (self.bendingRadius + self.rOuterBender) * np.cos( angleArr * np.pi / 180) y2 = (self.bendingRadius + self.rOuterBender) * np.sin( angleArr * np.pi / 180) x = np.append(x1, x2) y = np.append(y1, y2) self.bender2 = Polygon(np.column_stack((x[None].T, y[None].T))) self.lens4 = Polygon([(0, 0), (self.Lm4, 0), (self.Lm4, self.rOuter4 * 2), (0, self.rOuter4 * 2)]) self.lens4 = translate(self.lens4, xoff=-self.Lm4 - self.airGap4, yoff=-self.rOuter4) self.lens3 = Polygon([(0, 0), (self.Lm3, 0), (self.Lm3, self.rOuter3 * 2), (0, self.rOuter3 * 2)]) self.lens3 = translate(self.lens3, xoff=-self.Lm3 - self.airGap3, yoff=self.bendingRadius - self.rOuter3) self.lens4VacuumTube = Polygon([ (0, 0), (self.TL2 - self.combinerLength - self.Lm4 - self.airGap4, 0), (self.TL2 - self.combinerLength - self.Lm4 - self.airGap4, self.rVacuumTube * 2), (0, self.rVacuumTube * 2) ]) self.lens4VacuumTube = translate(self.lens4VacuumTube, xoff=self.combinerLength, yoff=-self.rVacuumTube) self.lens4VacuumTube = rotate(self.lens4VacuumTube, self.combinerInputAngle, origin=(self.combinerLength, 0)) self.bender2 = translate(self.bender2, yoff=self.bendingRadius) self.lens3 = translate(self.lens3, yoff=self.bendingRadius) self.bender2 = rotate(self.bender2, self.combinerInputAngle, origin=(self.combinerLength, 0)) self.lens3 = rotate(self.lens3, self.combinerInputAngle, origin=(self.combinerLength, 0)) self.lens4 = rotate(self.lens4, self.combinerInputAngle, origin=(self.combinerLength, 0)) self.bender2 = translate(self.bender2, yoff=self.combinerInputSep / 2) self.lens3 = translate(self.lens3, yoff=self.combinerInputSep / 2) self.lens4 = translate(self.lens4, yoff=self.combinerInputSep / 2) tempx = self.TL2 * np.cos(self.combinerInputAngle * np.pi / 180) tempy = self.TL2 * np.sin(self.combinerInputAngle * np.pi / 180) self.bender2 = translate(self.bender2, xoff=tempx, yoff=tempy) self.lens3 = translate(self.lens3, xoff=tempx, yoff=tempy) self.lens4 = translate(self.lens4, xoff=tempx, yoff=tempy) self.objects.append(self.bender2) self.objects.append(self.lens4) self.objects.append(self.lens3) self.objects.append(self.lens4VacuumTube) self.bender1 = Polygon(np.column_stack((x[None].T, y[None].T))) self.bender1 = rotate(self.bender1, 180, origin=(0, 0)) self.bender1 = translate(self.bender1, yoff=self.bendingRadius, xoff=-self.TL1) self.lens1 = Polygon([(0, 0), (self.Lm1, 0), (self.Lm1, self.rOuter1 * 2), (0, self.rOuter1 * 2)]) self.lens1 = translate(self.lens1, xoff=-self.TL1 + self.airGap1, yoff=-self.rOuter1) self.lens2 = Polygon([(0, 0), (self.Lm2, 0), (self.Lm2, self.rOuter2 * 2), (0, self.rOuter2 * 2)]) self.lens2 = translate(self.lens2, xoff=-self.TL1 + self.airGap2, yoff=2 * self.bendingRadius - self.rOuter2) self.objects.append(self.bender1) self.objects.append(self.lens1) self.objects.append(self.lens2) self.lensShaper = Polygon([(0, 0), (self.Lm, 0), (self.Lm, self.rOuterShaper * 2), (0, self.rOuterShaper * 2)]) self.lensShaper = translate(self.lensShaper, yoff=-self.rOuterShaper, xoff=self.combinerLength) self.lensShaper = rotate(self.lensShaper, -self.combinerInputAngle, origin=(self.combinerLength, 0)) self.lensShaper = translate(self.lensShaper, yoff=-self.combinerInputSep / 2) tempx = (self.Li - self.combinerLength) * np.cos( self.combinerInputAngle * np.pi / 180) tempy = (self.Li - self.combinerLength) * np.sin( self.combinerInputAngle * np.pi / 180) self.lensShaper = translate(self.lensShaper, xoff=tempx, yoff=-tempy) self.shaperVacuumTube = Polygon([(0, 0), (self.Li - self.combinerLength, 0), (self.Li - self.combinerLength, self.rVacuumTube * 2), (0, self.rVacuumTube * 2)]) self.shaperVacuumTube = translate(self.shaperVacuumTube, yoff=-self.rVacuumTube, xoff=self.combinerLength) self.shaperVacuumTube = rotate(self.shaperVacuumTube, -self.combinerInputAngle, origin=(self.combinerLength, 0)) self.shaperVacuumTube = translate(self.shaperVacuumTube, yoff=-self.combinerInputSep / 2) self.objects.append(self.lensShaper) self.objects.append(self.shaperVacuumTube) # numShapes=len(self.objects) # temp=np.zeros((numShapes,numShapes)) # for i in range(numShapes): # for j in range(i+1,numShapes): # temp[i,j]=1 # print(temp) def show_Floor_Plan(self, sol=None, args=None): if args != None: # if someone provides values for arguments then build it, otherwise its already built self.build(args) if sol != None: self.build(sol.args) if (sol == None and args == None) or (sol != None and args != None): raise Exception( 'YOU CANNOT PROVIDE BOTH A SOLUTION AND ARGUMENTS TO PLOT') for i in range(len(self.objects)): plt.plot(*self.objects[i].exterior.xy) plt.xlim(-2, 2) plt.ylim(-1, 3) plt.show() def calculate_Cost(self, args=None, offset=4, areaWeight=100, lineWeight=1): # This method works fast by only building the floorplan, which takes a few ms, if all simple costs return zero # use fractional overlapping area, (area overlapping)/(total area) totalCost = 0 if args is not None: # if no arguments are provided, just use the cpreviously built floorplan. otherwise rebuild self.load_Paramters(args) xMostLeft = (self.Lo + self.Lm + self.Li) * np.cos( self.combinerInputAngle * np.pi / 180) #the most leftward point of the #bender. This is used to prevent the layout from impinging onto the wall and too keep enough seperation xMostLeft += self.TL1 + self.bendingRadius + self.rOuterBender if xMostLeft > (self.focusToWallDistance - self.wallSpacing): totalCost += lineWeight * np.abs(xMostLeft - (self.focusToWallDistance - self.wallSpacing)) if self.Li < self.LiMin: totalCost += lineWeight * np.abs(self.LiMin - self.Li) if self.Li > self.LiMax: totalCost += lineWeight * np.abs(self.Li - self.LiMax) if self.TL1 < 0: totalCost += lineWeight * np.abs(self.TL1) if self.TL2 < 0: totalCost += lineWeight * np.abs(self.TL2) if (self.Lm2 + self.Lm3 + self.airGap2 + self.airGap3) > ( self.TL1 + self.TL2): # if the two lenses overlap totalCost += lineWeight * np.abs( (self.Lm2 + self.Lm3 + self.airGap2 + self.airGap3) - (self.TL1 + self.TL2)) if (self.Li + self.Lm + self.Lo + self.TL1 + self.bendingRadius) > self.distanceFromObjectMax: totalCost += lineWeight * np.abs( (self.Li + self.Lm + self.Lo + self.TL1 + self.bendingRadius) - self.distanceFromObjectMax) if (self.TL1 - self.Lm1 - self.airGap1) < self.combinerLen1Sep: # if there is not enough room between the combiner output and next lens for optical pumping: totalCost += lineWeight * np.abs( (self.TL1 - self.Lm1 - self.airGap1) - self.combinerLen1Sep) if (self.TL2 - self.Lm4 - self.combinerLength) < 0: # if lens 4 is impinging on the combiner totalCost += lineWeight * np.abs(self.TL2 - self.Lm4 - self.combinerLength) if totalCost < 1E-10: # to prevent rounding errors that screwed me up before area = 0 if args is not None: # if args are None then use the current floorplan self.build(args, reloadParams=False) area += self.lens1.intersection( self.combiner).area / (self.lens1.area + self.combiner.area ) # fractional area overlap # between lens1 and combiner area += self.lens4.intersection( self.lensShaper).area / (self.lens1.area + self.lensShaper.area ) # farctional area overlap # between lens4 and shaper lens area += self.bender2.intersection(self.lensShaper).area / ( self.lensShaper.area + self.bender2.area ) # fractional area overlap # between shaper lens and bender 2 area += self.shaperVacuumTube.intersection(self.lens4).area / ( self.shaperVacuumTube.area + self.lens4.area) area += self.lens4VacuumTube.intersection(self.lensShaper).area / ( self.lens4VacuumTube.area + self.lensShaper.area) area += self.shaperVacuumTube.intersection(self.bender2).area / ( self.shaperVacuumTube.area + self.bender2.area) totalCost += area * areaWeight return totalCost + offset
def _shift_polygon(self, polygon): """ shifts a polygon according to the origin longitude """ if self.lon0 == 0.0: return [polygon] # no need to shift anything from shapely.geometry import Polygon # we need to split and join some polygons poly_coords = [] holes = [] for (lon, lat) in polygon.exterior.coords: poly_coords.append((lon - self.lon0, lat)) for hole in polygon.interiors: hole_coords = [] for (lon, lat) in hole.coords: hole_coords.append((lon - self.lon0, lat)) holes.append(hole_coords) poly = Polygon(poly_coords, holes) polygons = [] #print "shifted polygons", (time.time() - start) #start = time.time() try: p_in = poly.intersection(self.bounds) polygons += hasattr(p_in, 'geoms') and p_in.geoms or [p_in] except: pass #print "computed polygons inside bounds", (time.time() - start) #start = time.time() try: p_out = poly.symmetric_difference(self.bounds) out_geoms = hasattr(p_out, 'geoms') and p_out.geoms or [p_out] except: out_geoms = [] pass #print "computed polygons outside bounds", (time.time() - start) #start = time.time() for polygon in out_geoms: ext_pts = [] int_pts = [] s = 0 # at first we compute the avg longitude c = 0 for (lon, lat) in polygon.exterior.coords: s += lon c += 1 left = s / float(c) < -180 # and use it to decide where to shift the polygon for (lon, lat) in polygon.exterior.coords: ext_pts.append((lon + (-360, 360)[left], lat)) for interior in polygon.interiors: pts = [] for (lon, lat) in interior.coords: pts.append((lon + (-360, 360)[left], lat)) int_pts.append(pts) polygons.append(Polygon(ext_pts, int_pts)) # print "shifted outside polygons to inside", (time.time() - start) return polygons
class Poly(object): def __init__(self, pts): super(Poly, self).__init__() self.points = pts self.poly = Polygon self.updatePolygon() def move(self, x, y): for pt in self.points: pt.move(x, y) self.updatePolygon() def scale(self, r): for pt in self.points: pt.scale(r) self.updatePolygon() def updatePolygon(self): self.poly = Polygon([(pnt.x(), pnt.y()) for pnt in self.points]) # self.poly = Polygon([(1,2),(1,1),(5,5)]) def containsPoint(self, pnt): self.poly.contains(pnt.pnt) def intersects(self, poly): return self.poly.intersects(poly.poly) def intersection(self, poly): if not self.intersects(poly): return None try: poly = self.poly.intersection(poly.poly) if type(poly) is Polygon: return Poly(Poly.getPointsFromShapelyPoly(poly)) except Exception: return None return None def union(self, poly): #does not return a Poly object return self.poly.union(poly.poly) def subtractPoly(self, poly): spoints = list(self.points) if len(self.points) > 4: pnts = self.points size = len(pnts) for i in range(size): p1, p2 = pnts[(i - 1) % size], pnts[(i + 1) % size] vec1 = pnts[i] - p1 vec2 = p2 - pnts[i] if vec1.isParallel(vec2, 0.05): spoints.remove(pnts[i]) if len(spoints) > 4: return [self] def getTopLeft(points): minY = min([pnt.y() for pnt in points]) minX = None minPnt = None for pnt in points: if pnt.y() == minY: if not minPnt: minPnt = pnt minX = pnt.x() if pnt.x() < minX: minPnt = pnt minX = pnt.x() return minPnt pntM = getTopLeft(spoints) indM = [ i for i, pnt in enumerate(spoints) if pnt.x() == pntM.x() and pnt.y() == pntM.y() ][0] vecL = spoints[(indM + 1) % len(spoints)] - spoints[indM] vecW = spoints[(indM - 1) % len(spoints)] - spoints[indM] if vecW.magn() > vecL.magn(): vecL, vecW = vecW, vecL pPntM = None minS = None for pnt in poly.points: vec = pnt - pntM if vec.isParallel(vecL): if not pPntM: pPntM = pnt minS = vec.magn() elif minS > vec.magn(): pPntM = pnt minS = vec.magn() if not pPntM: # from UI import Plotter # from matplotlib import pyplot as plt # print("ERROR GEOM2D: NO PARALLELISM") # print(self) # print(poly) # Plotter.plotPolys([self],1) # Plotter.plotPolys([poly], 2) # Plotter.plotPolys([self,poly], 2) # plt.show() return [self] # pPntM = getTopLeft(poly.points) pIndM = [ i for i, pnt in enumerate(poly.points) if pnt.x() == pPntM.x() and pnt.y() == pPntM.y() ][0] pvecL = poly.points[(pIndM + 1) % len(poly.points)] - poly.points[pIndM] pvecW = poly.points[(pIndM - 1) % len(poly.points)] - poly.points[pIndM] # print(vecL) # print(vecW) # print(pvecL) # print(pvecW) if pvecW.isParallel(vecL, 0.05): pvecW, pvecL = pvecL, pvecW if not pvecL.isParallel(vecL, 0.05): print( "ERROR GEOM2D SUBTRACTPOLY: NOT PARALLEL, THEY SHOULD BE PARALLEL!" ) return [self] vecp = pPntM - pntM if pntM.x() == pPntM.x() and pntM.y() == pPntM.y(): if pvecL.magn() == vecL.magn(): # print("REMOVING IT ALL!!!") # print(self) # print(poly) return [] return [ Poly([ pPntM + pvecL, pPntM + pvecL + pvecW, pntM + vecL + pvecW, pntM + vecL ]) ] if vecp.magn() + pvecL.magn() == vecL.magn(): return [Poly([pntM, pPntM, pPntM + pvecW, pntM + pvecW])] # return [self] polys = [ Poly([pntM, pPntM, pPntM + pvecW, pntM + pvecW]), Poly([ pPntM + pvecL, pPntM + pvecL + pvecW, pntM + vecL + pvecW, pntM + vecL ]) ] # print(polys[0]) # print(polys[1]) return polys # return [self] def copy(self): return Poly([pnt.copy() for pnt in self.points]) def area(self): return self.poly.area def centroid(self): return self.poly.centroid def momentX(self): pts = [[p.x(), p.y()] for p in self.points][::-1] return inertia(pts)[0] def momentY(self): pts = [[p.x(), p.y()] for p in self.points][::-1] return inertia(pts)[1] def __copy__(self): return self.copy() def __str__(self): s = "polygon:\n" for pnt in self.points: s += str(pnt) + '\n' return s @staticmethod def getPointsFromShapelyPoly(polygon): pnts = [] for pnt in polygon.exterior.coords: pnts.append(Pnt(pnt[0], pnt[1])) del pnts[-1] return pnts
from shapely.geometry import box, Polygon import rtree gridcell_shape = box(129.5, -27.0, 129.75, 27.25) # Populate R-tree index with bounds of grid cells for pos, cell in enumerate(gridcell_shape): # assuming cell is a shapely object idx.insert(pos, cell.bounds) # Example polygon xy = [[130.21001, 27.200001], [129.52, 27.34], [129.45, 27.1], [130.13, 26.950001]] polygon_shape = Polygon(xy) # Example grid cell gridcell_shape = box(129.5, -27.0, 129.75, 27.25) # The intersection polygon_shape.intersection(gridcell_shape).area # In[ ]: from osgeo import ogr import shapely import matplotlib.pyplot as plt import matplotlib.pyplot as plt from descartes import PolygonPatch import shapely wkt1 = "POLYGON ((1208064.271243039 624154.6783778917, 1208064.271243039 601260.9785661874, 1231345.9998651114 601260.9785661874, 1231345.9998651114 624154.6783778917, 1208064.271243039 624154.6783778917))" wkt2 = "POLYGON ((1199915.6662253144 633079.3410163528, 1199915.6662253144 614453.958118695, 1219317.1067437078 614453.958118695, 1219317.1067437078 633079.3410163528, 1199915.6662253144 633079.3410163528)))" poly1 = ogr.CreateGeometryFromWkt(wkt1) poly2 = ogr.CreateGeometryFromWkt(wkt2)
def GetVoPolygons(pos1,course1,speed1,pos2,course2,speed2): # 获得四个VO区域的多边形坐标集合 # pos1为本船的位置向量,pos2为目标船位置向量 # course1为本船的航向,course2为目标船航向,正北为0°,向右旋转为正 # speed1为本船速度,speed2为目标船速度,m/s #返回的是shapely格式的polygon #船舶1的坐标 pp1 = np.array(pos1) #船舶2速度向量终点坐标,起点为本船位置 pp2 = np.array([pp1[0] + speed2 * np.sin(course2 * np.pi / 180) * SCALE,\ pp1[1] + speed2 * np.cos(course2 * np.pi / 180) * SCALE]) #从pos1指向pos2的向量 vec12 = np.array(pos2) - pp1 #vec12逆时针旋转90°得到的向量 vec12_rotate90 = np.array([vec12[0] * np.cos(np.pi / 2) - vec12[1] * np.sin(np.pi / 2),\ vec12[0] * np.sin(np.pi / 2) + vec12[1] * np.cos(np.pi / 2)]) pp4,pp3 = lc.LineCircleIntersection(pp1,V_MAX * SCALE, pp2, vec12_rotate90) gamma = math.asin(DCPA / np.linalg.norm(vec12)) * 180 / np.pi #安全角度 #相对位置向量顺时针旋转gamma后的向量 vec_rotate_right = [vec12[0] * np.cos(gamma * np.pi / 180) + vec12[1] * np.sin(gamma * np.pi / 180),\ -vec12[0] * np.sin(gamma * np.pi / 180) + vec12[1] * np.cos(gamma * np.pi / 180)] #相对位置向量顺时针旋转gamma后的向量 vec_rotate_left = [vec12[0] * np.cos(gamma * np.pi / 180) - vec12[1] * np.sin(gamma * np.pi / 180),\ vec12[0] * np.sin(gamma * np.pi / 180) + vec12[1] * np.cos(gamma * np.pi / 180)] p_temp1, p_temp2 = lc.LineCircleIntersection(pp1,V_MAX * SCALE, pp2, vec_rotate_right) #这里还需要进一步判断 vec1 = pp3 - pp1 vec2 = p_temp1 - pp1 if vec1[0] * vec2[1] - vec2[0] * vec1[1] > 0: pp5 = p_temp1 else: pp5 = p_temp2 p_temp1, p_temp2 = lc.LineCircleIntersection(pp1,V_MAX * SCALE, pp2, vec_rotate_left) #这里还需要进一步判断 vec1 = p_temp1 - pp1 vec2 = pp4 - pp1 if vec1[0] * vec2[1] - vec2[0] * vec1[1] > 0: pp6 = p_temp1 else: pp6 = p_temp2 pp7 = np.array([pp1[0] + V_MAX * SCALE * np.sin((course1 + ALPHA_MAX) * np.pi / 180),\ pp1[1] + V_MAX * SCALE * np.cos((course1 + ALPHA_MAX) * np.pi / 180)]) pp8 = np.array([pp1[0] + V_MAX * SCALE * np.sin((course1 - ALPHA_MAX) * np.pi / 180),\ pp1[1] + V_MAX * SCALE * np.cos((course1 - ALPHA_MAX) * np.pi / 180)]) ########################################################################## #计算多个矩形区域 # 1:整个速度向量区域 point_temp = ga.GetArcPoints(pp1,pp7,pp8) poly_whole = np.vstack((pp1, pp7,point_temp,pp8)) #多个矩阵合并 #python四边形对象,会自动生成逆时针的凸多边形 poly_whole = Polygon(poly_whole).convex_hull #2:速度障碍区域 point_temp = ga.GetArcPoints(pp1,pp5,pp6) poly_vo = np.vstack((pp2, pp5,point_temp,pp6)) #多个矩阵合并 poly_vo = Polygon(poly_vo).convex_hull #3:poly_front point_temp = ga.GetArcPoints(pp1,pp6,pp4) poly_front = np.vstack((pp2, pp6,point_temp,pp4)) #多个矩阵合并 poly_front = Polygon(poly_front).convex_hull #4:poly_rear point_temp = ga.GetArcPoints(pp1,pp3,pp5) poly_rear = np.vstack((pp2, pp3,point_temp,pp5)) #多个矩阵合并 poly_rear = Polygon(poly_rear).convex_hull #5:poly_diverging point_temp = ga.GetArcPoints(pp1,pp4,pp3) poly_diverging = np.vstack((pp3,pp4,point_temp)) #多个矩阵合并 poly_diverging = Polygon(poly_diverging).convex_hull #################################################### #求多个区域与poly_whole的相交区域 if not poly_vo.intersects(poly_whole): #如果两四边形不相交 poly_vo = [] else: poly_vo = poly_vo.intersection(poly_whole) if not poly_front.intersects(poly_whole): #如果两四边形不相交 poly_front = [] else: poly_front = poly_front.intersection(poly_whole) if not poly_rear.intersects(poly_whole): #如果两四边形不相交 poly_rear = [] else: poly_rear = poly_rear.intersection(poly_whole) if not poly_diverging.intersects(poly_whole): #如果两四边形不相交 poly_diverging = [] else: poly_diverging = poly_diverging.intersection(poly_whole) ########################################################################## return poly_vo,poly_front,poly_rear,poly_diverging #pos1 = [1000,-5134] #course1 = 0 #speed1 = 5.144 # #pos2 = [5446,2567] #course2 = 240 #speed2 = 5.144 # #poly_vo,poly_front,poly_rear,poly_diverging = GetVoPolygons(pos1,course1,speed1,pos2,course2,speed2) # #print(poly_vo)
def iou(boxa: List, boxb: List) -> float: a = Polygon(boxa) b = Polygon(boxb) intersect_area = a.intersection(b).area union_area = a.union(b).area return intersect_area / union_area
def calculate_intersection(box_1, box_2): poly_1 = Polygon(box_1) poly_2 = Polygon(box_2) intersection_area = poly_1.intersection(poly_2).area return intersection_area
def __find_areas(self, vor, boundary): import itertools if boundary is not list: boundary = boundary.tolist() if boundary[0] != boundary[-1]: boundary.append(boundary[0]) bounds = Polygon(boundary) #diagonal of bounding box = safe maximum distance to add: radius = common.distance((bounds.bounds[0], bounds.bounds[1]), (bounds.bounds[2], bounds.bounds[3])) vor = self.__voronoi_correction(vor, radius) regions, vertices = self.__voronoi_finite_polygons_2d(vor, radius) areas = [] for region in regions: #check for polygon validity: vs = np.asarray([tuple(vertices[i]) for i in region]) if len(vs) < 3: print "NON-POLYGON=>no area record" areas.append(np.nan) continue p = Polygon(vs) if not p.is_valid: #brute-force validation of polygon c = vs.mean(axis=0) angles = np.arctan2(vs[:, 1] - c[1], vs[:, 0] - c[0]) cc_order = np.argsort(angles) print len( cc_order), ": INVALID POLYGON! Start permuting! (", len( angles), "points)", #permutation works on last elements of list first. However, #the first elements of the Voronoi vertices for a region tend #to be the ones that are wrongly defined perm = itertools.permutations(cc_order[::-1]) while True: try: opa = np.array(perm.next()) p = Polygon(vs[opa[::-1]]) except: print "RAN OUT OF PERMUTATIONS!" raise if p.is_valid: print "VALIDATED POLYGON! End permuting!" break #intersect with boundary (river polygon) inter = p.intersection(bounds) #calculate area if inter.type not in ['Polygon', 'MultiPolygon']: print inter.type, "NON-POLYGON=>no area record" areas.append(np.nan) #unknown area elif inter.type == 'MultiPolygon': a = 0.0 for poly in inter: a += abs(poly.area) areas.append(a) else: areas.append(abs(inter.area)) #adjust voronoi data structure vor.regions = [[]] + regions #add initial empty region vor.vertices = vertices return np.array(areas), vor
def _compute_bbox_height(self, height, width, ref_width, yaw): yaw -= math.pi / 2 fixed_width = int(ref_width / self.bvres) cosy = np.cos(yaw) siny = np.sin(yaw) cosyrect = np.cos(yaw + np.pi / 2) sinyrect = np.sin(yaw + np.pi / 2) # Compute the two possible car lengths l0 = abs((height - abs(cosyrect * fixed_width)) / cosy) if round( cosy, 3) != 0 else 0 # TODO Check if 0 is right value l1 = abs((width - abs(sinyrect * fixed_width)) / siny) if round( siny, 3) != 0 else 0 # TODO Check if 0 is right value # pdb.set_trace() # Compute vertexes for the aligned bbox aligned_v0 = (-height / 2, -width / 2) aligned_v1 = (-height / 2, +width / 2) aligned_v2 = (+height / 2, +width / 2) aligned_v3 = (+height / 2, -width / 2) # Compute rotated vertexes for the bbox 0 alignedl0_corners = np.array([[-l0 / 2, -fixed_width / 2], [-l0 / 2, +fixed_width / 2], [+l0 / 2, +fixed_width / 2], [+l0 / 2, -fixed_width / 2]]) # Compute rotated vertexes for the bbox 1 alignedl1_corners = np.array([[-l1 / 2, -fixed_width / 2], [-l1 / 2, +fixed_width / 2], [+l1 / 2, +fixed_width / 2], [+l1 / 2, -fixed_width / 2]]) # Compute rotation matrix c, s = np.cos(yaw), np.sin(yaw) R = np.array([[c, -s], [s, c]]) # Rotate all corners at once by yaw rot0_corners = np.dot(alignedl0_corners, R.T) rot1_corners = np.dot(alignedl1_corners, R.T) # Compute IoU between aligned bbox and the two refined proposals aligned_poly = Polygon( [aligned_v0, aligned_v1, aligned_v2, aligned_v3]) poly0 = Polygon([ tuple(rot0_corners[0]), tuple(rot0_corners[1]), tuple(rot0_corners[2]), tuple(rot0_corners[3]) ]) poly1 = Polygon([ tuple(rot1_corners[0]), tuple(rot1_corners[1]), tuple(rot1_corners[2]), tuple(rot1_corners[3]) ]) intersection_p0 = poly0.intersection(aligned_poly).area intersection_p1 = poly1.intersection(aligned_poly).area iou_p0 = intersection_p0 / (aligned_poly.area + poly0.area - intersection_p0) iou_p1 = intersection_p1 / (aligned_poly.area + poly1.area - intersection_p1) # Return the car length with higher IoU with the aligned bbox return l0 if iou_p0 > iou_p1 else l1
flags_near = [] path_pixels = [] inds = [] rats = [] err = False for ix, iy in zip(indx[flags], indy[flags]): xc = xp[iy, ix] yc = yp[iy, ix] pc = Point(xc, yc) poly_pixel = Polygon([ (xc - xhlf, yc - yhlf), (xc - xhlf, yc + yhlf), (xc + xhlf, yc + yhlf), (xc + xhlf, yc - yhlf), (xc - xhlf, yc - yhlf) ]) try: poly_intersect = poly_buffer.intersection(poly_pixel) except Exception: sys.stderr.write( 'Warning, error occured at (ix,iy)=({},{}), ii={}\n'. format(ix, iy, ii)) err = True continue rat = poly_intersect.area / poly_pixel.area if rat > 1.0e-10: inds.append(np.ravel_multi_index((iy, ix), data_shape)) rats.append(rat) if opts.debug or opts.check: flags_inside.append(pc.within(poly_buffer)) flags_near.append(rat > 1.0e-10) path_pixel = Path([(xc - xhlf, yc - yhlf), (xc - xhlf, yc + yhlf),
def compute_iou(box1, box2): a = Polygon(torch.t(box1)).convex_hull b = Polygon(torch.t(box2)).convex_hull return a.intersection(b).area / a.union(b).area
def plate(self, ptype, lat, decMax, rMax): lw = 1 pltLimit = 1 rMax = pltLimit self.p.setProjection(ptype, 0, 90, decMax, rMax) # circle1 = plt.Circle( (0,0), self.Rmax, linewidth=lw, color=self.plateCircleColor, fill=False) # self.ax.add_artist(circle1) #self.plotHorizon(18.0) n = 100 p = [] for i in range(n): t = float(i) / float(n - 1) * 2.0 * np.pi x = (np.sin(t)) y = (np.cos(t)) p.append((x, y)) circleShape = Polygon(p) n = 100 hrotate = 18 lon = 0 #self.a.setLatLong(lat, lon) altLine = self.a.createAltPath(0.0, n, hrotate) pAltLine = self.p.projectSimpleLine(altLine) #self.plotSimpleLine(pAltLine) horizonShape = Polygon(pAltLine) if ptype == 2: plateShape = circleShape.difference(horizonShape) elif ptype == 4: plateShape = horizonShape.intersection(circleShape) else: print "ptype = ", ptype, " error in plate" exit() ax = plt.gca() ax.add_patch( descartes.PolygonPatch(plateShape, fc='b', ec='k', alpha=0.4)) #ax.add_patch(descartes.PolygonPatch(ll1, fc='r', ec='k', alpha=0.2)) font0 = FontProperties() fontl = font0.copy() fontl.set_family( "sans-serif" ) # ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] fontl.set_style("normal") # ['normal', 'italic', 'oblique'] fontl.set_weight( "bold" ) # ['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black'] rhr = rMax * 0.93 for hr in range(24): theta = float(hr) * 15. * np.pi / 180. x = rhr * np.sin(-theta) y = rhr * np.cos(-theta) rot = 180. + float(hr) * 15. hhh = hr % 12 if hhh <> 0: ss = str(hhh) elif hr == 0: ss = "MID\n NIGHT" else: ss = "NOON" if hr > 14 or hr < 10: plt.text(x, y, ss, fontproperties=fontl, fontsize=self.plateFontSize, verticalalignment="center", horizontalalignment="center", rotation=rot, color=self.plateFontColor) dth = 4.0 theta = (float(hr) * 15. + dth) * np.pi / 180. x = rhr * np.sin(-theta) y = rhr * np.cos(-theta) rot = 180. + float(hr) * 15. if hr > 0 and hr < 11: ss = "AM" elif hr > 12 and hr < 24: ss = "PM" else: ss = "" if hr > 14 or hr < 10: plt.text(x, y, ss, fontsize=self.plateFontSize, fontproperties=fontl, color=self.plateFontColor, verticalalignment="center", horizontalalignment="center", rotation=rot) # 15 minute marks rhr = rMax rhr2 = rMax * 0.985 rhr3 = rMax * 0.96 for fm in range(0, 24 * 4): theta = float(fm) / 4.0 * 15. * np.pi / 180. x1 = rhr * np.sin(-theta) y1 = rhr * np.cos(-theta) if fm % 4 > 0: x2 = rhr2 * np.sin(-theta) y2 = rhr2 * np.cos(-theta) else: x2 = rhr3 * np.sin(-theta) y2 = rhr3 * np.cos(-theta) rot = 180. + float(hr) * 15. plt.plot([x1, x2], [y1, y2], linewidth=2, color=self.plateFontColor) # plt.text(x, y, "x", fontsize=36, verticalalignment="center", horizontalalignment="center", rotation=rot) #quote = "When I heard the learn'd astronomer, \n When the proofs, the figures, were arranged in columns before me, \n When I was shows the charts and diagrams, to add, divide, and measure them, \n When I sitting heard the astronomer where he lectured with much applause from the lecture-room, \n How soon unaccountable I became tired and sick, \n Till rising and glidering out I wander'd off by myself, \n In the mystical moist night-air, and from time to time, \n Look'd up in perfect silence at the star. \n Walt Whitman, The Learn'd Astronomer" #plt.text(-0.5, 0.4, quote, fontsize=5, verticalalignment = "center", horizontalalignment="left") font0 = FontProperties() fontq = font0.copy() fontq.set_family( "sans-serif" ) # ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] fontq.set_style("italic") # ['normal', 'italic', 'oblique'] fontq.set_weight( "bold" ) # ['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black'] quote = "For my part, I know nothing with certainty, \n but the sight of the stars makes me dream. \n - Vincent Van Gogh" plt.text(-0.0, 0.4, quote, fontsize=10, fontproperties=fontq, verticalalignment="center", horizontalalignment="center", color=self.plateFontColor) # https://matplotlib.org/examples/pylab_examples/fonts_demo.html font0 = FontProperties() fontt = font0.copy() fontt.set_family( "sans-serif" ) # ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] fontt.set_style("italic") # ['normal', 'italic', 'oblique'] fontt.set_weight( "bold" ) # ['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black'] plt.text(0.0, 0.5, "The Night Sky", fontsize=24, fontproperties=fontt, verticalalignment="center", horizontalalignment="center", color=self.plateFontColor)
class RBox: def __init__(self, rotate_rect: List[int], label=-1): """ :param rotate_rect: [x1, y1, x2, y2, x3, y3, x4, y4, angle] """ assert len(rotate_rect) == 9 self.update(rotate_rect) self.label = label def update(self, rotate_rect: List[int]): self.rotate_rect = rotate_rect self.x1 = rotate_rect[0] self.y1 = rotate_rect[1] self.x2 = rotate_rect[2] self.y2 = rotate_rect[3] self.x3 = rotate_rect[4] self.y3 = rotate_rect[5] self.x4 = rotate_rect[6] self.y4 = rotate_rect[7] self.angle = rotate_rect[8] self.center = (self.x1 + self.x3) / 2, (self.y1 + self.y3) / 2 self.cx = self.center[0] self.cy = self.center[1] self.points = [ (rotate_rect[0], rotate_rect[1]), (rotate_rect[2], rotate_rect[3]), (rotate_rect[4], rotate_rect[5]), (rotate_rect[6], rotate_rect[7]), ] self.poly = Polygon(self.points) self.meaningful_angle = self.get_meaningful_angle() def ioo(self, other: Union["RBox", Polygon]): if self.poly.area == 0: return 0 if isinstance(other, Polygon): inter = self.poly.intersection(other).area else: inter = self.poly.intersection(other.poly).area return inter / self.poly.area def _is_same(self, rbox: "RBox"): for i in range(9): if self.rotate_rect[i] != rbox.rotate_rect[i]: return False return True def get_meaningful_angle(self): # 返回易于理解的angle # 当框为顺时针旋转时,返回的角度大于0 ordered_points = order_points(np.array(self.points)) self.up_left = ordered_points[0, :] self.up_right = ordered_points[1, :] self.down_right = ordered_points[2, :] self.down_left = ordered_points[3, :] angle = ( np.arctan2( [self.up_right[1] - self.up_left[1]], [self.up_right[0] - self.up_left[0]], ) / np.pi * 180 ) return angle[0] def get_relative_rbox(self, center_point, delta_l, delta_t, delta_r, delta_b, angle=None): # delta_xxx 为非负数 相对center_point的偏移 """ 用于找和当前rbox倾斜角度一样的rbox,通常用于以背景框找前景框,center_point为锚点,delta_ltrb为各个边距锚点的距离 """ p1 = (-delta_l, delta_b) p2 = (delta_r, delta_b) p3 = (delta_r, -delta_t) p4 = (-delta_l, -delta_t) points = [p4, p3, p2, p1] # p1-4为左上角起顺时针四点的转正后坐标系的坐标,本函数目的是求该四个点转正前的坐标,注意直角坐标系y轴向上 # 先按本rbox的angle旋转 if angle is None: angle = self.meaningful_angle theta = -angle cos_theta = math.cos(theta / 180 * math.pi) sin_theta = math.sin(theta / 180 * math.pi) rotated_points = [] for point in points: x = point[0] * cos_theta + point[1] * sin_theta y = -point[0] * sin_theta + point[1] * cos_theta rotated_points.append((x, y)) # 平移,将up_left_point 从原点 trans_point = [] for point in rotated_points: x = int(point[0] + center_point[0]) y = int(point[1] + center_point[1]) trans_point.extend([x, y]) return RBox([*trans_point[0:8], angle]) @property def height(self): return np.sqrt( (self.up_left[0] - self.down_left[0]) ** 2 + (self.up_left[1] - self.down_left[1]) ** 2 ) @staticmethod def from_RotatedBoxWithLabel(data: RotatedBoxWithLabel) -> "RBox": return RBox( [ data.bbox.x1, data.bbox.y1, data.bbox.x2, data.bbox.y2, data.bbox.x3, data.bbox.y3, data.bbox.x4, data.bbox.y4, data.bbox.angle, ], label=data.label, ) @property def width(self): return np.sqrt( (self.up_left[0] - self.up_right[0]) ** 2 + \ (self.up_left[1] - self.up_right[1]) ** 2 ) def __eq__(self, other: "RBox"): return self._is_same(other) def __ne__(self, other: "RBox"): return not self._is_same(other) def __getitem__(self, index): return self.rotate_rect[index] def __len__(self): return len(self.rotate_rect) def __str__(self): return "[%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f]" % tuple(self.rotate_rect)
#Import library from shapely.geometry import Polygon #This script calculates the proportion area of square amoug a list of sqaure #Parameters polygon_to_test1 = Polygon([(0, 0), (0, 0.5), (1, 0.5), (1, 0)]) polygon_to_test2 = Polygon([(0, 0), (0, 0.5),(0.5, 0.5), (0, 0.5) ]) polygon_to_test=[polygon_to_test1,polygon_to_test1] polygon_ref_1 = Polygon([(0, 0), (0, 2), (2, 2), (2, 0)]) polygon_ref_2 = Polygon([(0, 0), (0, 3), (2, 3), (2, 0)]) nombre_imagette_oiseau=0 for i in polygon_to_test: intersection_1=polygon_ref_1.intersection(i) intersection_2=polygon_ref_2.intersection(i) proportion_1=intersection_1.area/polygon_ref_1.area proportion_2=intersection_2.area/polygon_ref_2.area max_proportion_test1=max(proportion_1,proportion_2) if (max_proportion_test1>0.5) : nombre_imagette_oiseau+=1 print(nombre_imagette_oiseau)
def area_of_intersection(det_x, det_y, gt_x, gt_y): p1 = Polygon(np.stack([det_x, det_y], axis=1)).buffer(0) p2 = Polygon(np.stack([gt_x, gt_y], axis=1)).buffer(0) return float(p1.intersection(p2).area)
def seed_neurons(self, neurons=None, container=None, on_area=None, xmin=None, xmax=None, ymin=None, ymax=None, soma_radius=0, unit=None, return_quantity=None): ''' Return the positions of the neurons inside the :class:`Shape`. Parameters ---------- neurons : int, optional (default: None) Number of neurons to seed. This argument is considered only if the :class:`Shape` has no `parent`, otherwise, a position is generated for each neuron in `parent`. container : :class:`Shape`, optional (default: None) Subshape acting like a mask, in which the neurons must be contained. The resulting area where the neurons are generated is the :func:`~shapely.Shape.intersection` between of the current shape and the `container`. on_area : str or list, optional (default: None) Area(s) where the seeded neurons should be. xmin : double, optional (default: lowest abscissa of the Shape) Limit the area where neurons will be seeded to the region on the right of `xmin`. xmax : double, optional (default: highest abscissa of the Shape) Limit the area where neurons will be seeded to the region on the left of `xmax`. ymin : double, optional (default: lowest ordinate of the Shape) Limit the area where neurons will be seeded to the region on the upper side of `ymin`. ymax : double, optional (default: highest ordinate of the Shape) Limit the area where neurons will be seeded to the region on the lower side of `ymax`. unit : string (default: None) Unit in which the positions of the neurons will be returned, among 'um', 'mm', 'cm', 'dm', 'm'. return_quantity : bool, optional (default: False) Whether the positions should be returned as ``pint.Quantity`` objects (requires Pint). .. versionchanged:: 0.5 Accepts `pint` units and `return_quantity` argument. Note ---- If both `container` and `on_area` are provided, the intersection of the two is used. Returns ------- positions : array of double with shape (N, 2) or `pint.Quantity` if `return_quantity` is `True`. ''' return_quantity = (self._return_quantity if return_quantity is None else return_quantity) if return_quantity: unit = self._unit if unit is None else unit if not _unit_support: raise RuntimeError("`return_quantity` requested but Pint is " "not available. Please install it first.") if _unit_support: from .units import Q_ if isinstance(xmin, Q_): xmin = xmin.m_as(unit) if isinstance(xmax, Q_): xmax = xmax.m_as(unit) if isinstance(ymin, Q_): ymin = ymin.m_as(unit) if isinstance(ymax, Q_): ymax = ymax.m_as(unit) if isinstance(soma_radius, Q_): soma_radius = soma_radius.m_as(unit) positions = None if neurons is None and self._parent is not None: neurons = self._parent.node_nb() if neurons is None: raise ValueError("`neurons` cannot be None if `parent` is None.") if on_area is not None: if not hasattr(on_area, '__iter__'): on_area = [on_area] min_x, min_y, max_x, max_y = self.bounds custom_shape = (container is not None) if container is None and on_area is None: # set min/max if xmin is None: xmin = -np.inf if ymin is None: ymin = -np.inf if xmax is None: xmax = np.inf if ymax is None: ymax = np.inf min_x = max(xmin, min_x) # smaller that Shape max x assert min_x <= self.bounds[2], "`min_x` must be inside Shape." min_y = max(ymin, min_y) # smaller that Shape max y assert min_y <= self.bounds[3], "`min_y` must be inside Shape." max_x = min(xmax, max_x) # larger that Shape min x assert max_x >= self.bounds[0], "`max_x` must be inside Shape." max_y = min(ymax, max_y) # larger that Shape min y assert max_y >= self.bounds[1], "`max_y` must be inside Shape." # remaining tests if self._geom_type == "Rectangle": xx = uniform(min_x + soma_radius, max_x - soma_radius, size=neurons) yy = uniform(min_y + soma_radius, max_y - soma_radius, size=neurons) positions = np.vstack((xx, yy)).T elif (self._geom_type == "Disk" and (xmin, ymin, xmax, ymax) == self.bounds): theta = uniform(0, 2 * np.pi, size=neurons) # take some precaution to stay inside the shape r = (self.radius - soma_radius) *\ np.sqrt(uniform(0, 0.99, size=neurons)) positions = np.vstack((r * np.cos(theta) + self.centroid[0], r * np.sin(theta) + self.centroid[1])).T else: custom_shape = True container = Polygon([(min_x, min_y), (min_x, max_y), (max_x, max_y), (max_x, min_y)]) elif on_area is not None: custom_shape = True area_shape = Polygon() for area in on_area: area_shape = area_shape.union(self._areas[area]) if container is not None: container = container.intersection(area_shape) else: container = area_shape assert container.area > 0, "`container` and `on_area` have " +\ "empty intersection." # enter here only if Polygon or `container` is not None if custom_shape: seed_area = self.intersection(container) area_buffer = seed_area.buffer(-soma_radius) if not area_buffer.is_empty: seed_area = area_buffer assert not seed_area.is_empty, "Empty area for seeding, check " +\ "your `container` and min/max values." if not isinstance(seed_area, (Polygon, MultiPolygon)): raise ValueError("Invalid boundary value for seed region; " "check that the min/max values you requested " "are inside the shape.") if _opengl_support: triangles = [] if isinstance(seed_area, MultiPolygon): for g in seed_area.geoms: triangles.extend((Polygon(v) for v in triangulate(g))) else: triangles = [Polygon(v) for v in triangulate(seed_area)] positions = rnd_pts_in_tr(triangles, neurons) else: logger.warning("Random point generation can be very slow " "without advanced triangulation methods. " "Please install PyOpenGL for faster seeding " "inside complex shapes.") points = [] while len(points) < neurons: new_x = uniform(min_x, max_x, neurons - len(points)) new_y = uniform(min_y, max_y, neurons - len(points)) for x, y in zip(new_x, new_y): p = Point(x, y) if seed_area.contains(p): points.append((x, y)) positions = np.array(points) if unit is not None and unit != self._unit: positions *= conversion_magnitude(unit, self._unit) if _unit_support and return_quantity: from .units import Q_ return positions * Q_("um" if unit is None else unit) return positions
def clean(self, handPoints, mainImg): cleanWeight = 0.01 hand = Polygon(handPoints) if self.frontExposed: face = Polygon(self.frontPoints) try: if face.intersects(hand): intersectionPoly = face.intersection( hand) # IMPOSSIBLE GEOMETRY PROBLEM intersectionPoly = list(intersectionPoly.exterior.coords) intersectionMask = np.zeros( (mainImg.shape[0], mainImg.shape[1]), np.uint8) cv2.fillPoly(intersectionMask, [np.int32(intersectionPoly)], (255, 255, 255)) tempColor = np.zeros( (mainImg.shape[0], mainImg.shape[1], 3), np.uint8) tempColor[:] = self.color transformPerspective = cv2.getPerspectiveTransform( np.array(self.frontPoints, dtype="float32"), np.array([[0, 0], [memSize_X, 0], [memSize_X, memSize_Y], [0, memSize_Y]], dtype="float32")) intersectionMask = cv2.bitwise_and(tempColor, tempColor, mask=intersectionMask) intersectionMask = cv2.warpPerspective( intersectionMask, transformPerspective, (memSize_X, memSize_Y)) self.frontFace = cv2.addWeighted(self.frontFace, 1.0, intersectionMask, cleanWeight, 0) except shapely.errors.TopologicalError: pass if self.backExposed: face = Polygon(self.backPoints) try: if face.intersects(hand): intersectionPoly = face.intersection(hand) intersectionPoly = list(intersectionPoly.exterior.coords) intersectionMask = np.zeros( (mainImg.shape[0], mainImg.shape[1]), np.uint8) cv2.fillPoly(intersectionMask, [np.int32(intersectionPoly)], (255, 255, 255)) tempColor = np.zeros( (mainImg.shape[0], mainImg.shape[1], 3), np.uint8) tempColor[:] = self.color transformPerspective = cv2.getPerspectiveTransform( np.array(self.backPoints, dtype="float32"), np.array([[0, 0], [memSize_X, 0], [memSize_X, memSize_Y], [0, memSize_Y]], dtype="float32")) intersectionMask = cv2.bitwise_and(tempColor, tempColor, mask=intersectionMask) intersectionMask = cv2.warpPerspective( intersectionMask, transformPerspective, (memSize_X, memSize_Y)) self.backFace = cv2.addWeighted(self.backFace, 1.0, intersectionMask, cleanWeight, 0) except shapely.errors.TopologicalError: pass if self.topExposed: face = Polygon(self.topPoints) try: if face.intersects(hand): intersectionPoly = face.intersection(hand) intersectionPoly = list(intersectionPoly.exterior.coords) intersectionMask = np.zeros( (mainImg.shape[0], mainImg.shape[1]), np.uint8) cv2.fillPoly(intersectionMask, [np.int32(intersectionPoly)], (255, 255, 255)) tempColor = np.zeros( (mainImg.shape[0], mainImg.shape[1], 3), np.uint8) tempColor[:] = self.color transformPerspective = cv2.getPerspectiveTransform( np.array(self.topPoints, dtype="float32"), np.array([[0, 0], [memSize_X, 0], [memSize_X, memSize_Y], [0, memSize_Y]], dtype="float32")) intersectionMask = cv2.bitwise_and(tempColor, tempColor, mask=intersectionMask) intersectionMask = cv2.warpPerspective( intersectionMask, transformPerspective, (memSize_X, memSize_Y)) self.topFace = cv2.addWeighted(self.topFace, 1.0, intersectionMask, cleanWeight, 0) except shapely.errors.TopologicalError: pass if self.bottomExposed: face = Polygon(self.bottomPoints) try: if face.intersects(hand): intersectionPoly = face.intersection(hand) intersectionPoly = list(intersectionPoly.exterior.coords) intersectionMask = np.zeros( (mainImg.shape[0], mainImg.shape[1]), np.uint8) cv2.fillPoly(intersectionMask, [np.int32(intersectionPoly)], (255, 255, 255)) tempColor = np.zeros( (mainImg.shape[0], mainImg.shape[1], 3), np.uint8) tempColor[:] = self.color transformPerspective = cv2.getPerspectiveTransform( np.array(self.bottomPoints, dtype="float32"), np.array([[0, 0], [memSize_X, 0], [memSize_X, memSize_Y], [0, memSize_Y]], dtype="float32")) intersectionMask = cv2.bitwise_and(tempColor, tempColor, mask=intersectionMask) intersectionMask = cv2.warpPerspective( intersectionMask, transformPerspective, (memSize_X, memSize_Y)) self.bottomFace = cv2.addWeighted(self.bottomFace, 1.0, intersectionMask, cleanWeight, 0) except shapely.errors.TopologicalError: pass if self.leftExposed: face = Polygon(self.leftPoints) try: if face.intersects(hand): intersectionPoly = face.intersection(hand) intersectionPoly = list(intersectionPoly.exterior.coords) intersectionMask = np.zeros( (mainImg.shape[0], mainImg.shape[1]), np.uint8) cv2.fillPoly(intersectionMask, [np.int32(intersectionPoly)], (255, 255, 255)) tempColor = np.zeros( (mainImg.shape[0], mainImg.shape[1], 3), np.uint8) tempColor[:] = self.color transformPerspective = cv2.getPerspectiveTransform( np.array(self.leftPoints, dtype="float32"), np.array([[0, 0], [memSize_X, 0], [memSize_X, memSize_Y], [0, memSize_Y]], dtype="float32")) intersectionMask = cv2.bitwise_and(tempColor, tempColor, mask=intersectionMask) intersectionMask = cv2.warpPerspective( intersectionMask, transformPerspective, (memSize_X, memSize_Y)) self.leftFace = cv2.addWeighted(self.leftFace, 1.0, intersectionMask, cleanWeight, 0) except shapely.errors.TopologicalError: pass if self.rightExposed: face = Polygon(self.rightPoints) try: if face.intersects(hand): intersectionPoly = face.intersection(hand) intersectionPoly = list(intersectionPoly.exterior.coords) intersectionMask = np.zeros( (mainImg.shape[0], mainImg.shape[1]), np.uint8) cv2.fillPoly(intersectionMask, [np.int32(intersectionPoly)], (255, 255, 255)) tempColor = np.zeros( (mainImg.shape[0], mainImg.shape[1], 3), np.uint8) tempColor[:] = self.color transformPerspective = cv2.getPerspectiveTransform( np.array(self.rightPoints, dtype="float32"), np.array([[0, 0], [memSize_X, 0], [memSize_X, memSize_Y], [0, memSize_Y]], dtype="float32")) intersectionMask = cv2.bitwise_and(tempColor, tempColor, mask=intersectionMask) intersectionMask = cv2.warpPerspective( intersectionMask, transformPerspective, (memSize_X, memSize_Y)) self.rightFace = cv2.addWeighted(self.rightFace, 1.0, intersectionMask, cleanWeight, 0) except shapely.errors.TopologicalError: pass
def calc_iou(poly1, poly2): assert(len(poly1) == 4 and len(poly2) == 4) a = Polygon([(p['x'], p['y']) for p in poly1]) b = Polygon([(p['x'], p['y']) for p in poly2]) return a.intersection(b).area / a.union(b).area
class Gui: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) self.clock = pygame.time.Clock() self.mode = INTERIOR_POLY self.angle_center_pos = 0.0 def new(self): self.interior_poly_points = [] self.exterior_poly_points = [] self.checkpoint_lines = [] self.interior_polygon = None self.exterior_polygon = None def run(self): self.playing = True while self.playing: self.dt = self.clock.tick( FPS) / 1000 # Controls update speed (FPS per second) self.events() self.update() self.draw() def close(self): pygame.quit() quit() def update(self): pygame.display.set_caption(f"{TITLE} || Mode: {self.mode}") def draw(self): self.screen.fill(COLORS['grass']) # Draw interior polygon point_rad = 30 for x, y in self.interior_poly_points: pygame.gfxdraw.aacircle(self.screen, x, y, point_rad, COLORS["red"]) if (len(self.interior_poly_points) >= 3): pygame.gfxdraw.aapolygon(self.screen, self.interior_poly_points, COLORS["red"]) # Draw interior polygon point_rad = 30 for x, y in self.exterior_poly_points: pygame.gfxdraw.aacircle(self.screen, x, y, point_rad, COLORS["blue"]) if (len(self.exterior_poly_points) >= 3): pygame.gfxdraw.aapolygon(self.screen, self.exterior_poly_points, COLORS["blue"]) # Draw checkpoint lines for i, p in enumerate(self.checkpoint_lines): x1, y1 = p[0] x2, y2 = p[1] color = Color("#000000") if i == 0: color = COLORS["green"] elif i == len(self.checkpoint_lines) - 1: color = COLORS["red"] pygame.gfxdraw.line(self.screen, int(x1), int(y1), int(x2), int(y2), color) pygame.display.flip() def events(self): # catch all events here mx, my = pygame.mouse.get_pos() for event in pygame.event.get(): if event.type == pygame.QUIT: self.close() if event.type == pygame.KEYDOWN: if event.key == pygame.K_1: self.mode = INTERIOR_POLY if event.key == pygame.K_2: self.mode = EXTERIOR_POLY if event.key == pygame.K_3: self.mode = CHECKPOINT if event.key == pygame.K_4: self.mode = SPAWN_DIRECTION if event.key == pygame.K_RETURN: print("> Storing data ...") output = { "interior_poly": self.interior_poly_points, "exterior_poly": self.exterior_poly_points, "checkpoints": self.checkpoint_lines } if type(self.angle_center_pos) == float: output["direction"] = self.angle_center_pos else: output["direction"] = False with open('Tracks/track_data.json', 'w') as f: json.dump(output, f, indent=4) print("> Successfully stored data") if event.type == pygame.MOUSEBUTTONDOWN: if self.mode == INTERIOR_POLY: self.interior_poly_points.append([mx, my]) if len(self.interior_poly_points) >= 3: self.interior_polygon = Polygon( self.interior_poly_points) if self.mode == EXTERIOR_POLY: self.exterior_poly_points.append([mx, my]) if len(self.exterior_poly_points) >= 3: self.exterior_polygon = Polygon( self.exterior_poly_points) if self.mode == CHECKPOINT: # Check if location is within proper bounds pos = [mx, my] p_pos = Point(pos) if not (self.exterior_polygon and self.interior_polygon): return if not (self.exterior_polygon.contains(p_pos) and not self.interior_polygon.contains(p_pos)): return default_half_length = 800 half_length = default_half_length degrees = 360 skip = 2 exterior_intersections = [] interior_intersections = [] for i in range(0, degrees, skip): p1 = [ pos[0] + cos(radians(i)) * half_length, pos[1] + sin(radians(i)) * half_length ] p_p1 = Point(p1) l1 = LineString([p1, pos]) try: interior_i = self.interior_polygon.intersection( l1).coords interior_i = [x for x in interior_i] interior_i.sort(key=lambda x: hypot( pos[0] - x[0], pos[1] - x[1])) exterior_i = self.exterior_polygon.exterior.intersection( l1).coords except: continue if len(interior_i) > 0: dist = hypot(pos[0] - interior_i[0][0], pos[1] - interior_i[0][1]) interior_intersections.append( [dist, interior_i[0]]) else: #intersects b dist = hypot(pos[0] - exterior_i[0][0], pos[1] - exterior_i[0][1]) exterior_intersections.append( [dist, exterior_i[0]]) interior_intersections.sort(key=lambda x: x[0]) exterior_intersections.sort(key=lambda x: x[0]) final_checkpoint_line = [ interior_intersections[0][1], exterior_intersections[0][1] ] self.checkpoint_lines.append(final_checkpoint_line) if self.mode == SPAWN_DIRECTION: if type(self.angle_center_pos) == float: self.angle_center_pos = [mx, my] else: self.angle_center_pos = atan2( self.angle_center_pos[0] - mx, self.angle_center_pos[1] - my) print("Angle set to: ", self.angle_center_pos * (180 / pi))
def polygon_split(polygon: Polygon, split_line: LineString) -> Optional[Tuple[Polygon, Polygon]]: """Split a polygon into two other polygons along split_line. Attempts to split a polygon into two other polygons. Here, a number of assumptions has to be made. That is, that split_line is a proper line connecting boundaries of a polygon. Also, that split_line does not connect outside boundary to a boundary of hole. This is a undefined behaviour. TODO: With current implementation, it may be possible to do non-decomposing cuts. But, some thought needs to be put in. Assumptions: Input polygon and split_line are valid. Args: polygon: Shapely polygon object. split_line: Shapely LineString object. Returns: (P1, P2): A tuple of Shapely polygons resulted from the split. If error occured, returns []. """ # This calculates the points on the boundary where the split will happen. ext_line = polygon.exterior common_pts = ext_line.intersection(split_line) logger.debug("Cut: %s Intersection: %s" % (split_line, common_pts)) # No intersection check. if not common_pts: return None # This intersection should always have only 2 points. if not isinstance(common_pts, MultiPoint): return None # Should only ever contain two points. if len(common_pts) != 2: return None # Split line should be inside polygon. if not split_line.within(polygon): return None # Check to see if cut line touches any holes for hole in polygon.interiors: if split_line.intersects(hole): return None split_boundary = ext_line.difference(split_line) # Check that split_boundary is a collection of linestrings if not isinstance(split_boundary, MultiLineString): return None # Make sure there are only 2 linestrings in the collection if len(split_boundary) > 3 or len(split_boundary) < 2: return None logger.debug("Split boundary: %s", split_boundary) # Even though we use LinearRing, there is no wrap around and diff produces # 3 strings. Need to union. Not sure if combining 1st and last strings # is guaranteed to be the right combo. For now, place a check. if len(split_boundary) == 3: if split_boundary[0].coords[0] != split_boundary[-1].coords[-1]: logger.warn( "The assumption that pts0[0] == pts2[-1] DOES not hold. Need" " to investigate.") return None line1 = LineString( list( list(split_boundary[-1].coords)[:-1] + list(split_boundary[0].coords))) else: line1 = split_boundary[0] line2 = split_boundary[1] if len(line1.coords) < 3 or len(line2.coords) < 3: return None mask1 = Polygon(line1) mask2 = Polygon(line2) if (not mask1.is_valid) or (not mask2.is_valid): return None res_p1_pol = polygon.intersection(mask1) res_p2_pol = polygon.intersection(mask2) if not isinstance(res_p1_pol, Polygon): return None if not isinstance(res_p2_pol, Polygon): return None if not res_p1_pol.is_valid: return None if not res_p2_pol.is_valid: return None return res_p1_pol, res_p2_pol
def determine_occupancy(indexes, box): global slot2Value, slot3Value slot2Value = 0 slot3Value = 0 boxess = [] ROI_car = [] ED = [] perc_ED = [] temp = [] IoU = [] Status = [] diagonal_slot = [] centroid_slot_x = [] centroid_slot_y = [] area_slot = [] carX = 0 carY = 0 allCentroidCar = [] ED = [] perc_ED = [] Status = [] min_ed_car = [] car_id = [] count = 0 idx_and_car = [] idx_car_list = [] IoU = [] slotImage = [] carImage = [] iou = [] car_idx = [] # Load koodinat npy ROI_slot = np.load('coordinate/camera8.npy', allow_pickle=True) for i in range(len(indexes)): boxess.append([]) boxess[i].append(box[i][0]) boxess[i].append(box[i][1]) boxess[i].append(box[i][2] + box[i][0]) boxess[i].append(box[i][3] + box[i][1]) for i in range(len(indexes)): ROI_car.append([(boxess[i][0], boxess[i][3]), (boxess[i][0], boxess[i][1]), (boxess[i][2], boxess[i][1]), (boxess[i][2], boxess[i][3])]) # inisialisasi array for i in range(len(ROI_slot)): new = [] new1 = [] new2 = [] new3 = [0, 0] for j in (ROI_slot[i]): new.append(0) new1.append(0) new2.append(0) diagonal_slot.append(new) centroid_slot_x.append(new1) centroid_slot_y.append(new2) for i in range(len(ROI_slot)): new = [] for j in (ROI_slot[i]): new.append(0) area_slot.append(new) for row in range(len(ROI_slot)): for slots in range(len(ROI_slot[row])): x1 = ROI_slot[row][slots][0][0] y1 = ROI_slot[row][slots][0][1] x2 = ROI_slot[row][slots][1][0] y2 = ROI_slot[row][slots][1][1] x3 = ROI_slot[row][slots][2][0] y3 = ROI_slot[row][slots][2][1] x4 = ROI_slot[row][slots][3][0] y4 = ROI_slot[row][slots][3][1] # menghitung centroid slot centroid_slot_x[row][slots] = (x3 + x1) / 2 centroid_slot_y[row][slots] = (y3 + y1) / 2 d1 = math.sqrt(((y3 - y1)**2) + ((x3 - x1)**2)) d2 = math.sqrt(((y4 - y2)**2) + ((x4 - x2)**2)) if d1 < d2: diagonal_slot[row][slots] = d1 else: diagonal_slot[row][slots] = d2 area_slot[row][slots] = (abs( ((x1 * y2 - y1 * x2) + (x2 * y3 - y2 * x3) + (x3 * y4 - y3 * x4) + (x4 * y1 - y4 * x1)) / 2)) # plotting slot parkir plottedImage = image.copy() rows, cols, channels = plottedImage.shape for i in range(len(ROI_slot)): new = [] new1 = [] new2 = [] for j in (ROI_slot[i]): new.append(0) new1.append(0) new2.append(0) ED.append(new) perc_ED.append(new) Status.append(new1) IoU.append(new2) # gambar titik centroid di mobil for car in range(len(ROI_car)): x1 = ROI_car[car][0][0] y1 = ROI_car[car][0][1] x3 = ROI_car[car][2][0] y3 = ROI_car[car][2][1] centroid_car_x = (x1 + x3) / 2 centroid_car_y = (y1 + y3) / 2 allCentroidCar.append((int(centroid_car_x), int(centroid_car_y))) mod = cv2.circle(plottedImage, (int(centroid_car_x), int(centroid_car_y)), 4, (0, 0, 255), -1) intersect = [] count = 0 for row in range(len(ROI_slot)): slotImage.append([]) carImage.append([]) iou.append([]) for slots in range(len(ROI_slot[row])): slotImage[row].append([]) carImage[row].append([]) iou[row].append([]) slotImage[row][slots] = np.zeros_like(image) carImage[row][slots] = np.zeros_like(image) centroid_slot_xx = centroid_slot_x[row][slots] centroid_slot_yy = centroid_slot_y[row][slots] # titik di slot mod = cv2.circle(plottedImage, (int(centroid_slot_xx), int(centroid_slot_yy)), 4, (0, 0, 255), -1) temp = [] temp2 = [] for car in range(len(ROI_car)): x1 = ROI_car[car][0][0] y1 = ROI_car[car][0][1] x3 = ROI_car[car][2][0] y3 = ROI_car[car][2][1] centroid_car_x = (x1 + x3) / 2 centroid_car_y = (y1 + y3) / 2 temp.append( math.sqrt(((centroid_slot_yy - centroid_car_y)**2) + ((centroid_slot_xx - centroid_car_x)**2))) temp2.append(car) p = Polygon(ROI_slot[row][slots]) q = Polygon(ROI_car[car]) intersect.append(q.intersection(p).area) min_ed = min(temp) idx = temp.index(min(temp)) idx_car = temp2[idx] idx_car_list.append(idx_car) min_ed_car.append([idx_car, row, slots, min_ed]) roi1 = np.array(ROI_slot[row][slots]) roi2 = np.array(ROI_car[idx_car]) cv2.fillPoly(slotImage[row][slots], pts=[roi1], color=(0, 0, 255)) cv2.fillPoly(carImage[row][slots], pts=[roi2], color=(0, 0, 255)) iou[row][slots] = cv2.bitwise_and(slotImage[row][slots], carImage[row][slots]) iouu = np.array(iou[row][slots]) # print(iouu) dst = cv2.add(plottedImage, iouu) plottedImage[0:rows, 0:cols] = dst ED[row][slots] = min(temp) perc_ED[row][slots] = (ED[row][slots] / diagonal_slot[row][slots]) * 100 max_intrsct = max(intersect) IoU[row][slots] = ((max_intrsct / area_slot[row][slots]) * 100) if perc_ED[row][slots] < 75: if IoU[row][slots] == 0: Status[row][slots] = 'VACANT' elif IoU[row][slots] > 0: Status[row][slots] = 'OCCUPIED' else: Status[row][slots] = 'VACANT' x = [min_ed_car[i][0] for i in range(len(min_ed_car))] h = max(idx_car_list) for count in range(h + 1): tempp = [] slott = [] for i in range(len(x)): if (x[i] in x[:i]) or (x[i] in x[i + 1:]): if x[i] == count: tempp.append(min_ed_car[i][3]) slott.append([min_ed_car[i][1], min_ed_car[i][2]]) if not tempp: minn = 99999 else: minn = min(tempp) indx = tempp.index(min(tempp)) for i in range(len(slott)): if (i == indx): ED[slott[i][0]][slott[i][1]] = minn perc_ED[slott[i][0]][slott[i][1]] = ( ED[slott[i][0]][slott[i][1]] / diagonal_slot[slott[i][0]][slott[i][1]]) * 100 if perc_ED[slott[i][0]][slott[i][1]] < 75: Status[slott[i][0]][slott[i][1]] = 'OCCUPIED' else: Status[slott[i][0]][slott[i][1]] = 'VACANT' else: Status[slott[i][0]][slott[i][1]] = 'VACANT' for row in range(len(ROI_slot)): for slots in range(len(ROI_slot[row])): if Status[row][slots] == 'OCCUPIED': slot2Value += 1 else: slot3Value += 1 fontScale = 0.8 for row in range(len(ROI_slot)): for slots in range(len(ROI_slot[row])): # draw ROI_slot mod = cv2.polylines(plottedImage, np.int32([ROI_slot[row][slots]]), True, (255, 0, 0), thickness=2) # draw Status_slot mod = cv2.putText(plottedImage, Status[row][slots], (int(centroid_slot_x[row][slots]) - 10, int(centroid_slot_y[row][slots])), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 255, 0), 1, cv2.LINE_AA) # Text slot # PENTING extY GANTI KE '0' UNTUK CAMERA 8 DAN '15' UNTUK CAMERA 1. BIAR TIDAK TUMPANG TINDIH extY = 0 minROISlot = min(ROI_slot[row][slots]) org = (minROISlot[0], minROISlot[1] + extY) slotId = "(" + str(row) + "-" + str(slots) + ")" font = cv2.FONT_HERSHEY_PLAIN cv2.putText(plottedImage, slotId, org, font, fontScale, (255, 255, 255), 1) for row in range(len(ROI_slot)): for slots in range(len(ROI_slot[row])): distancez = [] if Status[row][slots] == 'VACANT': continue else: centSlotX = int(centroid_slot_x[row][slots]) centSlotY = int(centroid_slot_y[row][slots]) for i in allCentroidCar: distancez.append( euclideanDistance((centSlotX, centSlotY), (i[0], i[1]))) minDistancezIndex = distancez.index(min(distancez)) centCarX = allCentroidCar[minDistancezIndex][0] centCarY = allCentroidCar[minDistancezIndex][1] mod = cv2.line(plottedImage, (centSlotX, centSlotY), (centCarX, centCarY), (0, 255, 255), 2) return plottedImage
def calculate_IOU_cornell(box_model, box_label): p1 = Polygon(box_model).convex_hull p2 = Polygon(box_label).convex_hull iou = p1.intersection(p2).area / (p1.area + p2.area - p1.intersection(p2).area) return iou