コード例 #1
0
def fit_circle(points_l, scale, debug=False):
    """Get information about a circle from a list of points `points_l`.

    This may involve fitting a circle or ellipse to a set of points?

    pip install circle-fit
    https://github.com/AlliedToasters/circle-fit

    Assuing for now that points_l contains a list of (x,y,z) points, so we
    take only (x,y) and scale according to `scale`. Both methods return a
    tuple of four values:

    xc: x-coordinate of solution center (float)
    yc: y-coordinate of solution center (float)
    R: Radius of solution (float)
    variance or residual (float)

    These methods should be identical if we're querying this with actual
    circles. Returning the second one for now.
    """
    from circle_fit import hyper_fit, least_squares_circle
    data = [(item[0] * scale, item[1] * scale) for item in points_l]
    data = np.array(data)
    circle_1 = hyper_fit(data)
    circle_2 = least_squares_circle(data)
    xc_1, yc_1, r_1, _ = circle_1
    xc_2, yc_2, r_2, _ = circle_2
    if debug:
        print(f'(hyperfit) rad {r_1:0.4f}, center ({xc_1:0.4f},{yc_1:0.4f})')
        print(f'(least-sq) rad {r_2:0.4f}, center ({xc_2:0.4f},{yc_2:0.4f})')
    return circle_2
コード例 #2
0
def get_xy_coords_for_circles(circles):

    for i in range(len(circles)):

        x_coor = circles[i]["lon"] * 111.320 * cos(
            np.radians(circles[i]["lat"])) * 1000
        y_coor = circles[i]["lat"] * 110.54 * 1000
        # converting from lat, lon to coordinates in metre from (0,0).

        c_xc = np.full(np.size(x_coor, 1), np.nan)
        c_yc = np.full(np.size(x_coor, 1), np.nan)
        c_r = np.full(np.size(x_coor, 1), np.nan)

        for j in range(np.size(x_coor, 1)):
            a = ~np.isnan(x_coor.values[:, j])
            if a.sum() > 4:
                c_xc[j], c_yc[j], c_r[j], _ = cf.least_squares_circle([
                    (k, l)
                    for k, l in zip(x_coor.values[:, j], y_coor.values[:, j])
                    if ~np.isnan(k)
                ])

        circle_y = np.nanmean(c_yc) / (110.54 * 1000)
        circle_x = np.nanmean(c_xc) / (111.320 * cos(np.radians(circle_y)) *
                                       1000)

        circle_diameter = np.nanmean(c_r) * 2

        xc = [None] * len(x_coor.T)
        yc = [None] * len(y_coor.T)

        xc = np.mean(x_coor, axis=0)
        yc = np.mean(y_coor, axis=0)

        delta_x = x_coor - xc  # *111*1000 # difference of sonde long from mean long
        delta_y = y_coor - yc  # *111*1000 # difference of sonde lat from mean lat

        circles[i]["platform_id"] = circles[i].platform_id.values[0]
        circles[i]["flight_altitude"] = circles[i].flight_altitude.mean(
        ).values
        circles[i]["circle_time"] = (
            circles[i].launch_time.mean().values.astype("datetime64"))
        # circles[i].encoding["circle_time"] = {
        #     "units": "seconds since 2020-01-01",
        #     "dtype": "datetime64[ns]",
        # }
        circles[i]["circle_lon"] = circle_x
        circles[i]["circle_lat"] = circle_y
        circles[i]["circle_diameter"] = circle_diameter
        circles[i]["dx"] = (["sounding", "alt"], delta_x)
        circles[i]["dy"] = (["sounding", "alt"], delta_y)

    return print("Circles ready for regression")
コード例 #3
0
ファイル: identify_circles.py プロジェクト: Makhaos/tubus
    def get_valid_radii(self):  # Creates circles from contours and accepts a certain interval for circles radius
        cont = EdgeDetection.total_contour_list
        valid_circles_list_total = list()
        valid_circles_list = list()

        for image_number, image in enumerate(cont):
            for contours in image:
                x_center, y_center, radius, _ = cf.least_squares_circle(contours[:, 0])
                if 30 < radius < 200:
                    valid_circles_list.append([image_number, x_center, y_center, radius])
            valid_circles_list_total.append(valid_circles_list)
            valid_circles_list = list()
            CirclePosition.circle_features = valid_circles_list_total
コード例 #4
0
def check_arc(points):
    # PULL X Y COORDS
    coords = [[s['X'], s['Y']] for s in points] 
    # print(f"no.points: {len(coords)}")

    # FIT CIRCLE 
    xc,yc,r,s = cf.least_squares_circle(coords)
    if DEBUG: print(f"CIRCLE FITTED:\n    X: {xc},\n    Y: {yc},\n    R: {r},\n    S: {s}")

    if s < Sthreshold:
        return True
    else:
        return False
コード例 #5
0
def fit_circle(gcode):
    """
    Takes a list of GCode commands in dict form and uses the least squares method to fit a cirlce. Returns xc, yx, r, s.
    """

    # PULL X Y COORDS
    coords = [[s['X'], s['Y']] for s in gcode] 

    # FIT CIRCLE 
    xc,yc,r,s = cf.least_squares_circle(coords)

    if DEBUG: print(f"CIRCLE FITTED:\n    X: {xc},\n    Y: {yc},\n    R: {r},\n    S: {s}")

    return xc, yc, r, s
