示例#1
0
def get_coor(img):
    (x,y),img=roi(img)
    median = cv2.GaussianBlur(image,(5,5),0)
    median = cv2.medianBlur(median,15)
    hsv = cv2.cvtColor(median, cv2.COLOR_BGR2HSV)
    lower_blue=np.array([91,111,68])
    upper_blue=np.array([115,255,255])
    mask=cv2.inRange(hsv,lower_blue,upper_blue)
    edges = cv2.Canny(mask,100,200)
    (contours,_) = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    #hull = cv2.convexHull(contours,returnPoints = False)
    #print(hull)
    arr=[]
    for contour in contours:
        (x,y,w,h) = cv2.boundingRect(contour)
        arr.append([x,y])
        arr.append([x+w,y])
        arr.append([x,y+h])
        arr.append([x+w,y+h])
    alpha = 0.4 * alphashape.optimizealpha(arr)
    hull = alphashape.alphashape(arr, alpha)
    hull_pts = hull.exterior.coords.xy
    arr=[]
    for i in range(len(hull_pts[0])):
        arr.append([int(hull_pts[0][i]),int(hull_pts[1][i])])
    results=[(np.array(z)+np.array([x,y])).tolist() for z in arr]
    return results
示例#2
0
def get_coor(image):
    X, Y, Z = de_hole1(image)
    Xk = roi(image)[0]
    arr_X = []
    arr_Y = []
    for z in Z:
        for x in X:
            if z[0] == x[0] or z[1] == z[1]:
                if check(z, x):
                    arr_X.append(z)
    for z in Z:
        for x in Y:
            if z[0] == x[0] or z[1] == z[1]:
                if check(z, x):
                    arr_Y.append(z)
    output = []
    arr = arr_X + arr_Y
    for x in arr:
        if x not in output:
            output.append(x)
    alpha = 0.3 * alphashape.optimizealpha(output)
    hull = alphashape.alphashape(output, alpha)
    hull_pts = hull.exterior.coords.xy
    arr = []
    for i in range(len(hull_pts[0])):
        arr.append([int(hull_pts[0][i]), int(hull_pts[1][i])])
    #r1=[[img[0]+Xk[0],img[1]+Xk[1]] for img in arr]
    return arr
 def test_given_a_point_return_a_point(self):
     """
     Given a point, the alphashape function should return the same point
     """
     alpha = optimizealpha(
         [(0., 0.), (0., 1.), (1., 1.), (1., 0.),
          (0.5, 0.25), (0.5, 0.75), (0.25, 0.5), (0.75, 0.5)])
     assert alpha > 3. and alpha < 3.5
示例#4
0
def get_coor12(image):
    X, Y, Z = de_hole12(image)
    if de_hole1(image) is not None:
        Xk = roi(image)[0]
        arr_X = []
        arr_Y = []
        for z in Z:
            for x in X:
                if z[0] == x[0] or z[1] == z[1]:
                    if check(z, x):
                        arr_X.append(z)
        for z in Z:
            for x in Y:
                if z[0] == x[0] or z[1] == z[1]:
                    if check(z, x):
                        arr_Y.append(z)
        output = []
        arr = arr_X + arr_Y
        for x in arr:
            if x not in output:
                output.append(x)
        alpha = 0.3 * alphashape.optimizealpha(output)
        hull = alphashape.alphashape(output, alpha)
        hull_pts = hull.exterior.coords.xy
        arr = []
        for i in range(len(hull_pts[0])):
            arr.append([int(hull_pts[0][i]), int(hull_pts[1][i])])

        def check(coor1, coor2):
            a = abs(coor1[0] - coor2[0]) + abs(coor2[1] - coor1[1])
            if a > 10:
                return False
            return True

        hull_pts = hull.exterior.coords.xy
        arr1 = []
        for i in range(len(hull_pts[0])):
            arr1.append([int(hull_pts[0][i]), int(hull_pts[1][i])])
        print(arr1)
        t = {}
        for i in range(len(arr1) - 1):
            t[i] = [arr1[i + 1][0], arr1[i][1]]
        print(t)
        count = 1
        for i in range(len(t)):
            if t[i] is not arr1:
                for v in arr:
                    if check(t[i], v):
                        arr1.insert(count, t[i])
                        count = count + 1
                        print(t[i])
                        break
            count = count + 1
    return arr1
