예제 #1
0
def component_detection(msk, prev, area_min=None, visualize=False):
    # Extract connected components
    comp = cv2.connectedComponentsWithStatsWithAlgorithm(
        msk, 8, cv2.CV_16U, cv2.CCL_DEFAULT)

    if comp[0] > 1:  # if there are some component + BG
        # Search for the biggest component (except BG)
        if area_min is not None:  # Filterby minimal area
            c = comp[2][1:, -1]
            c[c < area_min] = 0
            if c.max() == 0:
                return (0, 0, -1, 0)
            else:
                bigger_comp = np.argmax(c, axis=-1)  # Avoid BG
        else:
            bigger_comp = np.argmax(comp[2][1:, -1], axis=-1)  # Avoid BG

        msk[comp[1] != (bigger_comp + 1)] = 0
        (x, y) = comp[-1][bigger_comp + 1]
        area = comp[2][1:, -1][bigger_comp]

        (x_grade_cam, y_grade_cam) = angles_camera(x, y)
        x_grade_fw = angle_frontwheels(x_grade_cam, prev)

        if visualize:  # only for debug
            msk = cv2.rectangle(msk, (int(x) - 5, int(y) - 5),
                                (int(x) + 5, int(y) + 5), (255, 255, 255), -1)
            cv2.imwrite(
                './images/X_{}_{}-Y_{}_{}-Area_{}.png'.format(
                    x_grade_cam, x, y_grade_cam, y, area), msk)

        return (x_grade_cam, y_grade_cam, area, x_grade_fw)
    else:
        return (0, 0, -1, 0)
