def enlarge_park_boundary(park_list):
    '''
    Takes a list of parks, enlarges their boundaries and stores in a 
    dictionary and returns it
    '''
    polygon_dict = {}
    enlarged_polygon_dict = {}
    for park in park_list:
        for k in range(len(park_dict[park])):
            for i in range(len(park_dict[park][k])):
                coordiante = park_dict[park][k][i][0]
                polygon = Polygon(coordiante)
                if park not in polygon_dict.keys():
                    polygon_dict[park] = [polygon]
                else:
                    polygon_dict[park].append(polygon)
#                x, y = polygon.exterior.xy
#                plt.figure(1)
#                plt.plot(x, y, 'k')

                enlarged_polygon = Polygon(polygon.buffer(0.0005).exterior)
                if park not in enlarged_polygon_dict.keys():
                    enlarged_polygon_dict[park] = [enlarged_polygon]
                else:
                    enlarged_polygon_dict[park].append(enlarged_polygon)
#                x1, y1 = enlarged_polygon.exterior.xy
#                plt.figure(1)
#                plt.plot(x1, y1, 'b')
#    plt.show()
    return enlarged_polygon_dict
示例#2
0
def _contour_to_poly(contour):
    poly = Polygon(contour)
    if not poly.is_valid:
        poly = poly.buffer(0)
    assert poly.is_valid, \
        "Contour %r did not make valid polygon %s because %s" \
        % (contour, poly.wkt, explain_validity(poly))
    return poly
示例#3
0
def hasCollision(line, obstacles):
    line_string = LineString([(line[0][0],line[0][1]),(line[1][0],line[1][1])])
    for obstacle in obstacles:
        polygon = Polygon(obstacle)
        polygon_small = polygon.buffer(-.01)
        if line_string.intersects(polygon_small):
	        return True
    return False
示例#4
0
def _contour_to_poly(contour):
    poly = Polygon(contour)
    if not poly.is_valid:
        poly = poly.buffer(0)
    assert poly.is_valid, \
        "Contour %r did not make valid polygon %s because %s" \
        % (contour, poly.wkt, explain_validity(poly))
    return poly
示例#5
0
    def buffer(self, distance=None, join_style=2):
        # type: (Optional[float], Optional[int]) -> Polygon2D
        """Returns a representation of all points within a given distance of the polygon.

        :param join_style: The styles of joins between offset segments: 1 (round), 2 (mitre), and 3 (bevel).

        """
        s_poly = SPoly(self.vertices)
        core = s_poly.buffer(distance=distance, join_style=join_style)
        return Polygon2D(core.boundary.coords)
示例#6
0
def s2polygon_from_shapely_polygon(shapely_polygon: Polygon) -> s2.S2Polygon:
  '''Convert a Shapely Polygon to S2Polygon.
  Arguments:
    shapely_polygon(Polygon): The Shapely Polygon to be
    converted to S2Polygon.
  Returns:
    The S2Polygon equivelent to the input Shapely Polygon.
  '''

  # Filter where shape has no exterior attributes (e.g. lines).
  if not hasattr(shapely_polygon.buffer(0.00005), 'exterior'):
    return
  else:
    # Add a small buffer for cases where cover doesn't work.
    list_coords = list(shapely_polygon.buffer(0.00005).exterior.coords)

  # Get list of points.
  s2point_list = list(map(s2point_from_coord_xy, list_coords))
  s2point_list = s2point_list[::-1]  # Counterclockwise.
  return s2.S2Polygon(s2.S2Loop(s2point_list))
示例#7
0
    def calculate_road_geometry(self,
                                resolution: float = 0.25,
                                fix_eps: float = 1e-2):
        """ Calculate the boundary Polygon of the road.
        Calculates boundaries of lanes as a sub-function.

        Args:
            resolution: Sampling resolution for geometries
            fix_eps: If positive, then the algorithm attempts to fix sliver geometry in the map with this threshold
        """
        if self.lanes is None or self.lanes.lane_sections == []:
            return

        self.calculate_center_lane(resolution)

        boundary = Polygon()
        for ls in self.lanes.lane_sections:
            start_segment = ls.center_lanes[0].reference_line
            sample_distances = np.linspace(0.0, ls.length,
                                           int(ls.length / resolution) + 1)

            previous_direction = None
            reference_segment = start_segment
            reference_widths = np.zeros_like(sample_distances)
            for lane in ls.all_lanes:
                current_direction = np.sign(lane.id)
                if previous_direction is None or previous_direction != current_direction:
                    reference_segment = start_segment
                    reference_widths = np.zeros_like(sample_distances)

                lane_boundary, reference_segment, segment_widths = \
                    lane.sample_geometry(sample_distances, start_segment, reference_segment, reference_widths)

                boundary = unary_union([boundary, lane_boundary])
                previous_direction = current_direction
                reference_widths += segment_widths

        if fix_eps > 0.0:
            boundary = boundary.buffer(fix_eps, 1, join_style=JOIN_STYLE.mitre) \
                .buffer(-fix_eps, 1, join_style=JOIN_STYLE.mitre)

        if not boundary.boundary.geom_type == "LineString":
            logger.warning(
                f"Boundary of road ID {self.id} is not a closed a loop!")

        self._boundary = boundary
示例#8
0
    def handlePolygons(polygon):

        shapelyPolygon = Polygon(polygon)

        # orients the polygon
        shapelyPolygon = orient(shapelyPolygon, -1)

        if not shapelyPolygon.is_valid or not shapelyPolygon.is_simple:
            shapelyPolygon = shapelyPolygon.buffer(0)

        if not isinstance(shapelyPolygon, Polygon):

            polygons = shapelyPolygon.geoms

            listOfPolygons = []

            for pol in polygons:
                listOfPolygons.append(list(pol.exterior.coords))

            return listOfPolygons

        else:

            listOfPolygons = []

            if isinstance(shapelyPolygon, Polygon):

                try:

                    listOfPolygons.append(list(shapelyPolygon.exterior.coords))

                except AttributeError:

                    listOfPolygons = []

        return listOfPolygons
