EfelBaum
EfelBaum

Reputation: 159

Filling in Circles in OpenCV

I've been struggling with this for a while. I've been trying to figure out some sort of a way in OpenCV in Python to fill in while circles in an image that's entirely black and white.

To be clear this image has been tresholded using adaptive thresholding but now I have these rings which I'd like to be able to fill in. Ideally whatever algorithm is used to fill in circles should be able for both sets of pictures I included.

If anyone could offer any guidance in this regard I'd greatly appreciate it.

Before Algorithm: Before Algorithm

After Algorithm: After Algorithm

Before Algorithm: Before Algorithm

After Algorithm: After Algorithm

Upvotes: 1

Views: 5646

Answers (2)

zindarod
zindarod

Reputation: 6468

You can also fill the circles by drawing the contours.

import cv2
import numpy as np


#Run Main
if __name__ == "__main__" :

    image = cv2.imread("circle.jpg", -1)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    ret,thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)

    _,contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    cv2.drawContours(image, contours, -1, (255,255,255), thickness=-1)

    cv2.namedWindow('Image', cv2.WINDOW_NORMAL)
    cv2.imshow('Image', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

image1 image2

Upvotes: 2

Andriy Makukha
Andriy Makukha

Reputation: 8334

A simple search in Google would have given you this article, which answers exactly your question.

I adopted that solution for your input:

import cv2
import numpy as np

# Read image
im_in = cv2.imread("circles.jpg", cv2.IMREAD_GRAYSCALE)

# Threshold
th, im_th = cv2.threshold(im_in, 127, 255, cv2.THRESH_BINARY)

# Copy the thresholded image
im_floodfill = im_th.copy()

# Mask used to flood filling.
# NOTE: the size needs to be 2 pixels bigger on each side than the input image
h, w = im_th.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)

# Floodfill from point (0, 0)
cv2.floodFill(im_floodfill, mask, (0,0), 255)

# Invert floodfilled image
im_floodfill_inv = cv2.bitwise_not(im_floodfill)

# Combine the two images to get the foreground
im_out = im_th | im_floodfill_inv

# Display images.
cv2.imwrite("circles_filled.png", im_out)

Input file circles.png:

Circles

Output file circles_filled.png:

Filled circles

Upvotes: 3

Related Questions