예제 #2
0
def detecterbord(img, minp=850):
    #une image niveau de gris que je mets en tresh
    _, imseuil = cv2.threshold(img, 0, 255,
                               cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    #une ouverture de l'image seuillee pour reduire les possibilites
    noyeau = np.ones((3, 3), np.uint8)
    resultat = cv2.morphologyEx(imseuil, cv2.MORPH_OPEN, noyeau)

    #On cherche les composants connexes
    retval, labels, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm(
        resultat, 4, cv2.CV_32S, cv2.CCL_WU)
    #minp peu varier(de 50) en fonction du nombre de contour trouvé(une amelioration)
    pliste = []
    for i in range(1, retval):
        #On sait que les carrés du bord sont remplis en pixels(etudier le retour de stats)
        if (stats[i, 4] > minp):
            if (stats[i, 2] in range(20, 50) and stats[i, 3] in range(20, 50)):
                tr = (stats[i, 0] + stats[i, 2], stats[i, 1])
                pliste.append(tr)
    nb = 0
    #pour eviter la boucle en montant et en descandant,on fixe à 7(arbitraire)
    # le max d'iterration
    while nb < 7:
        if (len(pliste) == 5):
            break
        #ici on veut garantir que avant de sortir on
        # s'en sort avec des points eleves(c'est mieux que bas)
        if (nb == 6):
            nb += 1
            minp -= 100
        elif (len(pliste) < 5):
            #on diminue minp
            minp -= 100
            nb += 1
        elif (len(pliste) > 5):
            #on augmente minp
            minp += 100
            nb += 1
        #On refait le traitement (c'est nécessaire pour avoir les 5 carrés pour la rotation)
        pliste = []
        for i in range(1, retval):
            if (stats[i, 2] in range(20, 50) and stats[i, 3] in range(20, 50)):
                if (stats[i, 4] > minp):
                    tr = (stats[i, 0] + stats[i, 2], stats[i, 1])
                    pliste.append(tr)

    return pliste
def calculate_cropped_component_average(img):
    ccs = cv2.connectedComponentsWithStatsWithAlgorithm(
        img, 4, cv2.CV_32S, cv2.CCL_GRANA)
    cc_number = ccs[0] - 1
    cc_stats = ccs[2]

    a_sum, w_sum, h_sum = 0, 0, 0
    for i in range(len(cc_stats)):
        if i == 0:
            continue
        a_sum = a_sum + cc_stats[i][cv2.CC_STAT_AREA]
        w_sum = w_sum + cc_stats[i][cv2.CC_STAT_WIDTH]
        h_sum = h_sum + cc_stats[i][cv2.CC_STAT_HEIGHT]
    a_avg = a_sum / cc_number
    h_avg = h_sum / cc_number
    w_avg = w_sum / cc_number
    return a_avg, h_avg, w_avg
예제 #4
0
def connected_components_segmentation(intermediate_global_mask):
    """
    :param intermediate_global_mask: black and white image
    :return: components
    """
    _, labeled_img = cv2.connectedComponentsWithAlgorithm(
        intermediate_global_mask, 8, cv2.CV_32S, cv2.CCL_GRANA)
    labels = np.unique(labeled_img)
    labels = labels[labels != 0]

    components = []

    for label in labels:
        mask = np.zeros_like(labeled_img, dtype=np.uint8)
        mask[labeled_img == label] = 255

        # Compute the convex hull
        if get_opencv_major_version(cv2.__version__) in ['2', '3']:
            mask, contours, _ = cv2.findContours(mask, cv2.RETR_TREE,
                                                 cv2.CHAIN_APPROX_SIMPLE)
        else:
            contours, _ = cv2.findContours(mask, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)

        hull = []
        for cnt in contours:
            hull.append(cv2.convexHull(cnt, False))
        hull_mask = np.zeros((mask.shape[0], mask.shape[1]), dtype=np.uint8)
        for i in range(len(contours)):
            hull_mask = cv2.drawContours(hull_mask, hull, i, 255, -1, 8)

        single_component, flag = draw_border_for_picture_parts(hull_mask)

        _, connected_component, stats, _ = cv2.connectedComponentsWithStatsWithAlgorithm(
            single_component, 8, cv2.CV_32S, cv2.CCL_GRANA)
        valid_labels = np.argwhere(
            stats[:, cv2.CC_STAT_AREA] >= LABEL_AREA_THRESHOLD)
        if valid_labels[0] == 0:
            valid_labels = valid_labels[1:]
        for valid_label in valid_labels:
            component = Component(valid_label, connected_component,
                                  stats[valid_label], flag)
            components.append(component)

    components.sort(key=lambda x: x.area, reverse=True)
    return components
예제 #5
0
def image_segmentation_with_stats(img):
    """
    """
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    gray = cv2.GaussianBlur(gray, ksize=(5, 5), sigmaX=10)
    gray = cv2.bilateralFilter(gray, d=7, sigmaColor=75, sigmaSpace=75)
    gray = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, (7, 7), iterations=2)

    gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                 cv2.THRESH_BINARY, 13,
                                 3)  # 11,2 at the beginning

    cv2.imshow("Thresh", gray)
    # gray = erosion_dilation(gray)

    num_labels, labeled_img, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm(
        gray, connectivity=8, ltype=cv2.CV_32S, ccltype=cv2.CCL_GRANA)

    return labeled_img, stats
예제 #6
0
def post0(path):
    imwr = cv2.imread('./nivel0/' + path, 0)
    imwr = 255 - imwr
    output = cv2.connectedComponentsWithStatsWithAlgorithm(
        imwr, 4, ltype=cv2.CV_16U, ccltype=cv2.CCL_DEFAULT)
    num_labels = output[0]
    labels = output[1]
    stats = output[2]
    centroids = output[3]

    length = len(imwr)
    height = len(imwr[0])
    area = length * height
    dispose = list()
    #Se recorren borde superior e inferior
    for num in range(length):
        if labels[num, 0] != 0:
            if stats[labels[num, 0], cv2.CC_STAT_AREA] < area * 0.1:
                dispose.append(labels[num, 0])
        elif labels[num, height - 1] != 0:
            if stats[labels[num, height - 1], cv2.CC_STAT_AREA] < area * 0.1:
                dispose.append(labels[num, height - 1])

    for num in range(height):
        if labels[0, num] != 0:
            if stats[labels[0, num], cv2.CC_STAT_AREA] < area * 0.1:
                dispose.append(labels[0, num])
        elif labels[length - 1, num] != 0:
            if stats[labels[length - 1, num], cv2.CC_STAT_AREA] < area * 0.1:
                dispose.append(labels[length - 1, num])

    dispose = set(dispose)
    tmp = imwr
    print(dispose)
    for v in range(length):
        for b in range(height):
            if labels[v, b] in dispose:
                tmp[v, b] = 0
    tmp = 255 - tmp
    cv2.imshow("image", tmp)
    cv2.waitKey(0)