コード例 #6
0
def compute_arc_move(points):

    # PULL X Y COORDS
    coords = [[s['X'], s['Y']] for s in points] 

    # FIT CIRCLE 
    xc,yc,r,s = cf.least_squares_circle(coords)
    if DEBUG: print(f"CIRCLE FITTED:\n    X: {xc},\n    Y: {yc},\n    R: {r},\n    S: {s}")

    # DETERMINE MOVE TYPE
    movetype = move_type(coords[0][:2], coords[1][:2], (xc, yc))

    # SUM E TOTAL
    E_total = sum([i['E'] for i in points])

    # FORMULATE G CODE COMMAND
    if s < Sthreshold:
        COMMAND = f"{movetype} X{coords[-1][0]} Y{coords[-1][1]} R{round(r, 5)} E{round(E_total, 5)}"
        if DEBUG: print(f'{round(s, 5)} : {COMMAND}')
        return COMMAND
    else:
        print(f"{round(s, 5)} : NOT AN ARC MOVE")


    # ------------- PLOTTING --------------
    # ASK TO PLOT
    if PLOTTING:
        # CREATE FIGURE
        fig, ax = plt.subplots()
        ax.set_aspect(1)
        #ax.set_xlim([50,150])
        #ax.set_ylim([50,150])

        # PLOT SCATTER POINTS
        plt.scatter([i[0] for i in coords], [i[1] for i in coords])

        # PLOT CIRCLE
        circle1 = plt.Circle((xc, yc), r, linestyle='--', fill=False)
        ax.add_artist(circle1)

        # SHOW PLOT
        plt.show()
コード例 #7
0
def process_img(frame):
    # Convert BGR to HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # define range of blue color in HSV
    lowbound = np.array([0, 0, 0])
    uppbound = np.array([70, 255, 214])

    # inrange only colours of hand, then remove gaps
    mask = cv2.inRange(hsv, lowbound, uppbound)
    kernel = np.ones((5, 5), np.uint8)

    # dilate
    mask = cv2.dilate(mask, kernel, iterations=1)
    mask = cv2.erode(mask, kernel, iterations=1)

    hand = cv2.bitwise_and(frame, frame, mask=mask)

    print(hand.shape)
    im = hand.copy()
    hand = cv2.cvtColor(hand, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(hand, 100, 255, 0)

    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_NONE)
    cnts = contours
    hand_cnt = []
    for c in cnts:
        # if the contour is not sufficiently large, ignore it
        if cv2.contourArea(c) < 100:
            continue

        # compute the rotated bounding box of the contour.
        x, y, w, h = cv2.boundingRect(c)
        if (x, y) == (0, 0):
            continue

        cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.drawContours(hand, c, -1, (0, 255, 255))
        hand_cnt.append(c)
    #keeping doing until find a hand
    if len(hand_cnt) > 1 or len(hand_cnt) == 0:
        cv2.imshow('hand', im)
        print("keep finding hand")
    else:
        c = hand_cnt[0]
        hull = cv2.convexHull(c, returnPoints=False)
        defects = cv2.convexityDefects(c, hull)

        # creat lists to store start points and far points
        start_p = []
        far_p = []
        points = []
        for i in range(defects.shape[0]):
            s, e, f, d = defects[i, 0]

            start = tuple(c[s][0])
            end = tuple(c[e][0])

            far = tuple(c[f][0])
            start_p.append((c[s][0]))
            far_p.append(c[f][0])
            cv2.line(im, start, end, [0, 255, 0], 2)

            if i > 0:
                x1, y1 = far_p[i - 1]
                x2, y2 = far_p[i]
                if dist(x1, x2, y1, y2) > 50:
                    rightmost = tuple(c[c[:, :, 0].argmax()][0])
                    if abs(x2 - rightmost[0]) > 30:
                        points.append((x2, y2))
                else:
                    continue
        for i in range(len(points)):
            x, y = points[i]

            cv2.circle(im, (x, y), 5, [0, 0, 255], -1)
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(im, str(i), (x + 10, y + 10), font, 0.5,
                        (255, 255, 255), 2, cv2.LINE_AA)

            # cv2.circle(im, start, 2, [0, 255, 255], -1)
        if len(points) != 10:
            cv2.imshow('hand', im)
        else:
            even = [0, 2, 4, 6, 8, 10]
            odd = [1, 3, 5, 7, 9]
            fingers = {
                'pinky': 0,
                'ring': 0,
                'middle': 0,
                'index': 0,
                'thumb': 0
            }
            finger_length = []
            mid_points = []
            # find middle points, noted the one for index is inaccurate
            for i in range(len(even) - 1):
                x1, y1 = points[even[i]]
                x2, y2 = points[even[i + 1]]
                mx, my = midpoint(x1, x2, y1, y2)
                mid_points.append((mx, my))
                tx, ty = points[odd[i]]
                finger_length.append(dist(mx, tx, my, ty))

            # fit middle points in a circle curve
            data = []
            for i in range(4):
                data.append(points[even[i]])

            xc, yc, r, _ = cf.least_squares_circle(data)
            xc, yc = int(xc), int(yc)
            cv2.circle(im, (xc, yc), 5, [0, 255, 255], -1)
            mid_middle = mid_points[2]

            angle_mid_middle = find_angle(xc, mid_middle[0], yc, mid_middle[1])
            angle_6 = find_angle(xc, points[6][0], yc, points[6][1])
            # for the case centre is above point 6
            if yc >= mid_middle[1]:
                angle = (angle_6 - angle_mid_middle) + angle_6
            elif points[6][1] <= yc < mid_middle[1]:
                angle = (angle_6 + angle_mid_middle) + angle_6
            # correct the index finger length
            xi = xc - r * math.cos(angle)
            yi = yc - r * math.sin(angle)
            mid_index = (xi, yi)
            mid_points[3] = mid_index
            finger_length[3] = dist(points[7][0], xi, points[7][1], yi)
            for i in range(5):
                xm, ym = mid_points[i]
                xm, ym = int(xm), int(ym)
                cv2.circle(im, (xm, ym), 6, [175, 255, 255], -1)
            count = 0
            for name in fingers:
                fingers[name] = finger_length[count]
                count += 1
                print(name, ":", fingers[name])
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(
                    im, str(fingers[name]),
                    (points[odd[count]][0] + 10, points[odd[count]][1] + 10),
                    font, 0.5, (255, 255, 175), 2, cv2.LINE_AA)
            cv2.imshow('frame', im)