示例#5
0
def add_alphashap(points, ax, alpha_value=None, alpha=0.3, fc=None, ec=None):
    """
    Add a alpha shape which corresponds to the ternary scatter plot
    :param points: A list of 3-tuples that (i, j, k) requires i + j + k = scale
    :param ax: the ax to plot the alpha shape, supposed to be same as the scatter plot
    :param alpha_value: float. default None which will calculate the optimize. If zero a Convex hill will be added
    :param alpha: float 0 to 1
    :param fc: fill color
    :param ec: edge color
    :return: None
    """
    t_points = to_t_points(points)
    if alpha_value is None:
        alpha_value = alphashape.optimizealpha(t_points)
    alpha_shape = alphashape.alphashape(t_points, alpha_value)
    ax.add_patch(PolygonPatch(alpha_shape, alpha=alpha, fc=fc, ec=ec))
示例#6
0
    if counter % 100 == 0:
        nivo += 1

for i in range(0, len(zdata)):
    by_nivo[zdata[i]].append((xdata[i], ydata[i]))

min_z = min(zdata)
max_z = max(zdata)


polni_nivo = {}
outer_nivo =  {}

for _nivo in by_nivo:
    points = by_nivo[_nivo]
    alpha = 0.25 * alphashape.optimizealpha(points)
    hull = alphashape.alphashape(points, alpha)
    hull_pts = hull.exterior.coords.xy

    hull_points = []
    for i in range(0, len(hull_pts[0])):
        hull_points.append((hull_pts[0][i], hull_pts[1][i]))

    polyg = Polygon(hull_points)
    line_polygon = LineString(polyg.exterior.coords)
    # (minx, miny, maxx, maxy)
    bounds = list(map(int, list(polyg.bounds)))
    polni_nivo[_nivo] = []
    outer_nivo[_nivo] = []

    for i in range(bounds[0], bounds[2]+1):
