Exemple #1
0
def fill_binary(image):
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300, :] = 255
    mask = np.ones([402, 402, 1], np.uint8)
    mask[101:301, 101:301] = 0
    cv.floodFill(image, mask, (200, 200), (0, 0, 255), cv.FLOODFILL_MASK_ONLY)
    cv.imshow("fill_binary", image)
Exemple #2
0
def fill_color_demo(image):
    copyImg = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros([h + 2, w + 2], np.uint8)
    cv.floodFill(copyImg, mask, (30, 30), (0, 255, 255), (100, 100, 100),
                 (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)
    cv.imshow("fill_color_demo", copyImg)
Exemple #3
0
    def find_all_template(cls, source, target, threshold=0.8, mac_count=None):
        mask = None
        if len(target.shape) == 3 and target.shape[2] == 4:
            mask = target[:, :, 3]
            target = cv2.cvtColor(target, cv2.COLOR_BGRA2BGR)
            
        res = cv2.matchTemplate(source, target, cv2.TM_CCOEFF_NORMED, mask=mask)

        result = []
        height, width = target.shape[:2]
        while True:
            _, max_val, _, tl = cv2.minMaxLoc(res)

            if max_val < threshold:
                break

            br = (tl[0] + width, tl[1] + height)
            mp = (int(tl[0] + width / 2), int(tl[1] + height / 2))
            result.append({
                'pt': mp,
                'rect': (tl, br),
                'conf': max_val
            })

            if mac_count is not None:
                if mac_count <= 0:
                    break
                else:
                    mac_count -= 1

            cv2.floodFill(res, None, tl, (-1000,), max_val-threshold+0.1, 1, flags=cv2.FLOODFILL_FIXED_RANGE)
        return result
Exemple #4
0
def get_rm(img, vp, roi, config):
    rm_type = config['rm'].getint('type')
    if rm_type == 0:
        rm_mask = rm_static_noshade(img, roi, config)
    elif rm_type == 1:
        rm_mask = rm_static_sunshade(img, roi, config)
    elif rm_type == 2:
        rm_mask = rm_otsu_noshade(img, roi, config)
    elif rm_type == 3:
        rm_mask = rm_otsu_sunshade(img, roi, config)
    else:
        logging.error('Invalid road marking type.')
        rm_mask = None

    # remove glare near vp
    if config['rm'].getboolean('has_glare'):
        # cv2.imshow('before deglare', rm_mask)
        # cv2.waitKey(0)
        radius = config['rm'].getint('glare_radius')
        rm_mask = cv2.circle(rm_mask, vp, radius, 255, cv2.FILLED)
        # cv2.imshow('before deglare', rm_mask)
        # cv2.waitKey(0)
        cv2.floodFill(rm_mask, None, vp, 0)
        # cv2.imshow('before deglare', rm_mask)
        # cv2.waitKey(0)

    return rm_mask
Exemple #5
0
def fill_color_demo(image):
    copyIma = image.copy()
    w, h = image.shape[:2]
    print(w, h)
    mask = np.zeros([w + 2, h + 2], np.uint8)
    cv.floodFill(copyIma, mask, (30, 30), (0, 255, 255), (50, 50, 50),
                 (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)
    # cv.floodFill(copyIma, mask, (30, 30), (0, 255, 255), (20, 20, 10), (20, 20, 20))
    cv.imshow("fill_color", copyIma)
Exemple #6
0
def fill_binary():
    image = np.zeros([400, 400, 3], np.uint8)
    image[50:350, 50:350, :] = [0, 255, 0]
    image[100:300, 100:300, :] = 255
    cv.imshow("fill_binary", image)
    mask = np.ones([402, 402, 1], np.uint8)
    mask[60:340, 60:340] = 0  # this range will be flood filled
    cv.floodFill(image, mask, (60, 60), (0, 0, 255), cv.FLOODFILL_MASK_ONLY)
    cv.imshow("filled binary", image)
Exemple #7
0
def fill_binary():  #mask的指定的位置为零时才填充,不为零不填充
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300, :] = 255
    cv.imshow("fill banary", image)

    mask = np.ones([402, 402, 1], np.uint8)
    mask[101:301, 101:301] = 0
    cv.floodFill(image, mask, (200, 200), (100, 2, 255),
                 cv.FLOODFILL_MASK_ONLY)
    cv.imshow("filled banary", image)
def get_corners(painting_roi, draw=False):
    gray = cv2.cvtColor(painting_roi, cv2.COLOR_BGR2GRAY)
    blur = cv2.bilateralFilter(gray, 9, 75, 75)
    erosion = cv2.erode(blur, np.ones((9, 9), np.uint8), iterations=2)
    dilation = cv2.dilate(erosion, np.ones((9, 9), np.uint8), iterations=2)
    _, thresh = cv2.threshold(blur, 0, 255,
                              cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    # edges = auto_canny(thresh)

    h, w = thresh.shape[:2]
    mask = np.zeros((h + 2, w + 2), np.uint8)
    flood = thresh.copy()
    cv2.floodFill(flood, mask, (0, 0), 255)
    im_floodfill_inv = cv2.bitwise_not(flood)
    im_out = thresh | im_floodfill_inv

    contours, _ = cv2.findContours(im_out, cv2.RETR_EXTERNAL,
                                   cv2.CHAIN_APPROX_SIMPLE)

    # find the biggest countour (c) by the area
    c = max(contours, key=cv2.contourArea)

    x, y, w, h = cv2.boundingRect(c)
    bbox = x, y, w, h

    corners = cv2.goodFeaturesToTrack(im_out[y - 10:y + h + 10, x:x + w + 10],
                                      4,
                                      0.01,
                                      painting_roi.shape[0] / 3,
                                      useHarrisDetector=True)
    corners = np.int0(corners)
    corners = np.squeeze(corners)
    corners_img = painting_roi.copy()

    # draw the biggest contour (c) in green
    cv2.rectangle(corners_img, (x, y), (x + w + 10, y + h + 10), (0, 255, 0),
                  2)

    if draw:
        for i, corner in enumerate(corners):
            x_corner, y_corner = corner.ravel()
            cv2.circle(corners_img, (x_corner, y_corner), 3, 255, -1)
            cv2.putText(corners_img,
                        f'{i}', (x_corner + 3, y_corner + 3),
                        cv2.FONT_HERSHEY_SIMPLEX,
                        0.75,
                        color=(255, 0, 0))
        cv2.imshow("corners", corners_img)

    # for corner in corners:
    #     corner[0] += x
    #     corner[1] += y

    return corners, bbox
Exemple #9
0
def Fill_Holes(image):
    im_fill = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros((h + 2, w + 2), np.uint8)

    cv2.floodFill(im_fill, mask, (0, 0), 255)

    im_fill_inv = cv2.bitwise_not(im_fill)

    filled_image = cv2.bitwise_or(im_fill_inv, image)

    return filled_image
Exemple #10
0
def cut_background(img_src):
    """
    @return x, y, w, h
    """
    img = img_src.copy()
    h, w = img.shape[:2]
    # 背景填充 进行泛洪填充
    mask = np.zeros((h + 2, w + 2),
                    np.uint8)  #掩码长和宽都比输入图像多两个像素点,满水填充不会超出掩码的非零边缘
    cv2.floodFill(img, mask, (5, 5), (255, 255, 255), (3, 3, 3), (5, 5, 5), 8)

    # 去噪
    img = cv2.fastNlMeansDenoisingColored(img, None, 20, 20, 7, 21)

    # 背景识别
    mask = np.zeros((img.shape[:2]), np.uint8)
    bgdModel = np.zeros((1, 65), np.float64)
    fgdModel = np.zeros((1, 65), np.float64)
    rect = (5, 5, w - 5, h - 5)
    # 多次计算,保证计算准确度
    cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 1, cv2.GC_INIT_WITH_RECT)
    #关于where函数第一个参数是条件,满足条件的话赋值为0,否则是1。如果只有第一个参数的话返回满足条件元素的坐标。
    mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')

    # 绘制轮廓
    draw_img = img * mask2[:, :, np.newaxis]
    # 前景图使用白色填充,方便识别
    draw_img[np.where((draw_img > [0, 0, 0]).all(axis=2))] = [255, 255, 255]

    # h, w = draw_img.shape[:2]
    draw_img = cv2.cvtColor(draw_img, cv2.COLOR_BGR2GRAY)  #得到灰度图
    _, binary = cv2.threshold(draw_img, 200, 255,
                              cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    contours, _ = cv2.findContours(binary, cv2.RETR_TREE,
                                   cv2.CHAIN_APPROX_SIMPLE)
    if len(contours) < 1:
        return img
    else:
        max_countor = sorted(contours, key=cv2.contourArea, reverse=True)[0]
        return cv2.boundingRect(max_countor)
Exemple #11
0
def component_detection(binary,
                        min_obj_area=C.THRESHOLD_OBJ_MIN_AREA,
                        line_thickness=C.THRESHOLD_LINE_THICKNESS,
                        min_rec_evenness=C.THRESHOLD_REC_MIN_EVENNESS,
                        max_dent_ratio=C.THRESHOLD_REC_MAX_DENT_RATIO,
                        step_h=5,
                        step_v=2,
                        rec_detect=False,
                        show=False,
                        test=False):
    """
    :param binary: Binary image from pre-processing
    :param min_obj_area: If not pass then ignore the small object
    :param min_obj_perimeter: If not pass then ignore the small object
    :param line_thickness: If not pass then ignore the slim object
    :param min_rec_evenness: If not pass then this object cannot be rectangular
    :param max_dent_ratio: If not pass then this object cannot be rectangular
    :return: boundary: [top, bottom, left, right]
                        -> up, bottom: list of (column_index, min/max row border)
                        -> left, right: list of (row_index, min/max column border) detect range of each row
    """
    mask = np.zeros((binary.shape[0] + 2, binary.shape[1] + 2), dtype=np.uint8)
    compos_all = []
    compos_rec = []
    compos_nonrec = []
    row, column = binary.shape[0], binary.shape[1]
    for i in range(0, row, step_h):
        for j in range(i % 2, column, step_v):
            if binary[i, j] == 255 and mask[i, j] == 0:
                # get connected area
                # region = util.boundary_bfs_connected_area(binary, i, j, mask)

                mask_copy = mask.copy()
                cv2.floodFill(binary, mask, (j, i), None, 0, 0,
                              cv2.FLOODFILL_MASK_ONLY)
                mask_copy = mask - mask_copy
                region = np.nonzero(mask_copy[1:-1, 1:-1])
                region = list(zip(region[0], region[1]))

                # filter out some compos
                # ignore small area
                if len(region) < min_obj_area:
                    continue
                component = Component(region, binary.shape)
                # calculate the boundary of the connected area
                # ignore small area
                if component.width <= 3 or component.height <= 3:
                    continue
                # check if it is line by checking the length of edges
                if component.compo_is_line(line_thickness):
                    continue

                if test:
                    print('Area:%d' % (len(region)))
                    draw.draw_boundary([component], binary.shape, show=True)

                compos_all.append(component)

                if rec_detect:
                    # rectangle check
                    if component.compo_is_rectangle(min_rec_evenness,
                                                    max_dent_ratio):
                        component.rect_ = True
                        compos_rec.append(component)
                    else:
                        component.rect_ = False
                        compos_nonrec.append(component)

                if show:
                    print('Area:%d' % (len(region)))
                    draw.draw_boundary(compos_all, binary.shape, show=True)

    # draw.draw_boundary(compos_all, binary.shape, show=True)
    if rec_detect:
        return compos_rec, compos_nonrec
    else:
        return compos_all
Exemple #12
0
def floodFill(img):
    cv.floodFill(img)
Exemple #13
0
def block_division(grey,
                   org,
                   show=False,
                   write_path=None,
                   step_h=10,
                   step_v=10,
                   grad_thresh=C.THRESHOLD_BLOCK_GRADIENT,
                   line_thickness=C.THRESHOLD_LINE_THICKNESS,
                   min_rec_evenness=C.THRESHOLD_REC_MIN_EVENNESS,
                   max_dent_ratio=C.THRESHOLD_REC_MAX_DENT_RATIO,
                   min_block_height_ratio=C.THRESHOLD_BLOCK_MIN_HEIGHT):
    '''
    :param grey: grey-scale of original image
    :return: corners: list of [(top_left, bottom_right)]
                        -> top_left: (column_min, row_min)
                        -> bottom_right: (column_max, row_max)
    '''
    blocks = []
    mask = np.zeros((grey.shape[0] + 2, grey.shape[1] + 2), dtype=np.uint8)
    broad = np.zeros((grey.shape[0], grey.shape[1], 3), dtype=np.uint8)
    broad_all = broad.copy()

    row, column = grey.shape[0], grey.shape[1]
    for x in range(0, row, step_h):
        for y in range(0, column, step_v):
            if mask[x, y] == 0:
                # region = flood_fill_bfs(grey, x, y, mask)

                # flood fill algorithm to get background (layout block)
                mask_copy = mask.copy()
                cv2.floodFill(grey, mask, (y, x), None, grad_thresh,
                              grad_thresh, cv2.FLOODFILL_MASK_ONLY)
                mask_copy = mask - mask_copy
                region = np.nonzero(mask_copy[1:-1, 1:-1])
                region = list(zip(region[0], region[1]))

                # ignore small regions
                if len(region) < 500:
                    continue
                block = Block(region, grey.shape)

                draw.draw_region(region, broad_all)
                # if block.height < 40 and block.width < 40:
                #     continue
                if block.height < 30:
                    continue

                # print(block.area / (row * column))
                if block.area / (row * column) > 0.9:
                    continue
                elif block.area / (row * column) > 0.7:
                    block.redundant = True

                # get the boundary of this region
                # ignore lines
                if block.compo_is_line(line_thickness):
                    continue
                # ignore non-rectangle as blocks must be rectangular
                if not block.compo_is_rectangle(min_rec_evenness,
                                                max_dent_ratio):
                    continue
                # if block.height/row < min_block_height_ratio:
                #     continue
                blocks.append(block)
                draw.draw_region(region, broad)
    # if show:
    #     cv2.imshow('flood-fill all', broad_all)
    #     cv2.imshow('block', broad)
    #     cv2.waitKey()
    if write_path is not None:
        cv2.imwrite(write_path, broad)
    return blocks
Exemple #14
0
def fill_border_contour(contour, img_shape):
    mask = np.zeros(img_shape, dtype=np.uint8)
    cv2.drawContours(mask, [contour], 0, 255, cv2.FILLED)

    # Extract the perimeter pixels, leaving out the last pixel
    # of each side as it is included in the next side (going clockwise).
    # This makes all the side arrays the same length.
    # We also flip the bottom and left side, as we want to "unwrap" the
    # perimeter pixels in a clockwise fashion.
    top = mask[0, :-1]
    right = mask[:-1, -1]
    bottom = np.flipud(mask[-1, 1:])
    left = np.flipud(mask[1:, 0])

    # combine the perimeter sides into one continuous array
    perimeter_pixels = np.concatenate([top, right, bottom, left])

    region_boundary_locs = np.where(perimeter_pixels == 255)[0]

    # the perimeter here is not a geometric perimeter but the number of pixels around the image
    img_h = img_shape[0]
    img_w = img_shape[1]
    perimeter = (img_h - 1) * 2 + (img_w - 1) * 2

    # account for the wrap around from the last contour pixel to the end,
    # i.e. back at the start at (0, 0)
    wrap_distance = region_boundary_locs.max() - perimeter

    # insert the wrap distance in front of the region boundary locations
    region_boundary_locs = np.concatenate([[wrap_distance],
                                           region_boundary_locs])

    # calculate the gap size between boundary pixel locations
    gaps = np.diff(region_boundary_locs)

    # if there's only one gap, the contour is already filled
    if not np.sum(gaps > 1) > 1:
        return mask

    # add one to the results because of the diff offset
    max_gap_idx = np.where(gaps == gaps.max())[0] + 1

    # there should only be one, else we have a tie and should probably ignore that case
    if max_gap_idx.size != 1:
        return None

    start_perim_loc_of_flood_entry = region_boundary_locs[max_gap_idx[0]]

    # see if subsequent perimeter locations were also part of the contour,
    # adding one to the last one we found
    subsequent_region_border_locs = region_boundary_locs[
        region_boundary_locs > start_perim_loc_of_flood_entry]

    flood_fill_entry_point = start_perim_loc_of_flood_entry

    for loc in subsequent_region_border_locs:
        if loc == flood_fill_entry_point + 1:
            flood_fill_entry_point = loc

    # we should hit the first interior empty point of the contour
    # by moving forward one pixel around the perimeter
    flood_fill_entry_point += 1

    # now to convert our perimeter location back to an image coordinate
    if flood_fill_entry_point < img_w:
        flood_fill_entry_coords = (flood_fill_entry_point, 0)
    elif flood_fill_entry_point < img_w + img_h:
        flood_fill_entry_coords = (img_w - 1,
                                   flood_fill_entry_point - img_w + 1)
    elif flood_fill_entry_point < img_w * 2 + img_h:
        flood_fill_entry_coords = (img_h + (2 * img_w) - 3 -
                                   flood_fill_entry_point, img_h - 1)
    else:
        flood_fill_entry_coords = (0, perimeter - flood_fill_entry_point)

    flood_fill_mask = np.zeros((mask.shape[0] + 2, mask.shape[1] + 2),
                               dtype=np.uint8)

    cv2.floodFill(mask, flood_fill_mask, tuple(flood_fill_entry_coords), 255)

    return mask
Exemple #15
0
blurred = cv2.GaussianBlur(gray, (9, 9), 0)
#Adaptive gaussian thresholding produced the best results
blu_thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
                                   cv2.THRESH_BINARY, 11, 8)

inv = cv2.bitwise_not(blu_thresh)
kernel = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], np.uint8)
fin = cv2.dilate(inv, kernel)

##DETECTING THE GRID
height, width, _ = img.shape
maxi = -1
for x in range(0, height):
    for y in range(0, width):
        if fin[x, y] >= 128:
            area = cv2.floodFill(fin, None, (y, x), 80)[0]
            if area > maxi:
                maxpt = (y, x)
                maxi = area

cv2.floodFill(fin, None, maxpt, 255)
# cv2.imshow("a", fin)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
for x in range(height):
    for y in range(width):
        if fin[x, y] == 80 and x != maxpt[1] and y != maxpt[0]:
            cv2.floodFill(fin, None, (y, x), 0)
# fin = cv2.resize(fin, (28, 28))
# cv2.imshow("a", fin)
# cv2.waitKey(0)
Exemple #16
0
def flood(image):
    image_flooded = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros((h + 2, w + 2), np.uint8)
    cv2.floodFill(image_flooded, mask, (0, 0), (0, 0, 0))
    return image_flooded