def CorrelateStitchImages(dirname,
                          dirout,
                          stitchchannel,
                          chosenstitchgroup,
                          x1lim=-.05,
                          x2lim=1.05,
                          y1lim=-.05,
                          y2lim=1.05,
                          save_stitched=True,
                          save_multipage=True,
                          constant_size=250000000,
                          roll_ball=True,
                          use_gene_name=True,
                          save_merged=False):
    #dirname = os.path.expanduser('/wynton/group/ye/mtschmitz/images/MacaqueMotorCortex2/P2sagittal1_27_20200828/TR1.2020-09-03-01-35-13/')
    #Test params
    '''dirname = os.path.expanduser('/media/mt/Extreme SSD/MacaqueMotorCortex2/P2_OB_20200805/TR1.2020-08-06-23-10-18')
    dirout =os.path.expanduser('~/tmp/')
    stitchchannel='1'
    chosenstitchgroup='1'
    x1lim=0
    x2lim=1
    y1lim=0
    y2lim=1
    save_merged=False
    save_stitched=False
    save_multipage=True
    use_gene_name=True
    '''

    print(dirname, flush=True)
    ray.shutdown()
    num_cpus = 1  #psutil.cpu_count(logical=False)
    #set number of cores to use
    print('cpus:', num_cpus)
    ray.init(num_cpus=num_cpus)

    x1lim = float(x1lim)
    x2lim = float(x2lim)
    y1lim = float(y1lim)
    y2lim = float(y2lim)
    chosenstitchgroup = re.sub('TR_', "1", chosenstitchgroup)
    chosenstitchgroup = re.sub('TR', "", chosenstitchgroup)

    protocol = [x for x in os.listdir(dirname) if '.scanprotocol' in x][0]
    minoverlap = 0
    with open(os.path.join(dirname, protocol), 'r') as f:
        for line in f:
            try:
                #print(line)
                if 'MinOverlapPixel' in line:
                    minoverlap = float(line.split('>')[1].split('<')[0]) * 1.1
            except:
                pass

    n_locations = 0
    counting = False
    with open(os.path.join(dirname, protocol), 'r') as f:
        for line in f:
            try:
                if 'LocationIds' in line:
                    counting = ~counting
                elif counting:
                    n_locations += 1
            except:
                pass

    n_location = 1
    counting = False
    reference = False
    shapes = defaultdict(list)
    with open(os.path.join(dirname, protocol), 'r') as f:
        for line in f:
            try:
                if '<d2p1:ScanLocation>' in line:
                    counting = ~counting
                if counting and '<d10p1:_x>' in line:
                    x = float(line.split('>')[1].split('<')[0])
                if counting and '<d10p1:_y>' in line:
                    y = float(line.split('>')[1].split('<')[0])
                    shapes[str(n_location)].append((x, y))
                if '<d2p1:ReferencePoint ' in line:
                    counting = False
                    reference = True
                if reference and '<d10p1:_x>' in line:
                    xref = float(line.split('>')[1].split('<')[0])
                if reference and '<d10p1:_y>' in line:
                    yref = float(line.split('>')[1].split('<')[0])
                    reference = False
                    shapes[str(n_location)] = [
                        (x + xref, y + yref)
                        for x, y in shapes[str(n_location)]
                    ]
                    n_location += 1
                    xref = 0
                    yref = 0
            except:
                pass

    tags_to_get = [
        'SizeX', 'SizeY', 'ActualPositionX', 'ActualPositionY', 'Run Index',
        'Index', '"field" Index', 'TheC', 'AreaGrid AreaGridIndex', 'Name',
        '<Image ID="Image:" Name', 'ActualPositionZ'
    ]

    def get_tag(x, tp):
        return (re.search(x + '=' + '"([A-Za-z0-9_\./\\-]*)"', tp).group(1))

    @ray.remote
    def getTiffMetadata(f):
        f = open(f, 'rb')
        # Return Exif tags
        tags = exifread.process_file(f)
        tp = tags['Image ImageDescription'].values
        d = {}
        for tag in tags_to_get:
            d[tag] = get_tag(tag, tp)
        return (d)

    data = []
    for fname in sorted(os.listdir(dirname)):
        if fname.endswith(".TIF"):
            fpath = os.path.join(dirname, fname)
            path = os.path.normpath(dirname)
            d = path.split(os.sep)[-2]
            data.append((fname, d, fpath))
    imageFiles = pd.DataFrame(data, columns=['FileName', 'DirName', 'Path'])

    #normalize positions so starts at 0,0
    #imageFiles['ActualPositionX']=imageFiles['ActualPositionX']-imageFiles['ActualPositionX'].min()
    #imageFiles['ActualPositionY']=imageFiles['ActualPositionY']-imageFiles['ActualPositionY'].min()
    imageFiles = imageFiles.loc[['_R_' in x
                                 for x in imageFiles['FileName']], :]

    l = []
    for i in imageFiles.index:
        f = imageFiles.loc[i, 'Path']
        #d=getTiffMetadata(f)
        l.append(getTiffMetadata.remote(f))
        #print(d)
        #imageFiles.loc[i,d.keys()]=list(d.values())

    metadf = pd.DataFrame(ray.get(l))
    metadf.index = imageFiles.index
    imageFiles = imageFiles.join(metadf)
    ray.shutdown()

    imageFiles.rename(columns={'<Image ID="Image:" Name': 'Channel Name'},
                      inplace=True)

    imageFiles['ActualPositionX'] = imageFiles['ActualPositionX'].astype(float)
    imageFiles['ActualPositionY'] = imageFiles['ActualPositionY'].astype(float)
    #print(imageFiles['ActualPositionX'])
    #print(imageFiles['ActualPositionY'])
    imageFiles['SizeX'] = imageFiles['SizeX'].astype(float)
    imageFiles['SizeY'] = imageFiles['SizeY'].astype(float)
    imageFiles.sort_values(by=['"field" Index', 'Channel Name'], inplace=True)
    print(imageFiles, flush=True)
    #Max size
    chif = imageFiles  #.loc[imageFiles['Channel Name']==stitchchannel,:]
    chif['x1pix'] = 0
    chif['x2pix'] = 0
    chif['y1pix'] = 0
    chif['y2pix'] = 0
    xsize = imageFiles['SizeX'].value_counts().idxmax()
    ysize = imageFiles['SizeY'].value_counts().idxmax()
    xend = len(chif.ActualPositionX.unique()) * xsize
    yend = len(chif.ActualPositionY.unique()) * ysize

    #assume adjacent images are taken sequentially
    xd = []
    yd = []
    for i in range(len(chif['"field" Index'].unique()) - 1):
        indi = chif['"field" Index'] == list(chif['"field" Index'])[i]
        indip1 = chif['"field" Index'] == list(chif['"field" Index'])[i + 1]
        xdiff = np.abs(
            list(chif.loc[indi, 'ActualPositionX'])[0] -
            list(chif.loc[indip1, 'ActualPositionX'])[0])
        ydiff = np.abs(
            list(chif.loc[indi, 'ActualPositionY'])[0] -
            list(chif.loc[indip1, 'ActualPositionY'])[0])
        xd.append(xdiff)
        yd.append(ydiff)
    xd = np.array(xd)
    yd = np.array(yd)
    #nonzero (>10) median is the distance between images
    xmedian = np.median(xd[xd > 10])
    ymedian = np.median(yd[yd > 10])
    #for reference xsize-minoverlap=xmedian
    print('MEDIANS')
    print(xmedian, ymedian)

    from shapely.geometry import Point
    from shapely.geometry.polygon import Polygon
    polygon = Polygon(shapes[chosenstitchgroup])
    #Buffer expands, scale doesn't work for expanding linear regions with no points
    buffgon = Polygon(polygon.buffer(min(xmedian, ymedian)).exterior)
    #polygon=shapely.affinity.scale(polygon,xfact=1.2,yfact=1.2)
    inside = [
        buffgon.contains(Point(x, y))
        for x, y in list(zip(chif['ActualPositionX'], chif['ActualPositionY']))
    ]

    matplotlib.pyplot.scatter(list(chif['ActualPositionX']),
                              list(chif['ActualPositionY']))
    matplotlib.pyplot.scatter([x[0] for x in shapes[chosenstitchgroup]],
                              [x[1] for x in shapes[chosenstitchgroup]])
    matplotlib.pyplot.scatter(buffgon.exterior.coords.xy[0],
                              buffgon.exterior.coords.xy[1])
    matplotlib.pyplot.savefig(os.path.join(dirout, 'BufferPolygon.png'))
    matplotlib.pyplot.close()
    chif = chif.loc[inside, :]

    #normalize positions so starts at 0,0
    chif['ActualPositionX'] = chif['ActualPositionX'] - chif[
        'ActualPositionX'].min()
    chif['ActualPositionY'] = chif['ActualPositionY'] - chif[
        'ActualPositionY'].min()

    xorder = dict(
        zip(np.sort(chif['ActualPositionX'].unique()),
            np.sort(chif['ActualPositionX'].unique().argsort())))
    yorder = dict(
        zip(np.sort(chif['ActualPositionY'].unique()),
            np.sort(chif['ActualPositionY'].unique().argsort())))

    for i in chif.index:
        x = chif.loc[
            i,
            'ActualPositionX'] / xmedian  #xorder[chif.loc[i,'ActualPositionX']]
        y = chif.loc[
            i,
            'ActualPositionY'] / ymedian  #yorder[chif.loc[i,'ActualPositionY']]
        x1 = int((xsize * x) - (x * minoverlap))
        x2 = x1 + int(xsize)
        y1 = int((ysize * y) - (y * minoverlap))
        y2 = y1 + int(ysize)
        chif.loc[i, 'x1pix'] = x1
        chif.loc[i, 'x2pix'] = x2
        chif.loc[i, 'y1pix'] = y1
        chif.loc[i, 'y2pix'] = y2

    cf = chif.loc[chif['TheC'] == stitchchannel, :]
    cf['Image'] = None
    for i in tqdm.tqdm(cf.index):
        img = cv2.imread(cf.loc[i, 'Path'])[:, :, 0].T
        cf.loc[i, 'Image'] = [img]
    print(chif, flush=True)
    #print(cf.loc[2,'Image'].shape)
    #plt.imshow(cf.loc[2,'Image'],origin='lower')

    index = pynndescent.NNDescent(cf.loc[:, ['x1pix', 'y1pix']], n_neighbors=9)
    nn = index.query(cf.loc[:, ['x1pix', 'y1pix']], k=9)[0][:, 1:]

    g = networkx.DiGraph().to_undirected()
    for i, x in enumerate(nn):
        for j in x:
            g.add_edge(i, j)
    g = g.to_undirected()

    x1i = np.where(cf.columns == 'x1pix')[0][0]
    x2i = np.where(cf.columns == 'x2pix')[0][0]
    y1i = np.where(cf.columns == 'y1pix')[0][0]
    y2i = np.where(cf.columns == 'y2pix')[0][0]
    imgi = np.where(cf.columns == 'Image')[0][0]

    #could be modified with inner loop to get
    #average correlation of all channels
    #Downside of course is 4x processing time
    def correlateOffsets(x):
        xoffset, yoffset = x[0], x[1]
        for i in cf.index:
            x = cf.loc[
                i,
                'ActualPositionX'] / xmedian  #xorder[chif.loc[i,'ActualPositionX']]
            y = cf.loc[
                i,
                'ActualPositionY'] / ymedian  #yorder[chif.loc[i,'ActualPositionY']]
            x1 = int((xsize * x) - x * int(xoffset))
            x2 = x1 + int(xsize)
            y1 = int((ysize * y) - y * int(yoffset))
            y2 = y1 + int(ysize)
            cf.loc[i, 'x1pix'] = x1
            cf.loc[i, 'x2pix'] = x2
            cf.loc[i, 'y1pix'] = y1
            cf.loc[i, 'y2pix'] = y2

        i_vect = []
        j_vect = []
        for i, j in list(g.edges):
            ix1i = cf.iloc[i, x1i]
            iy1i = cf.iloc[i, y1i]
            ix2i = cf.iloc[i, x2i]
            iy2i = cf.iloc[i, y2i]
            jx1i = cf.iloc[j, x1i]
            jy1i = cf.iloc[j, y1i]
            jx2i = cf.iloc[j, x2i]
            jy2i = cf.iloc[j, y2i]

            p = Polygon([(ix1i, iy1i), (ix2i, iy1i), (ix2i, iy2i),
                         (ix1i, iy2i)])

            q = Polygon([(jx1i, jy1i), (jx2i, jy1i), (jx2i, jy2i),
                         (jx1i, jy2i)])

            if p.intersects(q):
                pqi = p.intersection(q)
                #x1,y1,x2,y2
                bounds = pqi.bounds
                ix1b, iy1b, ix2b, iy2b = bounds[0] - ix1i, bounds[
                    1] - iy1i, bounds[2] - ix2i, bounds[3] - iy2i
                jx1b, jy1b, jx2b, jy2b = bounds[0] - jx1i, bounds[
                    1] - jy1i, bounds[2] - jx2i, bounds[3] - jy2i

                rxi = np.intersect1d(np.arange(ix1i, ix2i),
                                     np.arange(bounds[0], bounds[2])) - ix1i
                rxj = np.intersect1d(np.arange(jx1i, jx2i),
                                     np.arange(bounds[0], bounds[2])) - jx1i
                ryi = np.intersect1d(np.arange(iy1i, iy2i),
                                     np.arange(bounds[1], bounds[3])) - iy1i
                ryj = np.intersect1d(np.arange(jy1i, jy2i),
                                     np.arange(bounds[1], bounds[3])) - jy1i
                rxi = rxi.astype(int)
                rxj = rxj.astype(int)
                ryi = ryi.astype(int)
                ryj = ryj.astype(int)

                if len(rxi) > 0 and len(rxj) > 0:
                    i_vect.append(
                        list(cf.iloc[i, imgi][rxi, ryi[:,
                                                       np.newaxis]].flatten()))
                    j_vect.append(
                        list(cf.iloc[j, imgi][rxj, ryj[:,
                                                       np.newaxis]].flatten()))
                    #plt.imshow(cf.iloc[i,imgi][rxi,ryi[:,np.newaxis]],origin='lower')
                    #plt.show()
                    #plt.imshow(cf.iloc[j,imgi][rxj,ryj[:,np.newaxis]],origin='lower')
                    #plt.show()
                #x,y = p.exterior.xy
                #plt.plot(x,y)
                #x,y = q.exterior.xy
                #plt.plot(x,y)
                #x,y = pqi.exterior.xy
                #plt.plot(x,y)
                #plt.show()

        i_vect = [item for sublist in i_vect for item in sublist]
        j_vect = [item for sublist in j_vect for item in sublist]
        corr = 1 - np.corrcoef(i_vect, j_vect)[1, 0]
        #print(corr)
        return (corr)

    #opt=scipy.optimize.brute(correlateOffsets,(slice(30,500),slice(30,500)),full_output=True,disp=False,workers=num_cpus)
    opt = scipy.optimize.minimize(correlateOffsets,
                                  (minoverlap * 2.5, minoverlap * 2.5),
                                  method='Nelder-Mead',
                                  options={
                                      'xtol': .9,
                                      'ftol': .05
                                  })

    chif['final_identifier'] = chif['TheC']
    if use_gene_name:
        l = []
        for x in chif['FileName']:
            if x.startswith('L_'):
                l.append('1')
                continue
            if x.startswith('R_'):
                l.append('2')
                continue
            if '_TR_' in x:
                l.append('1')
                continue
            if '_TD_' in x:
                l.append('1')
                continue
            if 'TR' in x or 'TD' in x:
                groupnum = re.sub('TR|TD', '',
                                  re.search('TD[0-9]|TR[0-9]', x).group(0))
                l.append(groupnum)
                continue
            l.append(chosenstitchgroup)

        chif['stitchgroup'] = l
        tmppath = os.path.expanduser('~/imagingmetadata.csv')
        if os.path.exists(tmppath):
            refdf = pd.read_csv(tmppath, sep='\t')
        else:
            refdf = pd.read_csv(
                'https://docs.google.com/spreadsheets/d/e/2PACX-1vSYbvCJpS-GfRKuGgs2IBH7MD1KtDPDqs7ePqQJ1PyrMKp7f7z7ZpY4WtMFGPxU4mWbnRHgBl4PtaeH/pub?output=tsv&gid=1520792104',
                sep='\t')
            refdf.to_csv(tmppath, sep='\t')

        refdf.rename(columns={
            'Channel0': '0',
            'Channel1': '1',
            'Channel2': '2',
            'Channel3': '3'
        },
                     inplace=True)
        chif = pd.merge(chif,
                        refdf,
                        how='left',
                        left_on=['DirName', 'stitchgroup'],
                        right_on=['DirName', 'SlidePosition.1isL'])
        chif['gene'] = list(
            [chif.loc[chif.index[i], x] for i, x in enumerate(chif['TheC'])])
        chif['final_identifier'] = chif['gene']
    else:
        chif['final_identifier'] = chif['TheC']

    xoffset = opt.x[0]
    yoffset = opt.x[1]
    #xoffset=218
    #yoffset=209

    for i in chif.index:
        x = chif.loc[
            i,
            'ActualPositionX'] / xmedian  #xorder[chif.loc[i,'ActualPositionX']]
        y = chif.loc[
            i,
            'ActualPositionY'] / ymedian  #yorder[chif.loc[i,'ActualPositionY']]
        x1 = int((xsize * x) - x * int(xoffset))
        x2 = x1 + int(xsize)
        y1 = int((ysize * y) - y * int(yoffset))
        y2 = y1 + int(ysize)
        chif.loc[i, 'x1pix'] = x1
        chif.loc[i, 'x2pix'] = x2
        chif.loc[i, 'y1pix'] = y1
        chif.loc[i, 'y2pix'] = y2
    print('before min subtract')
    print(chif)
    xmin = chif['x1pix'].min()
    ymin = chif['y1pix'].min()

    chif['x1pix'] = chif['x1pix'] - xmin
    chif['x2pix'] = chif['x2pix'] - xmin
    chif['y1pix'] = chif['y1pix'] - ymin
    chif['y2pix'] = chif['y2pix'] - ymin

    def write_stitchy(chdf, infile, keyname='FileName'):
        with open(infile, 'w') as the_file:
            the_file.write('dim = 2\n')
            for i in chdf.index:
                cur = chdf.loc[i, :]
                the_file.write(cur[keyname] + '; ; (' + str(cur['x1pix']) +
                               ',' + str(cur['y1pix']) + ') \n')

    #for imagej merge on the fly
    for c in chif['final_identifier'].unique():
        cf = chif.loc[chif['final_identifier'] == c, :]
        infile = os.path.join(
            dirout,
            str(chosenstitchgroup) + '_' + stitchchannel + '.stitchy')
        write_stitchy(cf, infile, keyname='FileName')

    print(chif)
    #Or write whole file
    if save_stitched:
        for c in chif['final_identifier'].unique():
            cf = chif.loc[chif['final_identifier'] == c, :]
            cf['Image'] = None
            for i in cf.index:
                img = cv2.imread(cf.loc[i, 'Path'])[:, :, 0].T
                cf.loc[i, 'Image'] = [img]
            newimg = np.zeros(
                (int(np.nanmax(cf['x2pix'])), int(np.nanmax(cf['y2pix']))),
                np.uint8)
            divisor = np.zeros(
                (int(np.nanmax(cf['x2pix'])), int(np.nanmax(cf['y2pix']))),
                np.uint8)
            for i in cf.index:
                x1, x2, y1, y2 = cf.loc[i,
                                        ['x1pix', 'x2pix', 'y1pix', 'y2pix']]
                newimg[x1:x2, y1:y2] += cf.loc[i, 'Image']
                divisor[x1:x2, y1:y2] += 1
            im = np.nan_to_num(np.divide(newimg, divisor).T,
                               nan=0).astype(np.uint8)
            cur_size = im.shape[0] * im.shape[1]
            if constant_size < cur_size:
                scale_percent = np.sqrt(constant_size /
                                        cur_size)  # percent of original size
                width = int(im.shape[1] * scale_percent)
                height = int(im.shape[0] * scale_percent)
                dim = (width, height)
                # resize image
                im = cv2.resize(im, dim, interpolation=cv2.INTER_LINEAR)
            #from PIL import Image
            print('background subbing', flush=True)
            #import skimage
            #from skimage import morphology
            #im=im-skimage.morphology.rolling_ball(im,radius=100)
            #subtract_background(im,radius=100,light_bg=False)
            im = im.astype(np.uint16)
            tifffile.imsave(os.path.join(dirout, c + '_stitched.TIF'),
                            im,
                            compress=6)
            if roll_ball:
                RollingBallIJ(os.path.join(dirout, c + '_stitched.TIF'))
            print('background subbed', flush=True)
    '''
    if save_merged:
        imgs={}
        for c in sorted(chif['final_identifier'].unique()):
            cf=chif.loc[chif['final_identifier']==c,:]
            cf['Image']=None
            for i in tqdm.tqdm(cf.index):
                img=cv2.imread(cf.loc[i,'Path'])[:,:,0].T
                cf.loc[i,'Image']=[img]
            newimg=np.zeros((int(cf['x2pix'].max()),int(cf['y2pix'].max())), np.uint8)
            divisor=np.zeros((int(cf['x2pix'].max()),int(cf['y2pix'].max())), np.uint8)
            for i in cf.index:
                x1,x2,y1,y2=cf.loc[i,['x1pix','x2pix','y1pix','y2pix']]
                newimg[x1:x2,y1:y2]+=cf.loc[i,'Image']
                divisor[x1:x2,y1:y2]+=1
                imgs[c]=np.nan_to_num(np.divide(newimg,divisor).T,nan=0).astype(np.uint8)
        tifffile.imsave(os.path.join(dirout,'merged_stitched.TIF'),list(imgs.values()),metadata={'Test':'YES,No','Value':100},compress=6)
    '''

    if save_multipage:
        l = []
        for f in tqdm.tqdm(cf['"field" Index'].unique()):
            print(f, flush=True)
            cf = chif.loc[chif['"field" Index'] == f, :]
            cf = cf.sort_values(by='final_identifier', axis=0)
            cf['Image'] = None
            for i in cf.index:
                img = cv2.imread(cf.loc[i, 'Path'])[:, :, 0]
                cf.loc[i, 'Image'] = [img]
            #print(cf)
            imgs = {}
            for i in cf.index:
                imgs[cf.loc[i, 'final_identifier']] = cf.loc[i, 'Image']  #
            metadata = {'channel_names': ','.join(list(imgs.keys()))}
            metadata.update(cf.loc[i, [
                'DirName', 'SizeX', 'SizeY', 'ActualPositionX',
                'ActualPositionY', '"field" Index', 'ActualPositionZ', 'x1pix',
                'y1pix'
            ]].astype(str).to_dict())
            tifffile.imsave(os.path.join(dirout, f + '_merged.TIF'),
                            list(imgs.values()),
                            metadata=metadata,
                            compress=6)
            l.append(
                [f + '_merged.TIF', cf.loc[i, 'x1pix'], cf.loc[i, 'y1pix']])
        infile = os.path.join(dirout,
                              '_'.join(list(imgs.keys())) + '_merged.stitchy')
        write_stitchy(pd.DataFrame(l, columns=['FileName', 'x1pix', 'y1pix']),
                      infile,
                      keyname='FileName')