示例#7
0
    def cluster_hull(self, alpha0=2.25, minimum_lattice_distance=0.33):

        timeout_error = False
        concave_error = False

        y_fun = np.linspace(0.0, self.Ly, N_SAMPLES_Y)
        np.savetxt(self.save_fld + '/' + self.fr + 'y.txt', y_fun)

        mpl.use("Agg")
        print("[ -- Producing movie of the contact line in (x,y) -- ]")
        output_file_name = self.movie_name
        FFMpegWriter = manimation.writers['ffmpeg']
        metadata = dict(title='Contact Line',
                        artist='Michele Pellegrino',
                        comment='Contact line x(y) over time')
        writer = FFMpegWriter(fps=12, metadata=metadata)
        fig = plt.figure()

        with writer.saving(fig, output_file_name, N_WRITER):

            for frame in range(self.frm_ini, self.frm_fin + 1):

                print("[ ClusterHull: reading frame " + str(frame).zfill(4) +
                      " ]")

                # Read from .gro and add periodic images
                file_name = self.read_fld + '/' + self.fr + str(frame).zfill(
                    4) + '.gro'
                x = []
                y = []
                n_lines = count_line(file_name)
                n = 0
                in_file = open(file_name, 'r')
                for line in in_file:
                    n += 1
                    if n > 2 and n < n_lines:
                        line_data = read_gro_line(line)
                        if line_data[2] == "OW":
                            x.append(line_data[4])
                            y.append(line_data[5])
                in_file.close()
                for k in range(len(y)):
                    if y[k] > 0.75 * self.Ly:
                        y.append(y[k] - self.Ly)
                        x.append(x[k])
                    elif y[k] < 0.25 * self.Ly:
                        y.append(y[k] + self.Ly)
                        x.append(x[k])

                # Perform 2D clustering and find the label with the most points
                x = np.array(x)
                y = np.array(y)
                xcom = np.mean(x)
                points = np.column_stack((x, y))
                clustering = DBSCAN(eps=minimum_lattice_distance,
                                    min_samples=1).fit(points)
                cl_label = most_frequent(clustering.labels_)

                # Obtain a concave hull
                x_cl = np.take(x, np.where((clustering.labels_==cl_label) * \
                     ((x<xcom)*self.left_int+(x>xcom)*(1-self.left_int)) )[0])
                y_cl = np.take(y, np.where((clustering.labels_==cl_label) * \
                     ((x<xcom)*self.left_int+(x>xcom)*(1-self.left_int)) )[0])
                points_cl = np.column_stack((np.array(x_cl), np.array(y_cl)))
                if frame == self.frm_ini and alpha0 == 0:
                    print("[ Optimizing alpha, please wait... ]")
                    alpha = alphashape.optimizealpha(points_cl)
                    print("[ alpha = " + '{:05.3f}'.format(alpha) + " ]")
                else:
                    alpha = alpha0
                hull = alphashape.alphashape(points_cl, alpha)

                # Checking hull object instance
                if isinstance(hull,
                              shapely.geometry.multipolygon.MultiPolygon):
                    print(
                        "[ Warning: alphashape is returning more than one polygon as concave hull ]"
                    )
                    print(
                        "[    -> re-optimizing alpha...                                           ]"
                    )
                    alpha = alphashape.optimizealpha(points_cl)
                    hull = alphashape.alphashape(points_cl, alpha)
                    print("[ alpha = " + '{:05.3f}'.format(alpha) + " ]")
                    if isinstance(hull,
                                  shapely.geometry.multipolygon.MultiPolygon):
                        print(
                            "[ Error: cannot obtain an optimal value of alpha for a single polygon ]"
                        )
                        print(
                            "[    -> try changing clustering epsilon instead                       ]"
                        )
                        concave_error = True
                        break
                    print("[ Re-setting alpha to its original value... ]")
                    alpha = alpha0
                    print("[ alpha = " + '{:05.3f}'.format(alpha) + " ]")
                hull_pts = hull.exterior.coords.xy

                # Obtain the cl function x(y) at this frame
                hull_cl_x = []
                hull_cl_y = []
                s1 = False
                s2 = True
                l = len(hull_pts[0])
                hull_pts_x = hull_pts[0][0:l - 1]
                hull_pts_y = hull_pts[1][0:l - 1]
                if not (self.left_int):
                    hull_pts_x = np.flip(hull_pts_x)
                    hull_pts_y = np.flip(hull_pts_y)
                l = len(hull_pts_x)
                n = 0
                # Checking timeout
                timeout = cpu_time.time() + 5.0  # Five seconds from now
                while (s2):
                    n_new = n
                    n_old = (n - 1) % l
                    y_old = hull_pts_y[n_old]
                    y_new = hull_pts_y[n_new]
                    if y_old <= self.Ly and y_new >= self.Ly and s1:
                        s2 = False
                    if y_old <= 0 and y_new >= 0:
                        s1 = True
                        hull_cl_x.append(hull_pts_x[n_old])
                        hull_cl_y.append(hull_pts_y[n_old])
                    if s1:
                        hull_cl_x.append(hull_pts_x[n_new])
                        hull_cl_y.append(hull_pts_y[n_new])
                    n = (n + 1) % l
                    if cpu_time.time() > timeout:
                        print(
                            "[ Error: selection of contact line countour points is taking too long ]"
                        )
                        print(
                            "[    -> plotting concave hull, you may want to change alpha or eps    ]"
                        )
                        s2 = False
                        timeout_error = True
                if timeout_error:
                    break
                x_fun = np.interp(y_fun, hull_cl_y, hull_cl_x)

                # Saving cl x(y) on a .txt file
                np.savetxt(
                    self.save_fld + '/' + self.fr + str(frame).zfill(4) +
                    '.txt', x_fun)

                if self.make_movie:
                    plt.axis('scaled')
                    plt.ylim([self.xmin, self.xmax])
                    plt.xlim([0.0, self.Ly])
                    plt.title('CL @t=' + str(frame).zfill(4) + 'ps',
                              fontsize=17.5)
                    plt.fill_between(y_fun, x_fun, y2=self.xmax*self.left_int+self.xmin*(1-self.left_int), \
                        color='tab:cyan')
                    plt.plot(y, x, 'k.')
                    plt.xlabel("y [nm]", fontsize=15.0)
                    plt.ylabel("x [nm]", fontsize=15.0)
                    plt.xticks(fontsize=12.5)
                    plt.yticks(fontsize=12.5)
                    writer.grab_frame()
                    plt.cla()
                    plt.clf()

        mpl.use("TkAgg")

        if timeout_error:
            fig, ax = plt.subplots()
            ax.scatter(x, y, c=1 + clustering.labels_, s=150, cmap=cm.Paired)
            ax.plot(hull_pts[0], hull_pts[1], 'b--')
            ax.plot(hull_pts[0][0], hull_pts[1][0], 'bo')
            ax.plot(hull_pts[0][1], hull_pts[1][1], 'bx')
            ax.plot([self.xmin, self.xmax], [0.0, 0.0], 'r-')
            ax.plot([self.xmin, self.xmax], [self.Ly, self.Ly], 'r-')
            plt.xlabel("x [nm]", fontsize=25)
            plt.ylabel("y [nm]", fontsize=25)
            plt.xticks(fontsize=20.0)
            plt.yticks(fontsize=20.0)
            plt.show()

        if concave_error:
            fig, ax = plt.subplots()
            ax.scatter(x, y, c=1 + clustering.labels_, s=150, cmap=cm.Paired)
            ax.plot(xcom, 0.5 * self.Ly, 'rx', markersize=25)
            ax.plot([self.xmin, self.xmax], [0.0, 0.0], 'r-')
            ax.plot([self.xmin, self.xmax], [self.Ly, self.Ly], 'r-')
            plt.xlabel("x [nm]", fontsize=25)
            plt.ylabel("y [nm]", fontsize=25)
            plt.xticks(fontsize=20.0)
            plt.yticks(fontsize=20.0)
            plt.show()