コード例 #8
0
ファイル: image.py プロジェクト: michaelaye/venim
 def circle_fit(self):
     xCtr, yCtr, r, _ = cf.least_squares_circle(self.points_data.values)
     return hv.Ellipse(xCtr, yCtr, 2 * r).opts(color="red")
コード例 #9
0
def process_img(frame, right_hand):
    if right_hand == False:
        frame = cv2.flip(frame, 0)
    rows, cols, c = frame.shape
    framearea = float(rows * cols)

    # Convert
    img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    img = cv2.GaussianBlur(img, (7, 7), 0)

    # Process
    ret, thresh = cv2.threshold(img, 70, 255, 0)
    img = cv2.bitwise_and(img, thresh)

    #apply black border to aid contours
    border = 10
    bordmask = np.zeros((rows, cols), np.uint8)
    bordmask[border:rows - border, border:cols - border] = 1
    img = cv2.bitwise_and(img, img, mask=bordmask)

    minval = 0
    maxval = 255
    # edge detection
    edg = cv2.Canny(img, minval, maxval, apertureSize=3, L2gradient=True)
    # countour detection
    # opening and closing
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(edg, cv2.MORPH_OPEN, kernel)
    closing = cv2.morphologyEx(edg, cv2.MORPH_CLOSE, kernel)
    edg = closing

    contours, hierarchy = cv2.findContours(edg, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_NONE)
    hand = cv2.bitwise_and(frame, frame, mask=thresh)
    im = hand.copy()

    #find and draw contours
    cnts = contours
    hand_cnt = []
    for ci, c in enumerate(cnts):
        # if the contour is not sufficiently large, or if it's too big, ignore it
        if not framearea / 400.0 < cv2.contourArea(c) < framearea / 1.06:
            continue
        # compute the rotated bounding box of the contour.
        x, y, w, h = cv2.boundingRect(c)

        ellipse = _, _, orient_angle = cv2.fitEllipse(c)
        print(ci, orient_angle)
        cv2.ellipse(im, ellipse, (0, 0, 255), 2)

        #im = rotate_image(im, orient_angle, rows, cols)

        if x == 0:
            continue

        cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.drawContours(im, c, -1, (0, ci * 255, 255))
        hand_cnt.append(c)
    print(len(contours), len(hand_cnt))

    #keeping doing until find a hand
    if len(hand_cnt) < 1:
        #cv2.imshow('hand',im)
        print("keep finding hand, contour not found")
    else:
        c = hand_cnt[1] if len(hand_cnt) > 1 else hand_cnt[0]
        hull = cv2.convexHull(c, returnPoints=False)
        defects = cv2.convexityDefects(c, hull)

        # creat lists to store start points and far points
        start_p = []
        end_p = []
        far_p = []
        points = []

        for i in range(defects.shape[0]):
            s, e, f, d = defects[i, 0]

            start = tuple(c[s][0])
            end = tuple(c[e][0])

            far = tuple(c[f][0])
            start_p.append((c[s][0]))
            end_p.append((c[e][0]))
            far_p.append(c[f][0])
            cv2.line(im, start, end, [0, 255, 0], 2)
            #set ratio of constriant distance
            ratio = 0.18
            ratio_s = 0.09
            ratio_d = 0.065
            #ratio_d = 0.03
            if i == 0:
                x2, y2 = far_p[i]
                cv2.circle(im, (x2, y2), 5, [0, 0, 255], -1)
                points.append((x2, y2))
            else:
                #defect points
                x1, y1 = far_p[i - 1]
                x2, y2 = far_p[i]
                cv2.circle(im, (x2, y2), 5, [0, 0, 255], -1)

                #start and end points
                sx, sy = start_p[i]
                sx_1, sy_1 = start_p[i - 1]
                ex, ey = end_p[i]
                #take the only start point at finger tips
                if dist(sx, sx_1, sy, sy_1) > ratio_s * im.shape[1]:
                    if dist(sx, ex, sy, ey) > ratio_s * im.shape[1]:
                        points.append((sx, sy))

                if dist(x1, x2, y1, y2) > ratio_d * im.shape[1]:
                    bottommost = tuple(c[c[:, :, 1].argmax()][0])
                    rightmost = tuple(c[c[:, :, 0].argmax()][0])
                    topmost = tuple(c[c[:, :, 1].argmin()][0])

                    if abs(x2 - rightmost[0]) > ratio * im.shape[1]:

                        points.append((x2, y2))
                else:
                    continue

        #plot start points
        for i in range(len(start_p)):
            sx, sy = start_p[i]
            cv2.circle(im, (sx, sy), 2, [0, 125, 255], -1)
        #get all the points far away enough from right edge only
        pc = []
        ratio1 = 0.18
        for i in range(len(points)):
            px, py = points[i]
            if abs(px - rightmost[0]) > ratio1 * im.shape[1]:
                pc.append((px, py))
        points = pc
        if points[1][0] >= bottommost[0]:
            points[1] = bottommost
        if points[9][0] >= topmost[0]:
            points[9] = topmost
        if len(points) < 11:
            for i in range(1, 12 - len(points)):
                points.append(far_p[-i])

        #cv2.setMouseCallback('image', click_to_add)

        for i in range(len(points)):
            x, y = points[i]

            #cv2.circle(im, (x, y), 5, [0, 0, 255], -1)

            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(im, str(i), (x + 10, y + 10), font, 0.5,
                        (255, 255, 255), 2, cv2.LINE_AA)

            # cv2.circle(im, start, 2, [0, 255, 255], -1)
        #cv2.imshow('hand',im)
        #cv2.waitKey(0)
        if len(points) < 10:
            print("not enough points")
        else:
            even = [0, 2, 4, 6, 8, 10]
            odd = [1, 3, 5, 7, 9]

            fingers = {
                'pinky': 0,
                'ring': 0,
                'middle': 0,
                'index': 0,
                'thumb': 0
            }
            finger_length = []
            mid_points = []
            # find middle points, noted the one for index is inaccurate
            for i in range(len(even) - 1):
                x1, y1 = points[even[i]]
                x2, y2 = points[even[i + 1]]
                mx, my = midpoint(x1, x2, y1, y2)
                mid_points.append((mx, my))
                tx, ty = points[odd[i]]
                finger_length.append(round(dist(mx, tx, my, ty), 1))

            # fit middle points in a circle curve
            data = []
            for i in range(4):
                data.append(points[even[i]])

            xc, yc, r, _ = cf.least_squares_circle(data)
            xc, yc = int(xc), int(yc)
            cv2.circle(im, (xc, yc), 5, [0, 255, 255], -1)
            mid_middle = mid_points[2]
            #get points for line construction for each finger
            finger_line = []
            for i in range(5):
                a1, b1 = points[odd[i]]
                a1, b1 = int(a1), int(b1)
                a2, b2 = mid_points[i]
                a2, b2 = int(a2), int(b2)
                finger_line.append([(a2, b2), (a1, b1)])

            angle_mid_middle = find_angle(xc, mid_middle[0], yc, mid_middle[1])
            angle_6 = find_angle(xc, points[6][0], yc, points[6][1])

            # for the case centre is below point 6
            if yc >= mid_middle[1]:
                angle = (angle_6 - angle_mid_middle) + angle_6
                xi = xc - r * cos(angle)
                yi = yc - r * sin(angle)
            # for the case yc is in between
            elif points[6][1] <= yc < mid_middle[1]:
                angle = (angle_6 + angle_mid_middle) + angle_6
                xi = xc - r * cos(angle)
                yi = yc - r * sin(angle)
            else:
                # for the case points 6 and mid_middle both below yc
                if (angle_mid_middle - angle_6) <= angle_6:
                    angle = angle_6 - (angle_mid_middle - angle_6)
                    xi = xc - r * cos(angle)
                    yi = yc + r * sin(angle)
                # for the case index_mid will be above yc
                else:
                    angle = (angle_mid_middle - angle_6) - angle_6
                    xi = xc - r * cos(angle)
                    yi = yc - r * sin(angle)

            # correct the index finger length
            mid_index = (xi, yi)
            mid_points[3] = mid_index
            finger_line[3][0] = tuple([int(i) for i in mid_index])
            finger_length[3] = round(dist(points[7][0], xi, points[7][1], yi),
                                     1)
            for i in range(5):
                xm, ym = mid_points[i]
                xm, ym = int(xm), int(ym)
                cv2.circle(im, (xm, ym), 6, [175, 255, 255], -1)

            count = 0
            for name in fingers:
                fingers[name] = finger_length[count]
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(
                    im, str(int(fingers[name])),
                    (points[odd[count]][0] - 10, points[odd[count]][1] - 10),
                    font, 0.5, (255, 255, 175), 2, cv2.LINE_AA)
                count += 1

    return im