예제 #7
0
def get_bounding_boxes(original_frame, edge_detection_image):
    """
        Given an image it looks for the paintings and returns a list of bounding boxes.
        Each Bounding Boxes contains four points: upper_left, upper_right, down_left, down_right

    :param original_frame: ndarray (H, W, C)
    :param edge_detection_image: ndarray (H, W)
    :return: list of bounding boxes
    """
    list_bounding_boxes = []
    padding_image = cv2.copyMakeBorder(edge_detection_image, 1, 1, 1, 1, cv2.BORDER_CONSTANT, None, 0)
    ret_val, labels, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm(padding_image,
                                                                                      connectivity=8,
                                                                                      ltype=cv2.CV_16U,
                                                                                      ccltype=cv2.CCL_GRANA)
    # Remove more small
    num_paintings = 1
    for num_label in range(1, stats.shape[0]):
        if stats[num_label, cv2.CC_STAT_AREA] < np.mean(stats[1:, cv2.CC_STAT_AREA]):
            labels[labels == num_label] = 0
        else:
            labels[labels == num_label] = num_paintings
            num_paintings += 1
    for num_label in range(1, num_paintings):  # Label equals zero is the background
        label_image = (labels == num_label) * 255
        label_image = label_image.astype('uint8')
        contours, hierarchy = cv2.findContours(label_image, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
        cv2.drawContours(label_image, contours, -1, color=(0, 0, 0), thickness=10)
        sorted_approx = find_paintings(contours[0])
        if sorted_approx is not None and not (0, 0) in sorted_approx:
            # upper_left, upper_right, lower_left, lower_right = sorted_approx
            # upper_width = abs(upper_right[1] - upper_left[1])
            # lower_width = abs(lower_right[1] - lower_left[1])
            # right_height = abs(lower_left[0] - upper_left[0])
            # left_height = abs(lower_right[0] - upper_right[0])
            # print(upper_width, lower_width, right_height, left_height)
            list_bounding_boxes.append(sorted_approx)
    return list_bounding_boxes
def get_same_patches(img, thresh):
    patch_size = 70
    epsilon = 0.0001
    ccs = cv2.connectedComponentsWithStatsWithAlgorithm(
        thresh, 4, cv2.CV_32S, cv2.CCL_GRANA)
    cc_number = ccs[0]
    cc_labels = ccs[1]
    cc_stats = ccs[2]

    i_x, i_y = 0, 0
    x_margin, y_margin = 5, 5

    while True:
        p1_pos = [
            np.random.randint(
                2 * x_margin + (i_x + 1) * patch_size,
                img.shape[1] - (i_x + 2) * patch_size - 2 * x_margin),
            np.random.randint(
                (i_y + 1) * patch_size + 2 * y_margin,
                img.shape[0] - (i_y + 2) * patch_size - 2 * y_margin)
        ]
        p2_pos = [
            np.random.randint(
                2 * x_margin + (i_x + 1) * patch_size,
                img.shape[1] - (i_x + 2) * patch_size - 2 * x_margin),
            np.random.randint(
                (i_y + 1) * patch_size + 2 * y_margin,
                img.shape[0] - (i_y + 2) * patch_size - 2 * y_margin)
        ]

        p1 = img[p1_pos[1]:p1_pos[1] + patch_size,
                 p1_pos[0]:p1_pos[0] + patch_size]
        p1_thresh = thresh[p1_pos[1]:p1_pos[1] + patch_size,
                           p1_pos[0]:p1_pos[0] + patch_size]

        p2 = img[p2_pos[1]:p2_pos[1] + patch_size,
                 p2_pos[0]:p2_pos[0] + patch_size]
        p2_thresh = thresh[p2_pos[1]:p2_pos[1] + patch_size,
                           p2_pos[0]:p2_pos[0] + patch_size]

        if cv2.countNonZero(p1_thresh) < 10 or cv2.countNonZero(
                p2_thresh) < 10:
            continue

        a1, h1, w1 = calculate_cropped_component_average(p1_thresh)
        a2, h2, w2 = calculate_cropped_component_average(p2_thresh)

        a1, a2, w1, w2, h1, h2 = a1 + epsilon, a2 + epsilon, w1 + epsilon, w2 + epsilon, h1 + epsilon, h2 + epsilon

        if min(a1, a2) / max(a1, a2) > 0.7:  # todo: improve on this condition
            label = 0
            break
        else:
            continue

    if SHOW_RESULTS:
        global counter
        disp_img = cv2.cvtColor(thresh.copy(), cv2.COLOR_GRAY2BGR)
        for cc_i in range(1, cc_number):
            x, y, w, h = cc_stats[cc_i][cv2.CC_STAT_LEFT], cc_stats[cc_i][
                cv2.CC_STAT_TOP], cc_stats[cc_i][
                    cv2.CC_STAT_WIDTH], cc_stats[cc_i][cv2.CC_STAT_HEIGHT]
            cv2.rectangle(disp_img, (int(x), int(y)), (int(x + w), int(y + h)),
                          (60, 200, 200),
                          1,
                          lineType=cv2.LINE_AA)

        cv2.rectangle(
            disp_img, (int(p1_pos[0]), int(p1_pos[1])),
            (int(p1_pos[0] + patch_size), int(p1_pos[1] + patch_size)),
            (255, 0, 0),
            5,
            lineType=cv2.LINE_AA)
        cv2.rectangle(
            disp_img, (int(p2_pos[0]), int(p2_pos[1])),
            (int(p2_pos[0] + patch_size), int(p2_pos[1] + patch_size)),
            (0, 0, 255),
            5,
            lineType=cv2.LINE_AA)

        cv2.imwrite(
            'sample_pairs/' + str(counter) + 'page' + str(label) + '.png',
            disp_img)
        cv2.imwrite(
            'sample_pairs/' + str(counter) + 'firstpair' + str(label) + '.png',
            p1)
        cv2.imwrite(
            'sample_pairs/' + str(counter) + 'secondpair' + str(label) +
            '.png', p2)
        counter = counter + 1

    return p1, p2, label
예제 #9
0
            sys.exit('Image file do not exist')
        model_path = sys.argv[2]
        try:
            mean, std = int(sys.argv[3]), int(sys.argv[4])
        except:
            sys.exit('Mean and std must be Integers')

    if image is None:
        sys.exit('Image file do not exist')

    image = cv2.copyMakeBorder(image, 14, 14, 14, 14, cv2.BORDER_CONSTANT,
                               None, 0)

    # Find connected components
    etval, labels, stats, centroid = \
        cv2.connectedComponentsWithStatsWithAlgorithm(image, 4, cv2.CV_16U, cv2.CCL_WU)

    # If find less then 4 digits - print that
    nComponents = labels.max()
    #if nComponents < 4:
    #print("Numbers in " + sys.argv[1] + " are too close, program will not find all digits")

    model_param = []  # for plotting result of testing models

    # Download model
    model = LeNetBN()
    try:
        model.load_state_dict(
            torch.load(model_path, map_location=torch.device('cpu')))
    except:
        sys.exit('Model file do not exist')