示例#10
0
def PatchMatch(Edges1F, gt1F, fx1F, fy1F, Edges0F, gt0F, fx0F, fy0F, MaskB0F,
               x_off, y_off, CV1):
    ps0F = 0.05
    w = int(25 / ps0F)
    buffer = 2 * w
    edges1Fa = np.zeros(
        (Edges1F.shape[0] + buffer * 2, Edges1F.shape[1] + 2 * buffer))
    edges1Fa[buffer:-buffer, buffer:-buffer] = Edges1F
    md = 12
    if CV1 > 4:
        md = md / 2
    elif CV1 > 1.5:
        md = md / 3
    else:
        md = md / 4
    max_dist = int((md) / (ps0F))
    contours, hierarchy = cv2.findContours(
        (1 - MaskB0F).astype(np.uint8), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    contour_sizes = [(cv2.contourArea(contour), contour)
                     for contour in contours]
    biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
    polygon = Polygon(np.array(biggest_contour[:, 0]))
    polygon = polygon.buffer(-w)
    v = w
    while polygon.is_empty or polygon.geom_type == 'MultiPolygon' or polygon.area / ps0F < 100:
        v -= int(2 / ps0F)
        polygon = Polygon(np.array(biggest_contour[:, 0]))
        polygon = polygon.buffer(-v)
    if v != w:
        print("WARNING   : Polygon-buffer: " + str(v * ps0F) + " < 25...")
    x, y = polygon.exterior.xy
    distance = np.cumsum(
        np.sqrt(np.ediff1d(x, to_begin=0)**2 + np.ediff1d(y, to_begin=0)**2))
    distance = distance / distance[-1]
    fx, fy = interp1d(distance, x), interp1d(distance, y)
    alpha = np.linspace(0, 1, 200)
    x_regular, y_regular = fx(alpha), fy(alpha)
    grid = []
    for i in range(len(x_regular)):
        grid.append((int(round(x_regular[i])), int(round(y_regular[i]))))
    CVa = np.zeros(len(grid))
    x0 = np.zeros(len(grid)).astype(int)
    y0 = np.zeros(len(grid)).astype(int)
    xog = np.zeros(len(grid)).astype(int)
    yog = np.zeros(len(grid)).astype(int)
    xof = np.zeros(len(grid)).astype(int)
    yof = np.zeros(len(grid)).astype(int)
    x1 = np.zeros(len(grid)).astype(int)
    y1 = np.zeros(len(grid)).astype(int)
    origin_x = np.zeros(len(grid))
    origin_y = np.zeros(len(grid))
    target_lon = np.zeros(len(grid))
    target_lat = np.zeros(len(grid))
    RECC_total = np.zeros(Edges1F.shape)
    circle1 = np.zeros((2 * w, 2 * w))
    for x in range(circle1.shape[0]):
        for y in range(circle1.shape[1]):
            if (x - w)**2 + (y - w)**2 < w**2:
                circle1[x, y] = 1
    circle2 = np.zeros((2 * max_dist, 2 * max_dist))
    for x in range(circle2.shape[0]):
        for y in range(circle2.shape[1]):
            if (x - max_dist)**2 + (y - max_dist)**2 < max_dist**2:
                circle2[x, y] = 1
    circle2[circle2 == 0] = np.NaN
    for i in tqdm(range(len(grid)),
                  position=0,
                  miniters=int(len(grid) / 10),
                  desc="RECC(f)   "):
        x0[i] = grid[i][1]
        y0[i] = grid[i][0]
        target_lon[i] = gt0F[0] + gt0F[1] * y0[i] * fy0F
        target_lat[i] = gt0F[3] + gt0F[5] * x0[i] * fx0F
        xog[i] = int(round((target_lat[i] - gt1F[3]) / (gt1F[5] * fx1F)))
        yog[i] = int(round((target_lon[i] - gt1F[0]) / (gt1F[1] * fy1F)))
        xof[i] = int(round(xog[i] + x_off / ps0F))
        yof[i] = int(round(yog[i] + y_off / ps0F))
        target = Edges0F[x0[i] - w:x0[i] + w, y0[i] - w:y0[i] + w]
        if target.shape != (2 * w, 2 * w):
            continue
        target = target * circle1
        sum_target = np.sum(target)
        search_wide = np.zeros((2 * (max_dist + w), 2 * (max_dist + w)))
        search_wide = edges1Fa[buffer + xof[i] - max_dist - w:buffer + xof[i] +
                               max_dist + w, buffer + yof[i] - max_dist -
                               w:buffer + yof[i] + max_dist + w]
        if search_wide.shape != (2 * (max_dist + w), 2 * (max_dist + w)):
            continue
        sum_patch = cv2.filter2D(search_wide, -1, circle1)
        numerator = cv2.filter2D(search_wide, -1, target)
        RECC_wide = numerator / (sum_patch + sum_target)
        RECC_area = RECC_wide[w:-w, w:-w] * circle2
        RECC_total.fill(np.NaN)
        RECC_total[xof[i] - max_dist:xof[i] + max_dist,
                   yof[i] - max_dist:yof[i] + max_dist] = RECC_area
        max_one = np.partition(RECC_total[~np.isnan(RECC_total)].flatten(),
                               -1)[-1]
        max_n = np.partition(RECC_total[~np.isnan(RECC_total)].flatten(),
                             -4 - 1)[-4 - 1]
        y1[i] = np.where(RECC_total >= max_one)[1][0]
        x1[i] = np.where(RECC_total >= max_one)[0][0]
        y_n = np.where(RECC_total >= max_n)[1][0:-1]
        x_n = np.where(RECC_total >= max_n)[0][0:-1]
        CVa[i] = sum(
            np.sqrt(np.square(x1[i] - x_n) + np.square(y1[i] - y_n))) / 4
        origin_x[i] = x1[i] * fx1F
        origin_y[i] = y1[i] * fy1F
        dx = (x1 - xof) * ps0F
        dy = (y1 - yof) * ps0F
    plt.figure()
    plt.subplot(1, 2, 1)
    plt.imshow(Edges0F, cmap='gray')
    plt.scatter(y0, x0, c='r', s=3)
    plt.subplot(1, 2, 2)
    plt.imshow(Edges1F, cmap='gray')
    plt.scatter(y0, x0, c='r', s=3)
    plt.scatter(yog, xog, c='g', s=3)
    plt.scatter(yof, xof, c='b', s=3)
    ind = np.where(x1 != 0)
    plt.scatter(y1[ind], x1[ind], c='y', s=3)
    for i in range(len(y1)):
        plt.plot([y0[i], yog[i]], [x0[i], xog[i]], c='g', lw=0.5)
        plt.plot([yog[i], yof[i]], [xog[i], xof[i]], c='b', lw=0.5)
        if x1[i] != 0 and y1[i] != 0:
            plt.plot([yof[i], y1[i]], [xof[i], x1[i]], c='y', lw=0.5)
    plt.figure(7)
    plt.subplot(1, 2, 1)
    plt.imshow(Edges0F, cmap='gray')
    plt.subplot(1, 2, 2)
    plt.imshow(Edges1F, cmap='gray')
    plt.figure(8)
    plt.subplot(1, 2, 1)
    plt.imshow(Edges0F, cmap='gray')
    plt.subplot(1, 2, 2)
    plt.imshow(Edges1F, cmap='gray')
    return origin_x, origin_y, target_lon, target_lat, x0, y0, xog, yog, xof, yof, x1, y1, CVa, dx, dy

# In[81]:


matplotlib.pyplot.scatter([x[0] for x in shapes['1']], [x[1] for x in shapes['1']])
outside=np.array(shapes['1'])[~np.array(contains)]
matplotlib.pyplot.scatter([x[0] for x in outside], [x[1] for x in outside])


# In[82]:


matplotlib.pyplot.scatter([x[0] for x in shapes['1']], [x[1] for x in shapes['1']])
matplotlib.pyplot.scatter(polygon.exterior.coords.xy[0],polygon.exterior.coords.xy[1])
buffgon = Polygon(polygon.buffer(4500.0).exterior)
matplotlib.pyplot.scatter(buffgon.exterior.coords.xy[0],buffgon.exterior.coords.xy[1])
outside=np.array(shapes['1'])[~np.array(contains)]
matplotlib.pyplot.scatter([x[0] for x in outside], [x[1] for x in outside])
matplotlib.pyplot.savefig('/wynton/scratch/mtschmitz/BufferPolygon.png')


# In[74]:


buffgon


# In[75]:

        
        

# test erosion of polygon
from shapely.geometry.polygon import Polygon


from shapely.geometry import Polygon

p = Polygon([(0, 0), (1, 1), (1, 0)])

x,y = p.boundary.xy
plt.plot(x, y, color='r', alpha=0.7, linewidth=3, solid_capstyle='round', zorder=2)


p2 = p.buffer(-0.2);
x,y = p2.boundary.xy
plt.plot(x, y, color='r', alpha=0.7, linewidth=3, solid_capstyle='round', zorder=2)

b = p2.boundary;

for o in b:
  x,y = o.xy
  plt.plot(x, y, color='b', alpha=0.7, linewidth=3, solid_capstyle='round', zorder=2)


import numpy as np
t = np.linspace(0,10,50);
aline = np.vstack([t, np.sin(t)+0.5]).T;
aline[0] = [0,0];
aline[-1] = [10,-0.2];
示例#13
0
shape = [shape_2J, shape_2H]
shape_2HJ = cascaded_union(shape)
shape = [shape_2G, shape_2H]
shape_2GH = cascaded_union(shape)
shape_4R = Polygon(zip(nafo_div['4R']['lon'], nafo_div['4R']['lat']))
shape_4S = Polygon(zip(nafo_div['4S']['lon'], nafo_div['4S']['lat']))
shape_4T = Polygon(zip(nafo_div['4T']['lon'], nafo_div['4T']['lat']))
shape = [shape_4R, shape_4S]
shape_4RS = cascaded_union(shape)
shape = [shape_4R, shape_4S, shape_4T]
shape_4RST = cascaded_union(shape)
polygon4Vs = Polygon(zip(nafo_div['4Vs']['lon'], nafo_div['4Vs']['lat']))
polygon4Vn = Polygon(zip(nafo_div['4Vn']['lon'], nafo_div['4Vn']['lat']))
polygon4W = Polygon(zip(nafo_div['4W']['lon'], nafo_div['4W']['lat']))
polygon4X = Polygon(zip(nafo_div['4X']['lon'], nafo_div['4X']['lat']))
shape = [polygon4Vs.buffer(0), polygon4Vn.buffer(0), polygon4W.buffer(0), polygon4X.buffer(0)]
shape_4VWX = cascaded_union(shape)
shape_5Y = Polygon(zip(nafo_div['5Y']['lon'], nafo_div['5Y']['lat']))


dict_stats_3LNO = {}
dict_stats_3M = {}
dict_stats_3Ps = {}
dict_stats_3K = {}
dict_stats_3L = {}
dict_stats_3O = {}
dict_stats_2J = {}
dict_stats_2HJ = {}
dict_stats_2GH = {}
dict_stats_4R = {}
dict_stats_4S = {}
def main():
    parser = _argparser()
    args = parser.parse_args()

    schema = {
        'properties': [('filename', 'str'), ('path', 'str')],
        'geometry': 'Polygon'
    }

    if args.out_srs is not None:
        out_crs = fiona.crs.from_epsg(args.out_srs)
    else:
        out_crs = fiona.crs.from_epsg(4326)

    outshape = fiona.open(args.outshape,
                          'w',
                          crs=out_crs,
                          driver='ESRI Shapefile',
                          schema=schema)

    if args.processed:
        flist = glob.glob('AST*/*.zip.met') + glob.glob('AST*/zips/*.zip.met')
    else:
        flist = glob.glob('*.zip.met')

    for mfile in flist:
        imgpath = os.path.abspath(mfile)
        dirpath = os.path.dirname(imgpath)

        clean = [line.strip() for line in open(mfile).read().split('\n')]

        if os.path.sep in mfile:
            mfile = mfile.split(os.path.sep)[-1]

        latinds = [
            i for i, line in enumerate(clean) if 'GRingPointLatitude' in line
        ]
        loninds = [
            i for i, line in enumerate(clean) if 'GRingPointLongitude' in line
        ]

        latlines = clean[latinds[0]:latinds[1] + 1]
        lonlines = clean[loninds[0]:loninds[1] + 1]

        lonvalstr = lonlines[2]
        latvalstr = latlines[2]

        lats = [float(val) for val in latvalstr.strip('VALUE =()').split(',')]
        lons = [float(val) for val in lonvalstr.strip('VALUE =()').split(',')]

        coords = zip(lons, lats)
        footprint = Polygon(coords)
        if args.out_srs is not None:
            footprint = reproject_geometry(footprint, 4326, args.out_srs)

        footprint = footprint.buffer(args.buffer)
        outshape.write({
            'properties': {
                'filename': mfile,
                'path': dirpath
            },
            'geometry': mapping(footprint)
        })

    outshape.close()
示例#15
0
def PatchMatch(ps2, w, md, edges1F, gt, fx_F, fy_F, edges0F, gt_0, fx_F0,
               fy_F0, contour_F0, x_offset, y_offset, CV1):
    w = int(w / ps2)
    buffer = 2 * w
    edges1Fa = np.zeros(
        (edges1F.shape[0] + buffer * 2, edges1F.shape[1] + 2 * buffer))
    edges1Fa[buffer:-buffer, buffer:-buffer] = edges1F
    if CV1 > 4:
        md = md / 2
    elif CV1 > 1.5:
        md = md / 3
    else:
        md = md / 4
    max_dist = int((md) / (ps2))
    contours, hierarchy = cv2.findContours((1 - contour_F0).astype(np.uint8),
                                           cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    contour_sizes = [(cv2.contourArea(contour), contour)
                     for contour in contours]
    biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
    polygon = Polygon(np.array(biggest_contour[:, 0]))
    polygon = polygon.buffer(-w)
    v = w
    while polygon.is_empty or polygon.geom_type == 'MultiPolygon' or polygon.area / ps2 < 100:
        v -= int(2 / ps2)
        polygon = Polygon(np.array(biggest_contour[:, 0]))
        polygon = polygon.buffer(-v)
    if v != w:
        print("WARNING   : Polygon-buffer: " + str(v) + " < w...")
    x, y = polygon.exterior.xy
    distance = np.cumsum(
        np.sqrt(np.ediff1d(x, to_begin=0)**2 + np.ediff1d(y, to_begin=0)**2))
    distance = distance / distance[-1]
    fx, fy = interp1d(distance, x), interp1d(distance, y)
    alpha = np.linspace(0, 1, 200)
    x_regular, y_regular = fx(alpha), fy(alpha)
    grid = []
    for i in range(len(x_regular)):
        grid.append((int(round(x_regular[i])), int(round(y_regular[i]))))
    cv = np.zeros(len(grid))
    dist_lon = np.zeros(len(grid))
    dist_lat = np.zeros(len(grid))
    origin_x = np.zeros(len(grid))
    origin_y = np.zeros(len(grid))
    target_lon = np.zeros(len(grid))
    target_lat = np.zeros(len(grid))
    o_x = np.zeros(len(grid))
    o_y = np.zeros(len(grid))
    t_x = np.zeros(len(grid))
    t_y = np.zeros(len(grid))
    dx = np.zeros(len(grid))
    dy = np.zeros(len(grid))
    RECC_total = np.zeros(edges1Fa.shape)
    RECC_over = np.zeros(edges1Fa.shape)
    RECC_over.fill(np.NaN)
    circle1 = np.zeros((2 * w, 2 * w))
    for x in range(circle1.shape[0]):
        for y in range(circle1.shape[1]):
            if (x - w)**2 + (y - w)**2 < w**2:
                circle1[x, y] = 1
    circle2 = np.zeros((2 * max_dist, 2 * max_dist))
    for x in range(circle2.shape[0]):
        for y in range(circle2.shape[1]):
            if (x - max_dist)**2 + (y - max_dist)**2 < max_dist**2:
                circle2[x, y] = 1
    circle2[circle2 == 0] = np.NaN
    for i in tqdm(range(len(grid)),
                  position=0,
                  miniters=int(len(grid) / 10),
                  desc="RECC      "):
        x_i_0 = grid[i][1]
        y_i_0 = grid[i][0]
        target = edges0F[x_i_0 - w:x_i_0 + w, y_i_0 - w:y_i_0 + w]
        if target.shape != (2 * w, 2 * w):
            continue
        target = target * circle1
        sum_target = np.sum(target)
        lat_0 = gt_0[3] + gt_0[5] * x_i_0 * fx_F0
        lon_0 = gt_0[0] + gt_0[1] * y_i_0 * fy_F0
        x_i_0_og = int(
            round((lat_0 - gt[3]) / (gt[5] * fx_F) + (x_offset / ps2)))
        y_i_0_og = int(
            round((lon_0 - gt[0]) / (gt[1] * fy_F) + (y_offset / ps2)))
        search_wide = np.zeros((2 * (max_dist + w), 2 * (max_dist + w)))
        search_wide = edges1Fa[buffer + x_i_0_og - max_dist - w:buffer +
                               x_i_0_og + max_dist + w, buffer + y_i_0_og -
                               max_dist - w:buffer + y_i_0_og + max_dist + w]
        if search_wide.shape != (2 * (max_dist + w), 2 * (max_dist + w)):
            continue
        sum_patch = cv2.filter2D(search_wide, -1, circle1)
        numerator = cv2.filter2D(search_wide, -1, target)
        RECC_wide = numerator / (sum_patch + sum_target)
        RECC_area = RECC_wide[w:-w, w:-w] * circle2
        RECC_total.fill(np.NaN)
        RECC_total[x_i_0_og - max_dist:x_i_0_og + max_dist,
                   y_i_0_og - max_dist:y_i_0_og + max_dist] = RECC_area
        if np.nansum(RECC_over[x_i_0_og - max_dist:x_i_0_og + max_dist,
                               y_i_0_og - max_dist:y_i_0_og + max_dist]) == 0:
            RECC_over[x_i_0_og - max_dist:x_i_0_og + max_dist,
                      y_i_0_og - max_dist:y_i_0_og + max_dist] = RECC_area
        max_one = np.partition(RECC_total[~np.isnan(RECC_total)].flatten(),
                               -1)[-1]
        max_n = np.partition(RECC_total[~np.isnan(RECC_total)].flatten(),
                             -4 - 1)[-4 - 1]
        y_i = np.where(RECC_total >= max_one)[1][0]
        x_i = np.where(RECC_total >= max_one)[0][0]
        y_n = np.where(RECC_total >= max_n)[1][0:-1]
        x_n = np.where(RECC_total >= max_n)[0][0:-1]
        cv[i] = sum(np.sqrt(np.square(x_i - x_n) + np.square(y_i - y_n))) / 4
        lon = gt[0] + gt[1] * y_i * fy_F + gt[2] * x_i * fx_F
        lat = gt[3] + gt[4] * y_i * fy_F + gt[5] * x_i * fx_F
        lon_0 = gt_0[0] + gt_0[1] * y_i_0 * fy_F0 + gt_0[2] * x_i_0 * fx_F0
        lat_0 = gt_0[3] + gt_0[4] * y_i_0 * fy_F0 + gt_0[5] * x_i_0 * fx_F0
        dist_lon[i] = lon_0 - lon
        dist_lat[i] = lat_0 - lat
        o_x[i] = x_i
        o_y[i] = y_i
        t_x[i] = x_i_0
        t_y[i] = y_i_0
        dx[i] = (x_i - x_i_0_og) * ps2
        dy[i] = (y_i - y_i_0_og) * ps2
        # For referencing:
        origin_x[i] = x_i * fx_F
        origin_y[i] = y_i * fy_F
        target_lon[i] = lon_0
        target_lat[i] = lat_0
    return origin_x, origin_y, target_lon, target_lat, o_x, o_y, t_x, t_y, cv, dx, dy
示例#16
0
from shapely.geometry.polygon import Polygon

from shapely.geometry import Polygon

p = Polygon([(0, 0), (1, 1), (1, 0)])

x, y = p.boundary.xy
plt.plot(x,
         y,
         color='r',
         alpha=0.7,
         linewidth=3,
         solid_capstyle='round',
         zorder=2)

p2 = p.buffer(-0.2)
x, y = p2.boundary.xy
plt.plot(x,
         y,
         color='r',
         alpha=0.7,
         linewidth=3,
         solid_capstyle='round',
         zorder=2)

b = p2.boundary

for o in b:
    x, y = o.xy
    plt.plot(x,
             y,
def extendAllMergedLines(dirPathLines, vectorMask, epsgValue):
    """
    extendAllMergedLines.
       
    :param dirPathLines: (text) path
	:param vectorMask: (text) path
	:param epsgValue: (text) epsg value
    :returns: OpenCV version.
    """

    crsEpsgId = {'init': 'epsg:' + str(epsgValue)}

    crutils.printLogMsg(crglobals.OK_MSG + 'Path Lines: %s' % (dirPathLines))
    crutils.printLogMsg(crglobals.OK_MSG + 'Mask: %s' % (vectorMask))
    crutils.printLogMsg(crglobals.OK_MSG + 'EPSG: %s' % (epsgValue))

    #input merged line file
    fileNameMergedLines = 'merged_lines.shp'
    mergedLinesGeoDataFrame = gpd.GeoDataFrame.from_file(
        os.path.join(
            dirPathLines,
            fileNameMergedLines))  #dirPathLines+'/'+fileNameMergedLines)
    #input mask polygon file
    boundsMaskGeoDataFrame = gpd.GeoDataFrame.from_file(vectorMask)

    longLinesArray = []
    idLongLinesArray = []
    for x in range(0, len(mergedLinesGeoDataFrame.geometry)):
        linea_bx = (list(mergedLinesGeoDataFrame.geometry[x].coords))
        extrapoledLine = getExtrapoledLine(*linea_bx[-2:])
        idLongLinesArray.append(x)
        longLinesArray.append(extrapoledLine)

    dataFrameLongLines = pd.DataFrame({'id': idLongLinesArray})
    longLinesGeoDataFrame = gpd.GeoDataFrame(dataFrameLongLines,
                                             crs=crsEpsgId,
                                             geometry=longLinesArray)
    longLinesFileName = os.path.join(
        dirPathLines,
        'merged_lines_long.shp')  #dirPathLines+'/'+'merged_lines_long.shp'
    longLinesGeoDataFrame.to_file(driver='ESRI Shapefile',
                                  filename=longLinesFileName)
    crutils.printLogMsg(crglobals.DONE_MSG + 'Generated long lines !')

    #######################################################################################
    #Get the convex hull lines
    convexHullFromBoundsMask = boundsMaskGeoDataFrame.convex_hull.iloc[0]
    x, y = convexHullFromBoundsMask.exterior.xy
    pointsConvexHullFromBoundsMaskArray = np.array(list(zip(x, y)))
    minBBoxRect = imboundrect.minimum_bounding_rectangle(
        pointsConvexHullFromBoundsMaskArray)
    polygonOMBB = Polygon(
        [minBBoxRect[0], minBBoxRect[1], minBBoxRect[2], minBBoxRect[3]])
    #######################################################################################
    #cut lines by ombb
    #update applying buffer. it fix some strange bug at some corner lines
    geoDataFrameLineCuttedByBoxBuffer = (longLinesGeoDataFrame.intersection(
        polygonOMBB.buffer(20)))
    dataFrameLineCuttedByBoxDf = pd.DataFrame({
        'id':
        idLongLinesArray,
        'len':
        geoDataFrameLineCuttedByBoxBuffer.length
    })
    geoDataFrameLinesCuttedByBox = gpd.GeoDataFrame(
        dataFrameLineCuttedByBoxDf,
        crs=crsEpsgId,
        geometry=geoDataFrameLineCuttedByBoxBuffer)
    mergedLinesCuttedByOMBBPolygonFile = os.path.join(
        dirPathLines, 'merged_lines_long_cut_ombb.shp'
    )  #dirPathLines+'/'+'merged_lines_long_cut_ombb.shp'
    geoDataFrameLinesCuttedByBox.to_file(
        driver='ESRI Shapefile', filename=mergedLinesCuttedByOMBBPolygonFile)
    crutils.printLogMsg(crglobals.DONE_MSG + 'Cut long lines by OMBB bounds !')

    #######################################################################################
    projectDistance = 1
    #enumerate lines in spatial order
    angle = crutils.getAzimuth(
        (geoDataFrameLinesCuttedByBox.geometry[0].coords[0][0]),
        (geoDataFrameLinesCuttedByBox.geometry[0].coords[0][1]),
        (geoDataFrameLinesCuttedByBox.geometry[0].coords[1][0]),
        (geoDataFrameLinesCuttedByBox.geometry[0].coords[1][1]))
    anglep = (angle + 270)
    #search for the closest geometry line to temporal point
    temporalXpoint = (geoDataFrameLinesCuttedByBox.geometry[0].centroid.x
                      ) + np.sin(np.deg2rad(anglep)) * 5000
    temporalYpoint = (geoDataFrameLinesCuttedByBox.geometry[0].centroid.y
                      ) + np.cos(np.deg2rad(anglep)) * 5000
    temporalExternalPoint = Point((temporalXpoint, temporalYpoint))
    crutils.printLogMsg(crglobals.DONE_MSG + 'Generate a Temporal Point')
    #print(temporalExternalPoint)
    tmpLineDistance = []
    for i in range(len(geoDataFrameLinesCuttedByBox)):
        distanceCalculated = (temporalExternalPoint.distance(
            geoDataFrameLinesCuttedByBox.geometry[i].centroid))
        tmpLineDistance.append(distanceCalculated)
        #print("i: %s -> distanceCalculated: %s -> %s" % (str(i), str(distanceCalculated) , str(geoDataFrameLinesCuttedByBox.geometry[i])   ))
    minelem = np.argmin(tmpLineDistance)
    crutils.printLogMsg(crglobals.DONE_MSG + "Found a closest line id: %s" %
                        (str(minelem)))
    #######################################################################################
    #Calc Distances using the closest line found
    xp = (geoDataFrameLinesCuttedByBox.geometry[minelem].centroid.x) + np.sin(
        np.deg2rad(anglep)) * projectDistance
    yp = (geoDataFrameLinesCuttedByBox.geometry[minelem].centroid.y) + np.cos(
        np.deg2rad(anglep)) * projectDistance
    externalPoint = Point((xp, yp))
    #print(externalPoint)

    geoDistance = []
    index = []

    for i in range(len(geoDataFrameLinesCuttedByBox)):
        #print('-> %s' % ( str( i)))
        distanceCalculated = (externalPoint.distance(
            geoDataFrameLinesCuttedByBox.geometry[i].centroid))
        geoDistance.append(distanceCalculated)
        #print(distanceCalculated)
        index.append(i)

    dataFrameLineCuttedByBoxBuffer = pd.DataFrame({
        'len':
        geoDataFrameLineCuttedByBoxBuffer.length,
        'geo_dist':
        geoDistance,
        'idx':
        index
    })
    geoDataFrameLinesCuttedByBox = gpd.GeoDataFrame(
        dataFrameLineCuttedByBoxBuffer,
        crs=crsEpsgId,
        geometry=geoDataFrameLineCuttedByBoxBuffer)

    mergedLongLinesCuttedByOMBwDistFileName = os.path.join(
        dirPathLines, 'merged_lines_long_cut_ombb_wdist.shp'
    )  #dirPathLines+'/'+'merged_lines_long_cut_ombb_wdist.shp'
    geoDataFrameLinesCuttedByBox.to_file(
        driver='ESRI Shapefile',
        filename=mergedLongLinesCuttedByOMBwDistFileName)

    #######################################################################################
    #######################################################################################
    ############## FILTERING LINES LOOKING FOR CANDIDATES #################################
    #######################################################################################
    #######################################################################################

    sortedDistance = np.argsort(geoDistance).astype('int')
    idByGeo = [x for _, x in sorted(zip(sortedDistance, index))]

    newObjDistancesSorted = np.sort(geoDistance)

    #Removing Adjacents and lines duplicates
    newObjDistancesSorted = crutils.removeAdjacentsInArray(
        newObjDistancesSorted)

    #print('====== new distances sorted =====')
    #print(newObjDistancesSorted)
    crutils.printLogMsg(crglobals.DONE_MSG + 'Candidate lines: %s ' %
                        str(len(newObjDistancesSorted)))

    ##Removing Closing Lines
    #pairsdistances = zip([0]+newObjDistancesSorted, newObjDistancesSorted)

    #TODO: distancesFiltered
    #distancesFiltered = [pair[1] for pair in pairsdistances if abs(pair[0]-pair[1]) >=0.5 ]
    ###########################################
    ## OTRO APPROACH TO FIND DISTANCES

    groups, current_group, first = [], [], newObjDistancesSorted[0]
    for item in newObjDistancesSorted:
        # Check if this element falls under the current group
        if item - first <= 1.3:
            current_group.append(item)
        else:
            # If it doesn't, create a new group and add old to the result
            groups.append(current_group[:])
            current_group, first = [item], item
        # Add the last group which was being gathered to the result
    groups.append(current_group[:])
    distancesFiltered = [np.max(item) for item in groups]

    #iter 1 removing proximal lines
    pairsdistances2 = zip([0] + distancesFiltered, distancesFiltered)
    distancesFiltered = [
        pair[1] for pair in pairsdistances2 if abs(pair[0] - pair[1]) >= 0.4
    ]

    #iter 2 removing proximal lines
    pairsdistances3 = zip([0] + distancesFiltered, distancesFiltered)
    distancesFiltered = [
        pair[1] for pair in pairsdistances3 if abs(pair[0] - pair[1]) >= 0.9
    ]  #>=0.8  -preff: 0.9

    ######################################3
    #print('====== distances filtered =====')
    #print(distancesFiltered)

    crutils.printLogMsg(crglobals.DONE_MSG +
                        'Resulting lines: %s ' % str(len(distancesFiltered)))

    #TODO: final

    #cut final lines by mask
    dataFrameCandidateLines = (geoDataFrameLinesCuttedByBox.intersection(
        boundsMaskGeoDataFrame.geometry.iloc[0]))

    candidateLinesFileName = os.path.join(
        dirPathLines,
        'candidate_lines.shp')  #dirPathLines+'/'+'candidate_lines.shp'

    dataFrameLineCuttedByMask = pd.DataFrame({
        'distance':
        dataFrameCandidateLines.length,
        'geo_dist':
        geoDistance,
        'idx':
        index
    })

    geoDataFrameLineCuttedByMask = gpd.GeoDataFrame(
        dataFrameLineCuttedByMask,
        crs=crsEpsgId,
        geometry=dataFrameCandidateLines)
    geoDataFrameLineCuttedByMask.to_file(driver='ESRI Shapefile',
                                         filename=candidateLinesFileName)

    #####################################
    ## NEW CROPROWS - GEOMETRY SEARCH
    #####################################

    #save candidateLinesbuffer
    candidateLinesBufferFileName = os.path.join(dirPathLines,
                                                'candidate_lines_buffer.shp')
    candidateLinesBuffer = geoDataFrameLineCuttedByMask.buffer(0.3)
    s = candidateLinesBuffer

    #ADDING FEATURE 3-9-2018
    #DISOLVE OVERLAPPING BUFFER POLYGONS
    #https://gis.stackexchange.com/questions/271733/geopandas-dissolve-overlapping-polygons/271735
    overlap_matrix = s.apply(lambda x: s.overlaps(x)).values.astype(int)
    n, ids = connected_components(overlap_matrix)
    df = gpd.GeoDataFrame({'geometry': s, 'group': ids}, crs=crsEpsgId)
    res = df.dissolve(by='group')
    res.to_file(driver='ESRI Shapefile', filename=candidateLinesBufferFileName)

    candidateLinesBufferCentroidFileName = os.path.join(
        dirPathLines, 'candidate_lines_buffer_centroid.shp')
    points = res.copy()
    points.geometry = res['geometry'].centroid
    points.crs = res.crs
    points.head()
    points.to_file(driver='ESRI Shapefile',
                   filename=candidateLinesBufferCentroidFileName)

    df_lines = dataFrameCandidateLines.geometry
    df_points = points.geometry
    #print(len(df_points))
    #print(len(df_lines))

    idClosestLineArr = []
    #find the closest candidate line to point
    for x in range(0, len(df_points)):
        minDistancePointLine = df_lines.distance(df_points[x]).min()
        allDistanceToLines = df_lines.distance(df_points[x])
        idClosestLine = np.where(allDistanceToLines == minDistancePointLine)[0]
        idClosestLineArr.append(idClosestLine[0])
        #print('centroid point: %s - id closest line: ' % (str(x)) , (str(idClosestLine))   )

    #print(idClosestLineArr)
    selcr = []
    for x in range(0, len(df_lines)):
        selcr = df_lines[idClosestLineArr]

    crf = 0
    geoidcr = []
    croprowLength = []

    for y in range(0, len(selcr)):
        #print(selcr.geometry.iloc[y])
        #print(selcr.geometry.iloc[y].length)
        croprowLength.append(selcr.geometry.iloc[y].length)
        geoidcr.append(crf)
        crf = crf + 1

    dataFrameCr = pd.DataFrame({
        'geometry': selcr,
        'crlen': croprowLength,
        'idg': geoidcr,
        'crg': 'Generated by Crop Rows Generator v1'
    })
    geoDataFrameCropRows = gpd.GeoDataFrame(dataFrameCr, crs=crsEpsgId)
    cropRowsFileNameByGeom = os.path.join(dirPathLines, 'croprows_lines.shp')
    geoDataFrameCropRows.to_file(driver='ESRI Shapefile',
                                 filename=str(cropRowsFileNameByGeom))

    ##EXPORT CROP ROWS RESULTS TO WGS84 SHP AND KML FORMATS
    crsExportID = {'init': 'epsg:' + str(crglobals.EXPORT_EPSG)}
    exportCropRowsShapeFile = os.path.join(
        os.path.dirname(os.path.dirname(dirPathLines)), crglobals.EXPORTDIR,
        'croprows_wgs84.shp')
    geoDataFrameCropRowsWGS84 = gpd.GeoDataFrame(dataFrameCr, crs=crsEpsgId)
    geoDataFrameCropRowsWGS84 = geoDataFrameCropRowsWGS84.to_crs(crsExportID)
    geoDataFrameCropRowsWGS84.to_file(driver='ESRI Shapefile',
                                      filename=str(exportCropRowsShapeFile))
    exportCropRowsShapeFileKML = os.path.join(
        os.path.dirname(os.path.dirname(dirPathLines)), crglobals.EXPORTDIR,
        'croprows_wgs84.kml')
    geoDataFrameCropRowsWGS84.to_file(driver='kml',
                                      filename=str(exportCropRowsShapeFileKML))
    crutils.printLogMsg(
        crglobals.DONE_MSG +
        'Exported Resulting Crop Rows to KML and SHP format in WGS84 CRS')

    cropRowsBufferFileName = os.path.join(dirPathLines,
                                          'croprows_lines_buffer.shp')
    cropRowsLinesBuffer = geoDataFrameCropRows.buffer(0.3)
    cropRowsLinesBufferGeoData = gpd.GeoDataFrame(crs=crsEpsgId,
                                                  geometry=cropRowsLinesBuffer)
    cropRowsLinesBufferGeoData.to_file(driver='ESRI Shapefile',
                                       filename=str(cropRowsBufferFileName))

    #####################################
    ## OLD CROPROWS - STAT SEARCH
    #####################################
    getIndexes = lambda x, xs: [
        i for (y, i) in zip(xs, range(len(xs))) if x == y
    ]
    cuttedLineArray = []
    #look for
    k = []
    flagCounter3 = 0
    for x in distancesFiltered:
        #print(distancesFiltered[i])
        #print(getIndexes(distancesFiltered[i],newobjdistances))
        k.append(getIndexes(distancesFiltered[flagCounter3], geoDistance)[0])
        flagCounter3 = flagCounter3 + 1

    #Reindex lines filtered
    index2 = []
    flagCounter2 = 0
    m = []
    j = 0
    croprowLength = []
    for x in k:
        m.append(dataFrameCandidateLines[k[j]])
        index2.append(flagCounter2)
        #line len for each geometry
        croprowLength.append(m[j].length)
        flagCounter2 += 1
        j = j + 1

    #print('index2:')
    #print(index2)
    #print('k')
    #print(k)
    #print('m')
    #print(m)

    sortdistance2 = np.argsort(distancesFiltered).astype('int')
    idByGeo2 = [x for _, x in sorted(zip(sortdistance2, index2))]

    #print('idByGeo2')
    #print(idByGeo2)

    crutils.printLogMsg(crglobals.DONE_MSG + 'Re-indexing candidate lines !')

    #Fix distances substracting projectDistance
    arrayDistances = np.array(distancesFiltered)
    #fixdist = arrayDistances - projectDistance
    crutils.printLogMsg(crglobals.DONE_MSG + 'Distances fixed !')

    #print(croprowLength)

    #fixdist
    dataFrameFixedLines = pd.DataFrame({
        'id': k,
        'geo_dist': arrayDistances,
        'idgeo': idByGeo2,
        'crlen': croprowLength
    })
    #dataFrameFixedLines = pd.DataFrame({  })
    geoDataFrameFixedLines = gpd.GeoDataFrame(dataFrameFixedLines,
                                              crs=crsEpsgId,
                                              geometry=m)
    geoDataFrameFixedLines.dropna()

    crutils.printLogMsg(crglobals.DONE_MSG + 'Result lines generated !')

    cropRowsLinesFileName = os.path.join(dirPathLines,
                                         'croprows_lines_stat.shp')
    geoDataFrameFixedLines.to_file(driver='ESRI Shapefile',
                                   filename=str(cropRowsLinesFileName))

    crutils.printLogMsg(crglobals.DONE_MSG +
                        'Writing file with resulting lines : %s ' %
                        (cropRowsLinesFileName))

    #saveResultXMLFile(cropRowsLinesFileName)
    resultingFiles = [
        cropRowsFileNameByGeom, cropRowsBufferFileName,
        exportCropRowsShapeFile, exportCropRowsShapeFileKML,
        str(epsgValue),
        str(len(newObjDistancesSorted)),
        str(len(distancesFiltered)), vectorMask
    ]
    saveResultXMLFile(resultingFiles)
    #saveResultXMLFile(cropRowsFileNameByGeom,cropRowsBufferFileName,exportCropRowsShapeFile,exportCropRowsShapeFileKML)

    #####################################

    return 1
示例#18
0
def init_match(ps1, w, md, edges1C, gt, fx_C, fy_C, xb_C, yb_C, edges0C, gt_0,
               fx_C0, fy_C0, xb_C0, yb_C0, mask_b_C0):
    w = int(w / ps1)
    buffer = 2 * w
    edges1Ca = np.zeros(
        (edges1C.shape[0] + buffer * 2, edges1C.shape[1] + 2 * buffer))
    edges1Ca[buffer:-buffer, buffer:-buffer] = edges1C
    max_dist = int((md) / ps1)
    contours, hierarchy = cv2.findContours((1 - mask_b_C0).astype(np.uint8),
                                           cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    contour_sizes = [(cv2.contourArea(contour), contour)
                     for contour in contours]
    biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
    polygon = Polygon(np.array(biggest_contour[:, 0]))
    polygon = polygon.buffer(-w)
    v = w
    while polygon.is_empty or polygon.geom_type == 'MultiPolygon' or polygon.area / ps1 < 100:
        v -= int(2 / ps1)
        polygon = Polygon(np.array(biggest_contour[:, 0]))
        polygon = polygon.buffer(-v)
    if v != w:
        print("WARNING   : Polygon-buffer: " + str(v * ps1) + " < w...")
    x, y = polygon.exterior.xy
    distance = np.cumsum(
        np.sqrt(np.ediff1d(x, to_begin=0)**2 + np.ediff1d(y, to_begin=0)**2))
    distance = distance / distance[-1]
    fx, fy = interp1d(distance, x), interp1d(distance, y)
    alpha = np.linspace(0, 1, 200)
    x_regular, y_regular = fx(alpha), fy(alpha)
    grid = []
    for i in range(len(x_regular)):
        grid.append((int(round(x_regular[i])), int(round(y_regular[i]))))
    x_offset = []
    y_offset = []
    o_x = np.zeros(len(grid))
    o_y = np.zeros(len(grid))
    t_x = np.zeros(len(grid))
    t_y = np.zeros(len(grid))
    cv = np.zeros(len(grid))
    RECC_total = np.zeros(edges1Ca.shape)
    RECC_over = np.zeros(edges1Ca.shape)
    RECC_over.fill(np.NaN)
    circle1 = np.zeros((2 * w, 2 * w))
    for x in range(circle1.shape[0]):
        for y in range(circle1.shape[1]):
            if (x - w)**2 + (y - w)**2 < w**2:
                circle1[x, y] = 1
    circle2 = np.zeros((2 * max_dist, 2 * max_dist))
    for x in range(circle2.shape[0]):
        for y in range(circle2.shape[1]):
            if (x - max_dist)**2 + (y - max_dist)**2 < max_dist**2:
                circle2[x, y] = 1
    circle2[circle2 == 0] = np.NaN
    for i in tqdm(range(len(grid)),
                  position=0,
                  miniters=int(len(grid) / 10),
                  desc="RECC      "):
        x_i_0 = grid[i][1]
        y_i_0 = grid[i][0]
        target = edges0C[x_i_0 - w:x_i_0 + w, y_i_0 - w:y_i_0 + w] * circle1
        if target.shape != (2 * w, 2 * w):
            continue
        sum_target = np.sum(target)
        lat_0 = gt_0[3] + gt_0[5] * x_i_0 * fx_C0
        lon_0 = gt_0[0] + gt_0[1] * y_i_0 * fy_C0
        x_i_0_og = int(round((lat_0 - gt[3]) / (gt[5] * fx_C)))
        y_i_0_og = int(round((lon_0 - gt[0]) / (gt[1] * fy_C)))
        search_wide = np.zeros((2 * (max_dist + w), 2 * (max_dist + w)))
        search_wide = edges1Ca[buffer + x_i_0_og - max_dist - w:buffer +
                               x_i_0_og + max_dist + w, buffer + y_i_0_og -
                               max_dist - w:buffer + y_i_0_og + max_dist + w]
        if search_wide.shape != (2 * (max_dist + w), 2 * (max_dist + w)):
            continue
        sum_patch = cv2.filter2D(search_wide, -1, circle1)
        numerator = cv2.filter2D(search_wide, -1, target)
        RECC_wide = numerator / (sum_patch + sum_target)
        RECC_area = RECC_wide[w:-w, w:-w] * circle2
        RECC_total.fill(np.NaN)
        RECC_total[x_i_0_og - max_dist:x_i_0_og + max_dist,
                   y_i_0_og - max_dist:y_i_0_og + max_dist] = RECC_area
        if np.nansum(RECC_over[x_i_0_og - max_dist:x_i_0_og + max_dist,
                               y_i_0_og - max_dist:y_i_0_og + max_dist]) == 0:
            RECC_over[x_i_0_og - max_dist:x_i_0_og + max_dist,
                      y_i_0_og - max_dist:y_i_0_og + max_dist] = RECC_area
        max_one = np.partition(RECC_total[~np.isnan(RECC_total)].flatten(),
                               -1)[-1]
        max_n = np.partition(RECC_total[~np.isnan(RECC_total)].flatten(),
                             -4 - 1)[-4 - 1]
        y_i = np.where(RECC_total >= max_one)[1][0]
        x_i = np.where(RECC_total >= max_one)[0][0]
        y_n = np.where(RECC_total >= max_n)[1][0:-1]
        x_n = np.where(RECC_total >= max_n)[0][0:-1]
        cv[i] = sum(np.sqrt(np.square(x_i - x_n) + np.square(y_i - y_n))) / 4
        x_offset.append(x_i - x_i_0_og)
        y_offset.append(y_i - y_i_0_og)
        o_x[i] = x_i
        o_y[i] = y_i
        t_x[i] = x_i_0
        t_y[i] = y_i_0
    x_offset = np.array(x_offset)
    y_offset = np.array(y_offset)
    a, b, c = np.histogram2d(x_offset[cv < 4],
                             y_offset[cv < 4],
                             bins=len(x_offset))
    d, e = np.where(a == np.max(a))
    if len(d) > 1:
        i = [0, 0]
        binnnn = len(x_offset) / 10
        while len(i) > 1:
            binnnn -= 1
            f, g, h = np.histogram2d(x_offset[cv < 4],
                                     y_offset[cv < 4],
                                     bins=binnnn)
            i, j = np.where(f == np.max(f))
        diff = (b[d] - g[i])**2 + (c[e] - h[j])**2
        ind = np.where(diff == np.min(diff))[0]
        d = d[ind]
        e = e[ind]
    x_offset = (b[d] + b[d + 1]) / 2
    y_offset = (c[e] + c[e + 1]) / 2
    x_offset = x_offset[0] * ps1
    y_offset = y_offset[0] * ps1
    o_x = o_x[cv < 4]
    o_y = o_y[cv < 4]
    t_x = t_x[cv < 4]
    t_y = t_y[cv < 4]
    return x_offset, y_offset, o_x, o_y, t_x, t_y
def ImageJStitchImages(dirname, dirout, stitchchannel, chosenstitchgroup,
                       x1lim, x2lim, y1lim, y2lim, minmax_displace,
                       abs_displace):
    ray.shutdown()
    num_cpus = 1  #psutil.cpu_count(logical=False)
    #set number of cores to use
    print('cpus:', num_cpus)
    ray.init(num_cpus=num_cpus)

    x1lim = float(x1lim)
    x2lim = float(x2lim)
    y1lim = float(y1lim)
    y2lim = float(y2lim)
    chosenstitchgroup = re.sub('TR_', "1", chosenstitchgroup)
    chosenstitchgroup = re.sub('TR', "", chosenstitchgroup)

    protocol = [x for x in os.listdir(dirname) if '.scanprotocol' in x][0]
    minoverlap = 0
    with open(os.path.join(dirname, protocol), 'r') as f:
        for line in f:
            try:
                #print(line)
                if 'MinOverlapPixel' in line:
                    minoverlap = float(line.split('>')[1].split('<')[0]) * 1.1
            except:
                pass

    n_locations = 0
    counting = False
    with open(os.path.join(dirname, protocol), 'r') as f:
        for line in f:
            try:
                if 'LocationIds' in line:
                    counting = ~counting
                elif counting:
                    n_locations += 1
            except:
                pass

    n_location = 1
    counting = False
    reference = False
    shapes = defaultdict(list)
    with open(os.path.join(dirname, protocol), 'r') as f:
        for line in f:
            try:
                if '<d2p1:ScanLocation>' in line:
                    counting = ~counting
                if counting and '<d10p1:_x>' in line:
                    x = float(line.split('>')[1].split('<')[0])
                if counting and '<d10p1:_y>' in line:
                    y = float(line.split('>')[1].split('<')[0])
                    shapes[str(n_location)].append((x, y))
                if '<d2p1:ReferencePoint ' in line:
                    counting = False
                    reference = True
                if reference and '<d10p1:_x>' in line:
                    xref = float(line.split('>')[1].split('<')[0])
                if reference and '<d10p1:_y>' in line:
                    yref = float(line.split('>')[1].split('<')[0])
                    reference = False
                    shapes[str(n_location)] = [
                        (x + xref, y + yref)
                        for x, y in shapes[str(n_location)]
                    ]
                    n_location += 1
                    xref = 0
                    yref = 0
            except:
                pass
    print(shapes)
    outline = mpltPath.Path(shapes[chosenstitchgroup])
    print(outline)
    outline = outline.transformed(matplotlib.transforms.Affine2D().scale(1.2))
    print(outline)
    tags_to_get = [
        'SizeX', 'SizeY', 'ActualPositionX', 'ActualPositionY', 'Run Index',
        'Index', '"field" Index', 'AreaGrid AreaGridIndex', 'Name',
        '<Image ID="Image:" Name', 'ActualPositionZ'
    ]

    def get_tag(x, tp):
        return (re.search(x + '=' + '"([A-Za-z0-9_\./\\-]*)"', tp).group(1))

    @ray.remote
    def getTiffMetadata(f):
        f = open(f, 'rb')
        # Return Exif tags
        tags = exifread.process_file(f)
        tp = tags['Image ImageDescription'].values
        d = {}
        for tag in tags_to_get:
            d[tag] = get_tag(tag, tp)
        return (d)

    data = []
    for fname in sorted(os.listdir(dirname)):
        if fname.endswith(".TIF"):
            fpath = os.path.join(dirname, fname)
            path = os.path.normpath(dirname)
            d = path.split(os.sep)[-2]
            data.append((fname, d, fpath))
    imageFiles = pd.DataFrame(data, columns=['FileName', 'DirName', 'Path'])

    #normalize positions so starts at 0,0
    #imageFiles['ActualPositionX']=imageFiles['ActualPositionX']-imageFiles['ActualPositionX'].min()
    #imageFiles['ActualPositionY']=imageFiles['ActualPositionY']-imageFiles['ActualPositionY'].min()
    imageFiles = imageFiles.loc[['_R_' in x
                                 for x in imageFiles['FileName']], :]

    l = []
    for i in imageFiles.index:
        f = imageFiles.loc[i, 'Path']
        #d=getTiffMetadata(f)
        l.append(getTiffMetadata.remote(f))
        #print(d)
        #imageFiles.loc[i,d.keys()]=list(d.values())

    metadf = pd.DataFrame(ray.get(l))
    metadf.index = imageFiles.index
    imageFiles = imageFiles.join(metadf)
    ray.shutdown()

    imageFiles.rename(columns={'<Image ID="Image:" Name': 'Channel Name'},
                      inplace=True)

    imageFiles['ActualPositionX'] = imageFiles['ActualPositionX'].astype(float)
    imageFiles['ActualPositionY'] = imageFiles['ActualPositionY'].astype(float)
    print(imageFiles['ActualPositionX'])
    print(imageFiles['ActualPositionY'])
    imageFiles['SizeX'] = imageFiles['SizeX'].astype(float)
    imageFiles['SizeY'] = imageFiles['SizeY'].astype(float)
    imageFiles.sort_values(by=['"field" Index', 'Channel Name'], inplace=True)

    #Max size
    chif = imageFiles.loc[imageFiles['Channel Name'] == stitchchannel, :]
    chif['x1pix'] = 0
    chif['x2pix'] = 0
    chif['y1pix'] = 0
    chif['y2pix'] = 0
    xsize = imageFiles['SizeX'].value_counts().idxmax()
    ysize = imageFiles['SizeY'].value_counts().idxmax()
    xend = len(chif.ActualPositionX.unique()) * xsize
    yend = len(chif.ActualPositionY.unique()) * ysize

    #assume adjacent images are taken sequentially
    xd = []
    yd = []
    for i in range(len(chif['"field" Index'].unique()) - 1):
        indi = chif['"field" Index'] == list(chif['"field" Index'])[i]
        indip1 = chif['"field" Index'] == list(chif['"field" Index'])[i + 1]
        xdiff = np.abs(
            list(chif.loc[indi, 'ActualPositionX'])[0] -
            list(chif.loc[indip1, 'ActualPositionX'])[0])
        ydiff = np.abs(
            list(chif.loc[indi, 'ActualPositionY'])[0] -
            list(chif.loc[indip1, 'ActualPositionY'])[0])
        xd.append(xdiff)
        yd.append(ydiff)
    xd = np.array(xd)
    yd = np.array(yd)
    #nonzero median is the distance between images
    xmedian = np.median(xd[xd > 5])
    ymedian = np.median(yd[yd > 5])
    #for reference xsize-minoverlap=xmedian
    print('MEDIANS')
    print(xmedian, ymedian)

    import shapely
    from shapely.geometry import Point
    from shapely.geometry.polygon import Polygon
    polygon = Polygon(shapes[chosenstitchgroup])
    #Buffer expands, scale doesn't work for expanding linear regions with no points
    buffgon = Polygon(polygon.buffer(min(xmedian, ymedian)).exterior)
    #polygon=shapely.affinity.scale(polygon,xfact=1.2,yfact=1.2)
    inside = [
        buffgon.contains(Point(x, y))
        for x, y in list(zip(chif['ActualPositionX'], chif['ActualPositionY']))
    ]

    matplotlib.pyplot.scatter(list(chif['ActualPositionX']),
                              list(chif['ActualPositionY']))
    matplotlib.pyplot.scatter([x[0] for x in shapes[chosenstitchgroup]],
                              [x[1] for x in shapes[chosenstitchgroup]])
    matplotlib.pyplot.scatter(buffgon.exterior.coords.xy[0],
                              buffgon.exterior.coords.xy[1])
    matplotlib.pyplot.savefig(os.path.join(dirout, 'BufferPolygon.png'))
    #inside = outline.contains_points(list(zip(chif['ActualPositionX'],chif['ActualPositionY'])))
    print(inside)
    print(list(zip(chif['ActualPositionX'], chif['ActualPositionY'])))
    chif = chif.loc[inside, :]

    #normalize positions so starts at 0,0
    chif['ActualPositionX'] = chif['ActualPositionX'] - chif[
        'ActualPositionX'].min()
    chif['ActualPositionY'] = chif['ActualPositionY'] - chif[
        'ActualPositionY'].min()

    xorder = dict(
        zip(np.sort(chif['ActualPositionX'].unique()),
            np.sort(chif['ActualPositionX'].unique().argsort())))
    yorder = dict(
        zip(np.sort(chif['ActualPositionY'].unique()),
            np.sort(chif['ActualPositionY'].unique().argsort())))

    for i in chif.index:
        x = chif.loc[
            i,
            'ActualPositionX'] / xmedian  #xorder[chif.loc[i,'ActualPositionX']]
        y = chif.loc[
            i,
            'ActualPositionY'] / ymedian  #yorder[chif.loc[i,'ActualPositionY']]
        print(x, y)
        x1 = int((xsize * x) - (x * minoverlap))
        x2 = x1 + int(xsize)
        y1 = int((ysize * y) - (y * minoverlap))
        y2 = y1 + int(ysize)
        chif.loc[i, 'x1pix'] = x1
        chif.loc[i, 'x2pix'] = x2
        chif.loc[i, 'y1pix'] = y1
        chif.loc[i, 'y2pix'] = y2

    #Incase specific stitchgroups are denoted in my normal way
    '''l=[]
    for x in chif['FileName']:
        if x.startswith('L_'):
            l.append('1')
            continue
        if x.startswith('R_'):
            l.append('2')
            continue
        if '_TR_' in x:
            l.append('1')
            continue
        if '_TD_' in x:
            l.append('1')
            continue
        if 'TR' in x or 'TD' in x:
            groupnum=re.sub('TR|TD','',re.search('TD[0-9]|TR[0-9]',x).group(0))
            l.append(groupnum)  
            continue  

    ###Getting stitch group
    if len(l)!=imageFiles.shape[0]:
        #add estimate pixel vals to df
        for i in chif.index:
            x=xorder[chif.loc[i,'ActualPositionX']]
            y=yorder[chif.loc[i,'ActualPositionY']]
            print(x,y)
            x1=int((xsize*x)-(x*minoverlap))
            x2=x1+int(xsize)
            y1=int((ysize*y)-(y*minoverlap))
            y2=y1+int(ysize)
            chif.loc[i,'x1pix']=x1
            chif.loc[i,'x2pix']=x2
            chif.loc[i,'y1pix']=y1
            chif.loc[i,'y2pix']=y2

  
        mat=sklearn.metrics.pairwise.euclidean_distances(chif.loc[:,['ActualPositionX','ActualPositionY']])
        np.fill_diagonal(mat,9999999999)
        sortmat=mat.copy()
        sortmat.sort(1)    
        chif['stitchgroup']='nan'
        #1.1 is larger than longest acceptable hypotenuse given reasonable aspect ratios
        G=nx.from_numpy_matrix((mat<=sortmat[:,1].max()).astype(int))
        co=nx.algorithms.components.connected_components(G)
        for i,sg in enumerate(co):
            chif.loc[chif.index[list(sg)],'stitchgroup']=str(i+1)
        
        
        
        
    else:
        chif['stitchgroup']=l

    
    imageFiles['stitchgroup']='nan'
    for i in chif['"field" Index']:
        imageFiles.loc[imageFiles['"field" Index']==i,'stitchgroup']=list(chif.loc[chif['"field" Index']==i,'stitchgroup'])[0]

    chif=chif.loc[chif['stitchgroup']==chosenstitchgroup,:]   
    imageFiles=imageFiles.loc[imageFiles['stitchgroup']==chosenstitchgroup,:]

    tmppath=os.path.expanduser('~/imagingmetadata.csv')
    if os.path.exists(tmppath):
        refdf=pd.read_csv(tmppath,sep='\t')
    else:
        refdf=pd.read_csv('https://docs.google.com/spreadsheets/d/e/2PACX-1vSYbvCJpS-GfRKuGgs2IBH7MD1KtDPDqs7ePqQJ1PyrMKp7f7z7ZpY4WtMFGPxU4mWbnRHgBl4PtaeH/pub?output=tsv&gid=1520792104',sep='\t')
        refdf.to_csv(tmppath,sep='\t')

    refdf.rename(columns={'Channel0':'GFP','Channel1':'DAPI','Channel2':'CY5','Channel3':'RFP'},inplace=True)
    imageFiles=pd.merge(imageFiles, refdf,  how='left', left_on=['DirName','stitchgroup'], right_on = ['DirName','SlidePosition.1isL'])
    imageFiles['gene']=list([imageFiles.loc[i,x] for i,x in enumerate(imageFiles['Channel Name'])])
    imageFiles['Channel Name']=imageFiles['gene']

    xpixdict=dict(zip(chif['"field" Index'],chif['x1pix']))
    ypixdict=dict(zip(chif['"field" Index'],chif['y1pix']))

    imageFiles=imageFiles.loc[imageFiles['"field" Index'].isin(chif['"field" Index']),:]
    imageFiles['x1pix']='nan'
    imageFiles['y1pix']='nan'
    imageFiles['x1pix']=[xpixdict[x] for x in imageFiles['"field" Index']]
    imageFiles['y1pix']=[ypixdict[x] for x in imageFiles['"field" Index']]

    
    if imageFiles.shape[0]<2:
        print('No Images!')
        return(None)

    imageFiles['xind']=[xorder[x] for x in imageFiles['ActualPositionX']]
    imageFiles['yind']=[yorder[x] for x in imageFiles['ActualPositionY']]


    # In[135]:


    channeldfs={}
    for c in imageFiles['Channel Name'].unique():
        channeldfs[c]=imageFiles.loc[imageFiles['Channel Name']==c,:]
        channeldfs[c].index=channeldfs[c]['"field" Index']
    '''

    #Take ordered list of items and break into blocks of size blocksize overlapping by 1
    #Used to break image into subblocks for faster stitching
    def array_to_overlapping_blocks(A, blocksize):
        import numpy as np
        size = blocksize
        step = blocksize - 1
        return (np.array([A[i:i + size] for i in range(0, len(A), step)]))

        # In[14]:

    print('PIXEL POSITIONS')
    print('minoverlap', minoverlap)
    print(chif.loc[:, ['x1pix', 'x2pix', 'y1pix', 'y2pix']], flush=True)

    xmax = chif['x2pix'].max()
    ymax = chif['y2pix'].max()

    inrange = (chif['x2pix'] / xmax > x1lim) & (
        chif['x1pix'] / xmax < x2lim) & (chif['y2pix'] / ymax > y1lim) & (
            chif['y1pix'] / ymax < y2lim)

    chif = chif.loc[inrange, :]

    xmin = chif['x1pix'].min()
    ymin = chif['y1pix'].min()

    chif['x1pix'] = chif['x1pix'] - xmin
    chif['x2pix'] = chif['x2pix'] - xmin
    chif['y1pix'] = chif['y1pix'] - ymin
    chif['y2pix'] = chif['y2pix'] - ymin
    xorder = dict(
        zip(np.sort(chif['ActualPositionX'].unique()),
            np.sort(chif['ActualPositionX'].unique().argsort())))
    yorder = dict(
        zip(np.sort(chif['ActualPositionY'].unique()),
            np.sort(chif['ActualPositionY'].unique().argsort())))
    chif['xind'] = [xorder[x] for x in chif['ActualPositionX']]
    chif['yind'] = [yorder[x] for x in chif['ActualPositionY']]

    #xblocks=array_to_overlapping_blocks(chif['xind'].unique(),blocksize)
    #yblocks=array_to_overlapping_blocks(chif['yind'].unique(),blocksize)

    infile = os.path.join(
        dirout,
        str(chosenstitchgroup) + '_' + stitchchannel + '.stitchy')

    def ijstitch(chdf, infile):
        #conda create -n imagej -c conda-forge openjdk=8 pyimagej
        #conda install -c conda-forge maven
        #conda install -c conda-forge pyjnius
        #conda install -c conda-forge imglyb
        import imagej
        ij = imagej.init(os.path.expanduser('~/utils/Fiji.app/'),
                         new_instance=True)
        #ij = imagej.init('sc.fiji:fiji',new_instance=True)
        plugin = 'Grid/Collection stitching'
        args = {
            'type': '[Positions from file]',
            'order': '[Defined by TileConfiguration]',
            'directory': '[]',
            'layout_file': infile,
            'regression_threshold': '0.0001',
            'fusion_method': '[Linear Blending]',
            'max/avg_displacement_threshold': '0.20',
            'absolute_displacement_threshold': '0.30',
            'subpixel_accuracy': True,
            #'downsample_tiles':True,'x':'.25', 'y':'.25','interpolation':'Bicubic average',"width":'512','height':'384','outputFile':infile+'.registered.txt',
            'compute_overlap': True,
            'use_virtual_input_images': True,
            'computation_parameters': '[Save memory (but be slower)]',
            'image_output': '[Fuse and display]'
        }
        #ij.py.run_plugin(plugin, args,ij1_style=False)
        #ij.py.run_macro('run("Grid/Collection stitching", "type=[Positions from file] order=[Defined by TileConfiguration] directory=[] layout_file=/home/mt/tmp/HOECHST.stitchy fusion_method=Average regression_threshold=0 max/avg_displacement_threshold=2.50 absolute_displacement_threshold=3.50 compute_overlap subpixel_accuracy downsample_tiles use_virtual_input_images computation_parameters=[Save memory (but be slower)] image_output=[Fuse and display] x=.25 y=.25 width=512 height=384 interpolation=Bicubic average");\n')
        #ij.py.run_script(language='js',script='importClass(Packages.ij.IJ);IJ.run("Grid/Collection stitching", "type=[Positions from file] order=[Defined by TileConfiguration] directory=[] layout_file=/home/mt/tmp/HOECHST.stitchy fusion_method=[Linear Blending] regression_threshold=.01 max/avg_displacement_threshold=.250 absolute_displacement_threshold=.35 compute_overlap subpixel_accuracy downsample_tiles use_virtual_input_images computation_parameters=[Save memory (but be slower)] image_output=[Fuse and display] x=.2 y=.2 width=410 height=307 interpolation=Bicubic average");')
        ij.getContext().dispose()

    def callstitching(
            infile,
            imagejpath='~/utils/Fiji.app/ImageJ-linux64',
            scriptpath='~/code/macaque-dev-brain/imaging/Stitching.js'):
        import sys
        import subprocess
        from subprocess import PIPE, STDOUT
        cmd = [
            os.path.expanduser(imagejpath),
            os.path.expanduser(scriptpath),
            os.path.expanduser(infile),
            str(minmax_displace),
            str(abs_displace)
        ]
        cmd = ' '.join(cmd)
        print(cmd, flush=True)
        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stdin=subprocess.PIPE,
                                   stderr=subprocess.STDOUT)
        (stdoutdata, stderrdata) = process.communicate()
        print(stdoutdata)

    def write_stitchy(chdf, infile):
        with open(infile, 'w') as the_file:
            the_file.write('dim = 2\n')
            for i in chdf.index:
                cur = chdf.loc[i, :]
                the_file.write(cur['Path'] + '; ; (' + str(cur['x1pix']) +
                               ',' + str(cur['y1pix']) + ') \n')

    def read_stitchy(chdf, infile):
        print('read_stitchy:')
        print(infile)
        df = pd.read_csv(infile, skiprows=4, header=None, sep=';')
        df.loc[:, ['ActualPositionX', 'ActualPositionY']] = [
            re.sub('\(|\)', '', x).split(',') for x in df[2]
        ]
        df.index = df[0]
        print(df)
        df.loc[:, ['xind', 'yind']] = 0
        for i in df.index:
            df.loc[i, ['xind', 'yind']] = chdf.loc[chdf['FileName'] == i,
                                                   ['xind', 'yind']].values[0]
        return (df)

    def do_ij_stitching(chdf, infile):
        print('do_ij_stitching')
        write_stitchy(chdf, infile)
        #ijstitch(chdf,infile)
        callstitching(infile)

        #This would have to be changed for non-evos microscopes
        with open(infile + '.registered.txt', "r") as sources:
            lines = sources.readlines()
        for d in ['d0', 'd1', 'd2', 'd3']:
            with open(
                    re.sub('DAPI', d, infile) + str(minmax_displace) + '_' +
                    str(abs_displace) + '.registered.txt', "w") as sources:
                for line in lines:
                    sources.write(re.sub('d1.TIF', d + '.TIF', line))
        return (read_stitchy(chdf, infile + '.registered.txt'))

    df = do_ij_stitching(chif, infile)
    with open(os.path.join(dirout, 'dummyfile.dummy'), 'w') as fp:
        pass
    ray.shutdown()
    return (df, imageFiles)
示例#20
0
def IniMatch(plist, Edges0F, Edges1F, MaskB0F, MaskB1F, x_off, y_off, CV1,
             gt0F, gt1F):
    # Nullify impact of OpenOrth + CannyLin + OneMatch:
    x_off = 0
    y_off = 0
    CV1 = 1.5

    ps0F = 0.05
    w = int(25 / ps0F)
    buff = w
    Edges1Fa = np.zeros(
        (Edges1F.shape[0] + buff * 2, Edges1F.shape[1] + 2 * buff))
    Edges1Fa[buff:-buff, buff:-buff] = Edges1F
    Edges1Fa = (Edges1Fa).astype(np.uint8)
    if CV1 >= 4:
        md = 5
        x_off = 0
        y_off = 0
    elif CV1 <= 1.5:
        md = 2
    else:
        md = 2 + 3 * ((CV1 - 1.5) / 2.5)
    md = 6
    md = int(6 / ps0F)

    contours, hierarchy = cv2.findContours(
        (1 - MaskB0F).astype(np.uint8), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    contour_sizes = [(cv2.contourArea(contour), contour)
                     for contour in contours]
    biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
    poly_base = Polygon(np.array(biggest_contour[:, 0]))
    contours, hierarchy = cv2.findContours(
        (1 - MaskB1F).astype(np.uint8), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    contour_sizes = [(cv2.contourArea(contour), contour)
                     for contour in contours]
    biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
    poly_file = Polygon(np.array(biggest_contour[:, 0]))
    if poly_file.area < 0.7 * poly_base.area:
        sf = 1
        print(
            "Georegistration of small orthomosaic on larger, very cool, preventive move to nrtu folder afterwards..."
        )
        inward = 0
        polygon = poly_file.buffer(-w)
        while polygon.area < 0.6 * poly_file.area:
            inward += 20
            polygon = poly_file.buffer(-w + inward)
        while polygon.type == 'MultiPolygon':
            polygon = sorted(list(polygon), key=lambda p: p.area,
                             reverse=True)[0]
        x, y = polygon.exterior.xy
        distance = np.cumsum(
            np.sqrt(
                np.ediff1d(x, to_begin=0)**2 + np.ediff1d(y, to_begin=0)**2))
        distance = distance / distance[-1]
        fx, fy = interp1d(distance, x), interp1d(distance, y)
        alpha = np.linspace(0, 1, 200)
        x_regular, y_regular = fx(alpha), fy(alpha)
        grid = []
        for i in range(len(x_regular)):
            lat = gt1F[3] + gt1F[5] * y_regular[i]
            lon = gt1F[0] + gt1F[1] * x_regular[i]
            y_regular[i] = (lat - gt0F[3]) / gt0F[5]
            x_regular[i] = (lon - gt0F[0]) / gt0F[1]
            grid.append((int(round(x_regular[i])), int(round(y_regular[i]))))
    elif poly_base.area < 0.4 * poly_file.area:
        sf = 1
        print(
            "Georegistration of large orthomosaic on smaller, moving to nrtu folder afterwards..."
        )
        polygon = poly_base.buffer(-w)
        while polygon.type == 'MultiPolygon':
            polygon = sorted(list(polygon), key=lambda p: p.area,
                             reverse=True)[0]
        x, y = polygon.exterior.xy
        distance = np.cumsum(
            np.sqrt(
                np.ediff1d(x, to_begin=0)**2 + np.ediff1d(y, to_begin=0)**2))
        distance = distance / distance[-1]
        fx, fy = interp1d(distance, x), interp1d(distance, y)
        alpha = np.linspace(0, 1, 200)
        x_regular, y_regular = fx(alpha), fy(alpha)
        grid = []
        for i in range(len(x_regular)):
            grid.append((int(round(x_regular[i])), int(round(y_regular[i]))))
        if polygon.buffer(-3 * w).is_empty == False:
            polygon = polygon.buffer(-2 * w)
            while polygon.type == 'MultiPolygon':
                polygon = sorted(list(polygon),
                                 key=lambda p: p.area,
                                 reverse=True)[0]
            x, y = polygon.exterior.xy
            distance = np.cumsum(
                np.sqrt(
                    np.ediff1d(x, to_begin=0)**2 +
                    np.ediff1d(y, to_begin=0)**2))
            distance = distance / distance[-1]
            fx, fy = interp1d(distance, x), interp1d(distance, y)
            alpha = np.linspace(0, 1, 100)
            x_regular, y_regular = fx(alpha), fy(alpha)
            for i in range(len(x_regular)):
                grid.append(
                    (int(round(x_regular[i])), int(round(y_regular[i]))))
    else:
        sf = 0
        polygon = poly_base.buffer(-w)
        while polygon.type == 'MultiPolygon':
            polygon = sorted(list(polygon), key=lambda p: p.area,
                             reverse=True)[0]
        x, y = polygon.exterior.xy
        distance = np.cumsum(
            np.sqrt(
                np.ediff1d(x, to_begin=0)**2 + np.ediff1d(y, to_begin=0)**2))
        distance = distance / distance[-1]
        fx, fy = interp1d(distance, x), interp1d(distance, y)
        alpha = np.linspace(0, 1, 200)
        x_regular, y_regular = fx(alpha), fy(alpha)
        grid = []
        for i in range(len(x_regular)):
            grid.append((int(round(x_regular[i])), int(round(y_regular[i]))))
        if polygon.buffer(-3 * w).is_empty == False:
            polygon = polygon.buffer(-2 * w)
            while polygon.type == 'MultiPolygon':
                polygon = sorted(list(polygon),
                                 key=lambda p: p.area,
                                 reverse=True)[0]
            x, y = polygon.exterior.xy
            distance = np.cumsum(
                np.sqrt(
                    np.ediff1d(x, to_begin=0)**2 +
                    np.ediff1d(y, to_begin=0)**2))
            distance = distance / distance[-1]
            fx, fy = interp1d(distance, x), interp1d(distance, y)
            alpha = np.linspace(0, 1, 100)
            x_regular, y_regular = fx(alpha), fy(alpha)
            for i in range(len(x_regular)):
                grid.append(
                    (int(round(x_regular[i])), int(round(y_regular[i]))))
    c1 = np.zeros((2 * w, 2 * w))
    for x in range(c1.shape[0]):
        for y in range(c1.shape[1]):
            if (x - w)**2 + (y - w)**2 < w**2:
                c1[x, y] = 1
    c1 = (c1).astype(np.uint8)
    c2 = np.zeros((2 * md, 2 * md))
    for x in range(c2.shape[0]):
        for y in range(c2.shape[1]):
            if (x - md)**2 + (y - md)**2 < md**2:
                c2[x, y] = 1
    c2 = (c2).astype(np.uint8)
    return plist, Edges1Fa, x_off, y_off, grid, md, c1, c2, sf