コード例 #10
0
    for nf in range (0,Nframes):
        time.time()
        rx = signal[nf*N:(nf+1)*N]
        s = sine1.gen2()
        g = rx*np.conj(s)
        d = sigs.decimate(g, D, 20, ftype='fir', zero_phase=True)
        d.flatten()
        # buffer
        buff.put(d)
        df = buff.get()
        #print(df)
        # Circle Fitting
        auxA = np.real(df)
        auxB = np.imag(df)
        print(auxA)
        P = circle_fit.least_squares_circle([auxA, auxB])
        print(P)
        # low pass memory filter
        x = axy*P[0] + (1-axy)*x
        y = axy*P[1] + (1-axy)*y
        r = ar*P[3] + (1-ar)*r

        # Signal Filtering
        dfit = (np.real(d)-x) + 1j*(np.imag(d)-y)

        # Angle conditioning
        phi = np.angle(dfit)
        phi = np.unwrap(phi)
        phi,z = sigs.lfilter(B, A, phi, zi = z)

        win.put(phi)
コード例 #11
0
# axes(handles.axes5);
# set(handles.axes5,'visible', 'on');
# set(handles.panel_ft_input_tag,'visible', 'on');
# set(handles.ft_panel_tag,'visible', 'on');
# set(handles.auto_ft_panel_tag,'visible', 'on');

axialc = axial - axial_median
lateralc = lateral - lateral_median
plt.scatter(lateralc, axialc)
plt.xlabel('Lateral (nm)')
plt.ylabel('Axial (nm)')
plt.title('Combined structures')

xy = np.vstack((lateralc, axialc)).T
circle = circle_fit.least_squares_circle(xy)
xc = circle[0]
yc = circle[1]
Rc = circle[2]
dc = 2 * Rc

plotcircle = circle_fit.plot_data_circle(lateralc, axialc, xc, yc, Rc)