示例#8
0
def get_perimeter(srf_file, depth=True, plot=False):
    """
    Like get_bounds but works with roughness where the edges aren't straight.
    srf_file: assumed to be finite fault
    depth: work in progress, need to find associated points or do 3d concave hull
    plot: for testing only, plot points, perimeter and show
    """
    if plot:
        from matplotlib import pyplot as plt
        from descartes import PolygonPatch

    perimeters = []
    top_edges = []
    if depth:
        value = "depth"
    else:
        value = None

    with open(srf_file, "r") as sf:
        planes = read_header(sf, idx=True)
        points = int(sf.readline().split()[1])

        for i in range(len(planes)):
            a = []
            nstk = planes[i]["nstrike"]
            ndip = planes[i]["ndip"]
            points = np.array(
                [get_lonlat(sf, value=None) for j in range(ndip * nstk)])

            # The value of alpha parameter determines how tightly points are enclosed
            # alpha= 0 means we get a convex-hull, but often a concave-hull represents a better fit.
            # Viktor reported alpha=600 worked ok with SRF (roughness 0.1) but it is too high and often misses points entirely.
            # if no alpha is given, the optimal value is to be found, but is impractically slow.
            # The following will try to optimize alpha with 10 iterations (default is 1000), and if no success, alpha=0 (convex hull)

            alpha = optimizealpha(points, max_iterations=10)
            ashape = alphashape(points, alpha)
            perimeters.append(np.dstack(ashape.exterior.coords.xy)[0])

            if plot:
                fig, ax = plt.subplots()
                ax.scatter(*zip(*points))
                ax.add_patch(PolygonPatch(ashape, alpha=0.2))
                plt.show()
                plt.close()

            # try to find top edges in perimeter
            # closest point in case corner not in perimeter (srf roughness)
            # roughness may result in closest point being a couple meters out
            # euclidian ok, even SRF res is only 100m
            # TODO: include depth to prevent issues with 90 degree dips
            c1 = perimeters[-1] - points[0]
            # minimum sum of squares
            c1 = np.argmin(np.einsum("ij,ij->i", c1, c1))
            c2 = perimeters[-1] - points[nstk - 1]
            c2 = np.argmin(np.einsum("ij,ij->i", c2, c2))
            # assume shorter edge is top edge
            if abs(c2 - c1) < len(perimeters[-1]) / 2:
                # edge doesn't wrap array
                start = min(c1, c2)
                end = max(c1, c2)
                top_edges.append(perimeters[-1][start:end + 1])
            else:
                # edge wraps array ends
                start = max(c1, c2)
                end = min(c1, c2)
                top_edges.append(
                    np.vstack(
                        (perimeters[-1][start:], perimeters[-1][:end + 1])))

    return perimeters, top_edges
