8

I would like to fill these polygon with white color and this operation is repeated through a loop over the whole image so I would like to know the syntax and function which can be used to perform this operation using opencv in python This is my input image

enter image description here

alist=[]
img = cv2.imread('closing2.jpg',cv2.IMREAD_GRAYSCALE)
imo = cv2.imread('closing2.jpg',cv2.IMREAD_GRAYSCALE)
imr = cv2.imread('closing2.jpg',cv2.IMREAD_GRAYSCALE)*0
imac = imr
height , width  = imo.shape[:2]
a,im = cv2.threshold(img,200,255,cv2.THRESH_BINARY)
# i=100
# p=[i,i]
points = []
for j in range(0,1000,50):
    for i in range(0,1000,50):
        p=[i,j]
        poly = raypoly(im,p,5)
        st = metrics(p,poly)

        polyc=raypolyLimit(im,p,st,30)
        # print(polyc)
        # print(len(polyc))
        # for m in range(len(polyc)):
        #     point = polyc[m]
        #     cv2.fillConvexPoly(im, point, 255)
        plotpoly(polyc,imr)

        plotpolypoints(polyc,imr,255,1)
        # plotray(im,p,imr)

        am = polyArea(polyc)
        # print(am)
        if am > 5:
            alist.append(am)
            # img[(i-5):(i+5),(j-5):(j+5)]=150
            # plt.imshow(imf)
            # plt.show()
        imo = im * 0
        plotpoly(polyc,imo)
        plotpoly(polyc, im)
        # plotArea(polyc,imo)
        imf = imo*1000 +im
        a,imf = cv2.threshold(imf,100.0,255.0,cv2.THRESH_BINARY)
        cv2.imshow('Frame_1', imr)
        cv2.imshow('Frame_3', imo)
        cv2.imshow('Frame_4', imf)
        cv2.imshow('Frame_5', im)
        cv2.waitKey(1)

I used the following function and the result as follows:

cv2.floodFill(imo,None,(i,j),255)

But my problem is that it gives a white flash for the whole image after certain number of polygons and I don't know how to fix it .

enter image description here

Medo2018
  • 479
  • 1
  • 4
  • 13
  • If you do not insist on using opencv, there is [scipy.ndimage.morphology.binary_fill_holes](https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.morphology.binary_fill_holes.html) for binary images – Tankred Aug 27 '19 at 07:24
  • 1
    Are you provided with these empty polygons or do you create them on your own, e.g. using [`drawContours`](https://docs.opencv.org/4.1.1/d6/d6e/group__imgproc__draw.html#ga746c0625f1781f1ffc9056259103edbc)? If the latter, just set the `thickness` to `FILLED`. Otherwise, you may need to use [`findContours`](https://docs.opencv.org/4.1.1/d3/dc0/group__imgproc__shape.html#gadf1ad6a0b82947fa1fe3c3d497f260e0) to find these polygons beforehand. (Then, you could also use [`floodFill`](https://docs.opencv.org/4.1.1/d7/d1b/group__imgproc__misc.html#gaf1f55a048f8a45bc3383586e80b1f0d0) for example.) – HansHirse Aug 27 '19 at 07:29
  • No these empty polygons were created on my own so I think that usinf floodfill or fillpoly would do this process but my problem is the mask used in this operation ?? – Medo2018 Aug 27 '19 at 07:40
  • @AhmedHabashi Then, please provide the code, which you use to create and draw the polygons [by editing your question](https://stackoverflow.com/posts/57669562/edit). It's easier to suggest possible improvements than making up solutions de novo, which then might not fit your existing code. – HansHirse Aug 27 '19 at 08:06
  • @HansHirse OK I edited my question by posting part of my algorithm as the definition of these functions are more than 250 lines and its main function to draw a polygon surrounding a certain point – Medo2018 Aug 27 '19 at 08:52
  • Why open and read the same file 3 times? You have the data in RAM already! Just copy the RAM, which is millions of times faster and doesn't annoy your disk drive. – Mark Setchell Aug 27 '19 at 09:11
  • @MarkSetchell OK but I don't know that this annoys disk drive .. I can take a copy of image img.copy() – Medo2018 Aug 27 '19 at 09:38
  • I was maybe exaggerating about annoying the disk drive and the buffer cache subsystem, but hopefully you get what I meant. Just trying to help engineers not get into *"sub-optimal practices"* ;-) – Mark Setchell Aug 27 '19 at 09:40
  • @HansHirse Could u tell e the best syntax for the function that suits my algorithm to perform such process – Medo2018 Aug 27 '19 at 10:59
  • @AhmedHabashi Unfortunately, you didn't provide a [mre]. Obviously, there are private methods in your code. The part with the actual drawing of the polygon seems most interesting here. Also, is the provided image the input or the output? – HansHirse Aug 27 '19 at 11:05
  • @HansHirse the provided image is an input one and I want to fill this polygon to be white and this process is repeated through the whole image as every point in the loop encloses a polygon surrounding it – Medo2018 Aug 27 '19 at 11:10
  • @HansHirse Also I edited my question by providing the required output image and function used but I faced a problem of white flash appears in the image and I don't know what the mask entered is correct or no – Medo2018 Aug 27 '19 at 11:22
  • If you get a full white image, then one of your polygons is not fully closed and the flood fill leaks out to fill the whole image. – fmw42 Aug 27 '19 at 17:05
  • https://stackoverflow.com/questions/51121978/how-to-fill-a-polyline-in-opencv – Jeru Luke Apr 28 '22 at 09:21

1 Answers1

6

You can use cv2.drawContours() to fill in a contour. From the docs, if the thickness parameter is negative (thickness=CV_FILLED or thickness=-1) then the contours will be filled. For instance, to fill in a contour with white

cv2.drawContours(image, [c], -1, (255,255,255), -1)

So the idea is to find the desired contour using cv2.findContours() then fill it in using cv2.drawContours(). For your image:

enter image description here

import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), -1)

cv2.imshow('image', image)
cv2.waitKey()
nathancy
  • 42,661
  • 14
  • 115
  • 137