# box on
# daspect([1 1 1])
# zlimits = [min((axial-axial_median))-0.1*(max(axial-axial_median)-...
#     min(axial-axial_median)) max((axial-axial_median))+0.1*(max(axial...
#     -axial_median)-min(axial-axial_median))]; %'zlimits' establishes an axial
#                                        % range centered at the axial
#                                        % 'median' position, and spanning
#                                        % over an axial length 20% greater
コード例 #12
0
def singleCircleAnalysis(sc_img,
                         settings,
                         prev_result=None,
                         showplot=True,
                         iterations=2):
    """
    Analyzes an image with only one circle in it. Having more is possible but will most likely fail.
    A result by means of hough transform or earlier investigation can be passed (cx, cy, r). If not, cx, cy is set to
    centre of image.
    :param sc_img: circle image
    :param nphi: number of angles at which lines will be used to evaluate intensity from centre point towards image
                 border
    :param prev_result: list or numpy array ordered like [cx, cy, r] whith center points cx, cy and radius r
    :param showplot: results will be plotted. default is True
    :return: image with circle where center of image is center of found circle. Therefore image may be smaller in size
    """
    nphi = settings['nphi']
    ny, nx = np.shape(sc_img)
    phi_ls = np.linspace(0, 2 * math.pi * (1 - 1 / nphi), nphi)
    # do it once to get length of line:
    # print("prev_result", prev_result)
    _, _, tmp = interp_along_radius(sc_img,
                                    0,
                                    centre=(prev_result[0], prev_result[1]))
    intensity_lines = np.zeros(shape=(len(tmp), len(phi_ls)))
    pts_of_max_int = np.zeros(shape=(nphi, 2))

    xcentre = nx / 2
    ycentre = ny / 2

    if showplot:
        fig, (axs1, axs2, axs3) = plt.subplots(1, 3, figsize=(10, 5))
        axs2.imshow(sc_img)

    intensity_lines = np.zeros(shape=(len(tmp), len(phi_ls)))
    pts_of_max_int = np.zeros(shape=(nphi, 2))
    for (i, p) in enumerate(phi_ls):
        x, y, tmp = interp_along_radius(sc_img,
                                        p,
                                        centre=(prev_result[0],
                                                prev_result[1]))
        #  put line into array:
        intensity_lines[:, i] = tmp
        pts_of_max_int[i, 0] = np.mean(x[np.where(tmp == np.amax(tmp))[0]])
        pts_of_max_int[i, 1] = np.mean(y[np.where(tmp == np.amax(tmp))[0]])
        if showplot:
            axs2.plot(x, y, 'k--')

    xmax = pts_of_max_int[:, 0]
    ymax = pts_of_max_int[:, 1]
    # fit circle through pts:
    xc, yc, r, _ = cf.least_squares_circle(np.array([ymax, xmax]).transpose())
    if r < settings['minRad'] or r > settings['maxRad']:
        # if found radius outside of defined range, set to zero
        r = np.nan

    if showplot:
        axs2.scatter(ymax, xmax, c='r')
        # circle from hough:
        if prev_result is not None:
            c = plt.Circle((prev_result[0], prev_result[1]),
                           prev_result[2],
                           fill=False,
                           color='red',
                           linestyle='--',
                           linewidth=3)
            axs2.add_artist(c)
        # circle newly found:
        if r is not np.nan:
            c = plt.Circle((xc, yc), r, fill=False, color='black', linewidth=3)
            axs2.add_artist(c)
            axs2.scatter(xc, yc, c='g', marker='+', s=20000)

    lx = np.shape(sc_img)[0]
    ly = np.shape(sc_img)[1]
    dx = min(abs(lx - xc), lx) - 1
    dy = min(abs(ly - yc), ly) - 1

    cropnew = False
    if cropnew:
        return_img = sc_img[int(yc - dy):int(yc + dy),
                            int(xc - dx):int(xc + dx)]
        # translate coordinates of new circle to new image:
        xc = xc - (xc - dx)
        yc = yc - (yc - dy)
    else:
        return_img = sc_img

    if showplot:
        ny, nx = np.shape(intensity_lines)
        XX, YY = np.meshgrid(np.arange(nx), np.arange(ny))
        axs1.contourf(XX, YY, intensity_lines)
        axs1.scatter(
            np.arange(nx),
            np.sqrt(np.square(xmax - xcentre) + np.square(ymax - ycentre)),
            c='r')
        axs1.set_xlim([0, nx - 1])
        every = 2
        axs1.set_xticks(np.arange(nphi)[::every])
        axs1.set_xticklabels(
            ["%4.1f" % (p * 180 / math.pi) for p in phi_ls[::every]],
            rotation=0)
        axs1.set_xlabel('angle [°]')
        axs1.set_ylim([0, np.shape(XX)[0] - 1])
        axs1.set_ylabel('Radius [px]')
        axs2.set_xlabel('x [px]')
        axs2.set_ylabel('y [px]')

        # print preview of new image and plot newly found circle in there (Note the displacement)
        if r is not np.nan:
            axs3.imshow(return_img)
            c = plt.Circle((xc, yc), r, fill=False, color='black', linewidth=3)
            axs3.add_artist(c)
            plt.show()

    return return_img, [xc, yc, r]
コード例 #13
0
ファイル: test.py プロジェクト: yisonghan/circle-fit
 def test_circle_fit(self):
     circle = least_squares_circle(self.data)
     circle = least_squares_circle(self.numpy_data)