def concaveHull(points, communities, alpha=.018):
    """
    Calculate the concave hull (external boundary) for a set of points, while also
    keeping track of the communities for each boundary point.

    Parameters
    ----------

    points : numpy.ndarray or list
        A set of points of shape (N, 2).

    communities : numpy.ndarray or list
        The community assignments for each point in points.

    alpha : float
        The alpha parameter for creating the hull; determines how angular or concave
        the final result is. Default value was choosen by using the alphashape.optimize
        function. If value is set to None, this method will be run explicitly to find
        a good value (though it takes a significantly longer period of time).

    Returns
    -------

    (numpy.ndarray, numpy.ndarray) : The lines that comprise the concave hull (1st element) and
        the communities that each point in each line belongs to (2nd element). Individual hull lines are
        formatted as:
        [[x1, x2], [y1, y2]]

    """
    # Find the total boundary around the shape
    # The .80 is to say that we don't want the boundary to be crazy angular
    if alpha == None:
        alpha = 0.80 * ap.optimizealpha(points)
    #print(alpha)
    hull = ap.alphashape(points, alpha)
    hullPoints = hull.exterior.coords.xy

    # And convert to a better format
    hullPoints = [hullPoints[0].tolist(), hullPoints[1].tolist()]

    # Now we also want to know what communities the points involved
    # in the boundary are (for creating closed shapes later on)
    # You can't use a list as a key for a dictionary, so we take the string
    # that represents the list. Not ideal, but it shouldn't cause any real issues
    communitiesByPointPosition = {}
    for i in range(len(points)):
        communitiesByPointPosition[str([points[i,0], points[i,1]])] = communities[i]

    # Transform to looking at the lines of the hull (instead of the points)
    hullLines = np.zeros([len(hullPoints[0]), 2, 2])
    hullLineCommunities = np.zeros([len(hullPoints[0]), 2])

    for i in range(len(hullPoints[0])):
        # Each of these lines are of the form:
        # [[x1, x2], [y1, y2]]
        hullLines[i] = [[hullPoints[0][i], hullPoints[0][(i+1)%len(hullPoints[0])]],
                        [hullPoints[1][i], hullPoints[1][(i+1)%len(hullPoints[0])]]]

        # This line is pretty disgusting, but unfortunately it can't really be avoided
        # because we need to know which communities the boundary lines connect :/
        hullLineCommunities[i] = [communitiesByPointPosition[str([hullPoints[0][i], hullPoints[1][i]])],
                                  communitiesByPointPosition[str([hullPoints[0][(i+1)%len(hullPoints[0])], hullPoints[1][(i+1)%len(hullPoints[0])]])]]

    return hullLines, hullLineCommunities
示例#10
0
Optimized Alpha Example
=======================

Using the optimized alpha function for obtaining the alpha parameter.

"""
import alphashape
import matplotlib.pyplot as plt
from descartes import PolygonPatch

# Define input points
points = [(0., 0.), (0., 1.), (1., 1.), (1., 0.), (0.5, 0.25), (0.5, 0.75),
          (0.25, 0.5), (0.75, 0.5)]

# Determine the optimized alpha parameter
alpha = alphashape.optimizealpha(points)

# Generate the alpha shape
alpha_shape = alphashape.alphashape(points, alpha)

# Initialize plot
fig, ax = plt.subplots()

# Plot input points
ax.scatter(*zip(*points))

# Plot alpha shape
ax.add_patch(PolygonPatch(alpha_shape, alpha=.2))

plt.show()