コード例 #14
0
def process_img(frame):
    img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # blur it
    img = cv2.GaussianBlur(img, (7, 7), 0)

    ret, thresh = cv2.threshold(img, 70, 255, 0)
    img = cv2.bitwise_and(img, thresh)
    minval = 0
    maxval = 255


    # ret,edg = cv2.threshold(img,12,255,cv2.THRESH_BINARY)
    # cv2.imshow('i', edg)

    # edge detection
    edg = cv2.Canny(img, minval, maxval, apertureSize=3, L2gradient=True)
    # countour detection
    # minval,maxval = 84,84
    # opening and closing
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(edg, cv2.MORPH_OPEN, kernel)
    closing = cv2.morphologyEx(edg, cv2.MORPH_CLOSE, kernel)
    edg = closing


    contours, hierarchy = cv2.findContours(edg, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    hand = cv2.bitwise_and(frame,frame, mask=thresh)

    #print(hand.shape)
    im = hand.copy()

    cnts = contours
    hand_cnt = []
    for c in cnts:
        # if the contour is not sufficiently large, ignore it
        if cv2.contourArea(c) < 400:
            continue

        # compute the rotated bounding box of the contour.
        x, y, w, h = cv2.boundingRect(c)
        if (x, y) == (0, 0):
            continue

        cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.drawContours(im, c, -1, (0, 255, 255))
        hand_cnt.append(c)
    #keeping doing until find a hand
    if len(hand_cnt)!=1:
        cv2.imshow('hand',im)

    else:
        c = hand_cnt[0]
        hull = cv2.convexHull(c, returnPoints=False)
        defects = cv2.convexityDefects(c, hull)

        # creat lists to store start points and far points
        start_p = []
        end_p =[]
        far_p = []
        points = []
        for i in range(defects.shape[0]):
            s, e, f, d = defects[i, 0]

            start = tuple(c[s][0])
            end = tuple(c[e][0])

            far = tuple(c[f][0])
            start_p.append((c[s][0]))
            end_p.append((c[e][0]))
            far_p.append(c[f][0])
            cv2.line(im, start, end, [0, 255, 0], 2)

            if i > 0:
                #defect points
                x1, y1 = far_p[i - 1]
                x2, y2 = far_p[i]
                #start and end points
                sx, sy = start_p[i]
                sx_1, sy_1 = start_p[i - 1]
                ex, ey = end_p[i]
                #take the only start point at finger tips
                if dist(sx, sx_1, sy, sy_1) > 40:
                    if dist(sx, ex, sy, ey) > 40:
                        points.append((sx, sy))

                if dist(x1, x2, y1, y2) > 35:
                    rightmost = tuple(c[c[:, :, 0].argmax()][0])
                    if abs(x2 - rightmost[0]) > 80:

                        points.append((x2, y2))
                else:
                    continue
        pc = []

        for i in range(len(points)):
            px,py = points[i]
            if abs(px - rightmost[0]) >70:
                pc.append((px, py))
        points =pc

        for i in range(len(points)):
            x, y = points[i]

            cv2.circle(im, (x, y), 5, [0, 0, 255], -1)
            #plot start points
            sx,sy =start_p[i]
            #cv2.circle(im, (sx, sy), 3, [0, 125, 255], -1)
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(im, str(i), (x + 10, y + 10), font, 0.5, (255, 255, 255), 2, cv2.LINE_AA)

            # cv2.circle(im, start, 2, [0, 255, 255], -1)


        if len(points)<10:
            print("not enough contour points")
            cv2.imshow('hand',im)
        else:
            even = [0, 2, 4, 6, 8, 10]
            odd = [1, 3, 5, 7, 9]

            fingers = {'pinky': 0, 'ring': 0, 'middle': 0, 'index': 0, 'thumb': 0}
            finger_length = []
            mid_points = []
            # find middle points, noted the one for index is inaccurate
            for i in range(len(even) - 1):
                x1, y1 = points[even[i]]
                x2, y2 = points[even[i + 1]]
                mx, my = midpoint(x1, x2, y1, y2)
                mid_points.append((mx, my))
                tx, ty = points[odd[i]]
                finger_length.append(dist(mx, tx, my, ty))

            # fit middle points in a circle curve
            data = []
            for i in range(4):
                data.append(points[even[i]])

            xc, yc, r, _ = cf.least_squares_circle(data)
            xc, yc = int(xc), int(yc)
            cv2.circle(im, (xc, yc), 5, [0, 255, 255], -1)
            mid_middle = mid_points[2]
            #get points for line construction for each finger
            finger_line = []
            for i in range(4):
                a1, b1 = points[odd[i]]
                a1,b1 = int(a1), int(b1)
                a2, b2 = mid_points[i]
                a2,b2 = int(a2), int(b2)
                finger_line.append([(a2,b2),(a1,b1)])
            angle_mid_middle = find_angle(xc, mid_middle[0], yc, mid_middle[1])
            angle_6 = find_angle(xc, points[6][0], yc, points[6][1])
            # for the case centre is below point 6
            if yc >= mid_middle[1]:
                angle = (angle_6 - angle_mid_middle) + angle_6
                xi = xc - r * math.cos(angle)
                yi = yc - r * math.sin(angle)
            #for the case yc is in between
            elif points[6][1] <= yc < mid_middle[1]:
                angle = (angle_6 + angle_mid_middle) + angle_6
                xi = xc - r * math.cos(angle)
                yi = yc - r * math.sin(angle)
            else:
                #for the case points 6 and mid_middle both below yc
                if (angle_mid_middle - angle_6) <= angle_6:
                    angle = angle_6 - (angle_mid_middle - angle_6)
                    xi = xc - r * math.cos(angle)
                    yi = yc + r * math.sin(angle)
                #for the case index_mid will be above yc
                else:
                    angle = (angle_mid_middle - angle_6) - angle_6
                    xi = xc - r * math.cos(angle)
                    yi = yc - r * math.sin(angle)

            # correct the index finger length
            mid_index = (xi, yi)
            mid_points[3] = mid_index
            finger_length[3] = dist(points[7][0], xi, points[7][1], yi)
            for i in range(5):
                xm, ym = mid_points[i]
                xm, ym = int(xm), int(ym)
                cv2.circle(im, (xm, ym), 6, [175, 255, 255], -1)

            count = 0
            for name in fingers:
                fingers[name] = finger_length[count]
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(im, str(int(fingers[name])), (points[odd[count]][0] - 10, points[odd[count]][1] - 10), font,
                            0.5,(255, 255, 175), 2, cv2.LINE_AA)
                count += 1
            return finger_line
コード例 #15
0
    def find_intensity_max_arround_circles2(self):
        kernel = np.ones((3, 3), np.uint8)
        #self.picture = cv2.erode(self.picture, kernel, iterations=1)
        #self.picture = cv2.dilate(self.picture, kernel, iterations=1)
        xcentre = np.shape(self.picture)[0]/2
        ycentre = np.shape(self.picture)[1]/2
        nphi = 9
        phi_ls = np.linspace(0, 2*math.pi*(1-1/nphi), nphi)
        # do it once to get length of line:
        _, _, tmp = interp_along_radius(self.picture, 0)

        fig, (axs1, axs2, axs3) = plt.subplots(1, 3, figsize=(10, 5))
        axs2.imshow(self.picture)
        # plot center of image:
        axs2.scatter(self.picture.shape[0]/2, self.picture.shape[1]/2, c='r', marker='+', s=1000)

        intensity_lines = np.zeros(shape=(len(tmp), len(phi_ls)))
        pts_of_max_int = np.zeros(shape=(nphi, 2))
        for (i, p) in enumerate(phi_ls):
            x, y, tmp = interp_along_radius(self.picture, p)
            #  put line into array:
            intensity_lines[:, i] = tmp
            pts_of_max_int[i, 0] = np.mean(x[np.where(tmp == np.amax(tmp))[0]])
            pts_of_max_int[i, 1] = np.mean(y[np.where(tmp == np.amax(tmp))[0]])
            axs2.plot(y, x, 'k--')

        xmax = pts_of_max_int[:, 0]
        ymax = pts_of_max_int[:, 1]
        axs2.scatter(ymax, xmax, c='r')
        # fit circle through pts:
        xc, yc, r, _ = cf.least_squares_circle(np.array([ymax, xmax]).transpose())
        # circle from hough:
        c = plt.Circle((xcentre, ycentre), self.radius, fill=False, color='red', linestyle='--', linewidth=3)
        axs2.add_artist(c)
        # circle newly found:
        c = plt.Circle((xc, yc), r, fill=False, color='black', linewidth=3)
        axs2.add_artist(c)
        axs2.scatter(xc, yc, c='g', marker='+', s=20000)

        ny, nx = np.shape(intensity_lines)
        XX, YY = np.meshgrid(np.arange(nx), np.arange(ny))
        axs1.contourf(XX, YY, intensity_lines)
        axs1.scatter(np.arange(nx), np.sqrt(np.square(xmax-xcentre)+np.square(ymax-ycentre)), c='r')
        axs1.set_xlim([0, nx-1])
        every = 2
        axs1.set_xticks(np.arange(nphi)[::every])
        axs1.set_xticklabels(["%4.1f" % (p*180/math.pi) for p in phi_ls[::every]], rotation=0)
        axs1.set_xlabel('angle [°]')
        axs1.set_ylim([0, np.shape(XX)[0]-1])
        axs1.set_ylabel('Radius [px]')
        axs2.set_xlabel('x [px]')
        axs2.set_ylabel('y [px]')
        print(nx)
        lx = np.shape(self.picture)[0]
        ly = np.shape(self.picture)[1]
        dx = min(abs(lx-xc), lx)-1
        dy = min(abs(ly-yc), ly)-1
        print(int(xc-dx), int(xc+dx))
        print(int(yc-dy), int(yc+dy))
        #self.picture = self.picture[xc-dx:xc+dx, yc-dy:yc+dy]
        axs3.imshow(self.picture[int(xc-dx):int(xc+dx), int(yc-dy):int(yc+dy)])
        plt.show()
コード例 #16
0
    def find_intensity_max_arround_circles(self):
        #since evaluating in polar coordinates is terrible, lets just rotate the picture by the angle we want, and crop the interesting part of the picture from there
        masksizewidth = 5
        length = self.radius
        searchsize = 0.1*self.radius
        phi = 0
        lines_to_evaluate = []
        cv2.line(self.picture, (0, self.y_midpoint), (self.picture.shape[0], self.y_midpoint), color=0, thickness=2)
        for phi in range(0, 180, 30):
            #first create the rotation matrix for the angle to evaluate:
            phi = phi*2*math.pi/360
            rot = cv2.getRotationMatrix2D((self.picture.shape[0]/2, self.picture.shape[1]/2), phi, 1.0)
            #trans = np.concatenate([rot, np.array([[1],[1]]).dot(np.array([0]))], axis=1)
            print(rot)
            rotatetPicture = cv2.warpAffine(self.picture, rot, self.picture.shape)
            """
            x_min = self.x_midpoint+length-searchsize
            x_max = self.x_midpoint+length+searchsize
            y_min = self.y_midpoint-masksizewidth
            y_max = self.y_midpoint-masksizewidth
            """
            intensity_line = rotatetPicture[int(rotatetPicture.shape[0]/2-3):int(rotatetPicture.shape[0]/2+3),0:self.picture.shape[-1]]
            intensity_line = np.mean(intensity_line, axis=0)
            lines_to_evaluate.append([phi, intensity_line])
        #fining maximums in these lines:
        x_max = []
        y_max = []
        for line in lines_to_evaluate:
            #line[1] equals the points to evaluate, line[0] equals phi
            line_ev = line[1][0:int(len(line[1])/2)]
            x_max.append(-(-np.argmax(line_ev) + len(line_ev))*math.cos(line[0])+self.picture.shape[0]/2)
            y_max.append(-(-np.argmax(line_ev) + len(line_ev))*math.sin(line[0])+self.picture.shape[1]/2)

            line_ev=line[1][int(len(line[1])/2):-1]
            x_max.append(np.argmax(line_ev)*math.cos(line[0])+self.picture.shape[0]/2)
            y_max.append(np.argmax(line_ev)*math.sin(line[0])+self.picture.shape[1]/2)

        x=[]
        y=[]
        z=[]
        for line in lines_to_evaluate:
            x.append([(i-len(line[1])/2)*math.cos(line[0])+self.picture.shape[0]/2 for i in range(len(line[1]))])
            y.append([(i-len(line[1])/2)*math.sin(line[0])+self.picture.shape[1]/2 for i in range(len(line[1]))])
            z.append(line [1])

        x=np.asarray(x).flatten()
        y=np.asarray(y).flatten()
        z=np.asarray(z).flatten()

        fig, (axs1, axs2) = plt.subplots(1,2, sharex=True, sharey=True)
        axs1.scatter(x,y,c=z)
        #axs1.scatter(range(len(lines_to_evaluate[0][1])),12*np.ones(22,1), lines_to_evaluate[0][1])
        axs2.imshow(self.picture)
        axs2.scatter(x_max, y_max, c='b')
        # fit circle through pts:

        xc, yc, r, _ = cf.least_squares_circle(np.array([x_max, y_max]).transpose())
        c = plt.Circle((xc, yc), r, fill=False, color='red')
        axs2.add_artist(c)
        axs2.scatter(self.picture.shape[0]/2, self.picture.shape[1]/2, c='g', marker='o', s=200)
        axs2.scatter(xc, yc, c='r', marker='+', s=200)
        print(xc,yc)
        plt.show()
コード例 #17
0
        data = [(float(x), float(y), float(z), float(expTime), str(filt_slot),
                 float(flux), float(counts), float(fwhm), float(bkgnd),
                 float(chiSq)) for x, y, z, expTime, filt_slot, flux, counts,
                fwhm, bkgnd, chiSq in csv.reader(csvfile, delimiter=',')]

    return data


if __name__ == "__main__":
    fileName = sys.argv[1]

    if fileName[0] == '~':
        fileName = os.path.expanduser('~') + fileName[1:]

    data = get_data(fileName)

    xyData = []

    #scrub everything but x & y from data
    for target in data:
        xyData.append(target[:2])

    xc, yc, r, mse = cf.least_squares_circle(xyData)

    xc = xc + CENTER_OFFSET[0]
    yc = yc + CENTER_OFFSET[1]

    print("XCenter = " + repr(xc))
    print("YCenter = " + repr(yc))
    print("Radius  = " + repr(r))
    print("MSE = " + repr(mse))
コード例 #18
0
                                       cv2.CHAIN_APPROX_SIMPLE)

backtorgb = cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)

for i in range(np.array(contours).shape[0]):
    if (np.array(contours[i]).shape[0] > 1000):
        cv2.drawContours(backtorgb, contours[i], -1, (0, 0, 255), 3)
        print(i)

plt.figure(figsize=(20, 20))
plt.imshow(backtorgb)
#cv2.imshow("img", gray)
#cv2.waitKey(0)

for i in range(np.array(contours).shape[0]):
    if (np.array(contours[i]).shape[0] > 1000):
        print(np.array(contours[i]).shape)

import circle_fit as cf

cor = []

#for i in range(20):
#    cor.append(contours[35][i])

cor = np.array(contours[1])
cor = cor.reshape(cor.shape[0], cor.shape[2])
print(cor.shape)

xc, yc, r, _ = cf.least_squares_circle(cor)
print(xc, yc, r)
コード例 #19
0
gdf.plot(column="cluster", categorical=True, markersize=1)

# Subsetting the dataset
sel = gdf

# Keep only clusters with more than x building
min_buildings = 3
count = gdf.groupby("cluster").count().iloc[:, 0]
sel = sel.loc[gdf["cluster"].isin(count[count > min_buildings].index), :]

# Keep only close buildings fitting in a circle
sel["radius"] = 0
sel2 = sel.copy()
for i, c in enumerate(sel.cluster.unique()):
    x, y, radius, e = circle_fit.least_squares_circle(
        sel.loc[sel.cluster == c,
                ["E.Gebäudekoordinate", "N.Gebäudekoordinate"]].values)
    sel2.loc[sel2.cluster == c, "radius"] = radius

max_radius = 500
sel = sel2.loc[sel2.radius < max_radius, :]

print(
    sel[["PV_ERTRAG", "DACHART", "Bauperiode", "cluster", "radius",
         "sqdist"]].sort_values(by="cluster"))

fig, ax = plt.subplots()
gdf.plot(ax=ax, color="grey", markersize=0.5)
sel.plot(column="cluster", ax=ax, markersize=3, categorical=True)
ax.set_xticks([])
ax.set_yticks([])
コード例 #20
0
ファイル: Main.py プロジェクト: StephenBurke/seminar
    print("The as-designed center point is: (" + str(givenC_tuple[0]) + "," +
          str(givenC_tuple[1]) + ")")
    print("The distance between them is: " +
          str(round(math.dist(givenC_tuple, FCP), 7)))
    print("The fitted radius is: " + str(radius) +
          " and the actual radius is: " + str(givenR))
    print("The difference between them is: " +
          str(round(abs(givenR - radius), 7)))


pipe_point = []
sec_count = 0
for n in range(50):
    a = PassesSecondNoiseTestBySection[2 * n:2 * n + 2]
    if len(a[0]) > 0:
        xc, yc, r, CI = least_squares_circle(a[0], 8)
        plot_data_circle((list(zip(*a[0]))[0]), (list(zip(*a[0]))[1]), xc, yc,
                         r)
        plt.title("Section " + str(sec_count) + " Pipe " + str(sec_count * 2))
        plt.show()
        printInfo(r, xc, yc, sec_count, 0)
        pipe_point.append({xc, yc})
    else:
        pass
    if len(a[1]) > 0:
        xc, yc, r, CI = least_squares_circle(a[1], 4.375)
        plot_data_circle((list(zip(*a[1]))[0]), (list(zip(*a[1]))[1]), xc, yc,
                         r)
        plt.title("Section " + str(sec_count) + " Pipe " +
                  str(sec_count * 2 + 1))
        plt.show()