Filling edges using flood fill not working properly












-1















I am using openCV in python to detect cracks in concrete. I am able to use canny edge detection to detect cracks. Next, I need to fill the edges. I used floodfill operation of openCV but some of the gaps are filled whereas some are not filled. The image on the left is the input image whereas that on the right is the floodfilled image. I am guessing this is because my edges have breaks at points. How do i solve this ?
My code for floodfilling:



im_th1 = imginput
im_floodfill = im_th1.copy()
# Mask used to flood filling.
# Notice the size needs to be 2 pixels than the image.
h, w = im_th1.shape[:2]
mask = np.zeros((h + 2, w + 2), np.uint8)

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

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

# Combine the two images to get the foreground.
im_out = im_th1 | im_floodfill_inv
cv2.imshow("Foreground", im_out)
cv2.waitKey(0)









share|improve this question



























    -1















    I am using openCV in python to detect cracks in concrete. I am able to use canny edge detection to detect cracks. Next, I need to fill the edges. I used floodfill operation of openCV but some of the gaps are filled whereas some are not filled. The image on the left is the input image whereas that on the right is the floodfilled image. I am guessing this is because my edges have breaks at points. How do i solve this ?
    My code for floodfilling:



    im_th1 = imginput
    im_floodfill = im_th1.copy()
    # Mask used to flood filling.
    # Notice the size needs to be 2 pixels than the image.
    h, w = im_th1.shape[:2]
    mask = np.zeros((h + 2, w + 2), np.uint8)

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

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

    # Combine the two images to get the foreground.
    im_out = im_th1 | im_floodfill_inv
    cv2.imshow("Foreground", im_out)
    cv2.waitKey(0)









    share|improve this question

























      -1












      -1








      -1








      I am using openCV in python to detect cracks in concrete. I am able to use canny edge detection to detect cracks. Next, I need to fill the edges. I used floodfill operation of openCV but some of the gaps are filled whereas some are not filled. The image on the left is the input image whereas that on the right is the floodfilled image. I am guessing this is because my edges have breaks at points. How do i solve this ?
      My code for floodfilling:



      im_th1 = imginput
      im_floodfill = im_th1.copy()
      # Mask used to flood filling.
      # Notice the size needs to be 2 pixels than the image.
      h, w = im_th1.shape[:2]
      mask = np.zeros((h + 2, w + 2), np.uint8)

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

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

      # Combine the two images to get the foreground.
      im_out = im_th1 | im_floodfill_inv
      cv2.imshow("Foreground", im_out)
      cv2.waitKey(0)









      share|improve this question














      I am using openCV in python to detect cracks in concrete. I am able to use canny edge detection to detect cracks. Next, I need to fill the edges. I used floodfill operation of openCV but some of the gaps are filled whereas some are not filled. The image on the left is the input image whereas that on the right is the floodfilled image. I am guessing this is because my edges have breaks at points. How do i solve this ?
      My code for floodfilling:



      im_th1 = imginput
      im_floodfill = im_th1.copy()
      # Mask used to flood filling.
      # Notice the size needs to be 2 pixels than the image.
      h, w = im_th1.shape[:2]
      mask = np.zeros((h + 2, w + 2), np.uint8)

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

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

      # Combine the two images to get the foreground.
      im_out = im_th1 | im_floodfill_inv
      cv2.imshow("Foreground", im_out)
      cv2.waitKey(0)






      python opencv image-processing edge-detection flood-fill






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 18 '18 at 6:56









      Eshant Eshant

      53




      53
























          2 Answers
          2






          active

          oldest

          votes


















          0














          I see this so often here on SO, everybody wants to use edge detection, and then fill in the area in between the edges.



          Unless you use a method for edge detection that purposefully creates a closed contour, detected edges will likely not form a closed contour. And you cannot flood-fill a region unless you have a closed contour.



          In most of these cases, some filtering and a simple threshold suffice. For example:



          import PyDIP as dip
          import matplotlib.pyplot as pp

          img = dip.Image(pp.imread('oJAo7.jpg')).TensorElement(1) # From OP's other question
          img = img[4:698,6:]

          lines = dip.Tophat(img, 10, polarity='black')
          dip.SetBorder(lines, [0], [2])
          lines = dip.PathOpening(lines, length=100, polarity='opening', mode={'robust'})
          lines = dip.Threshold(lines, method='otsu')[0]


          output of script



          This result is obtained after a simple top-hat filter, which keeps only thin things, followed by a path opening, which keeps only long things. This combination removes large-scale shading, as well as the small bumps and things. After the filtering, a simple Otsu threshold yields a binary image that marks all pixels in the crack.



          Notes:




          • The input image is the one OP posted in another question, and is the input to the images posted in this question.

          • I'm using PyDIP, which you can get on GitHub and need to compile yourself. Hopefully soon we'll have a binary distribution. I'm an author.






          share|improve this answer
























          • I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

            – Eshant
            Nov 23 '18 at 6:15













          • @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

            – Cris Luengo
            Nov 23 '18 at 6:34



















          0














          I found the solution to what i was looking for. Posting it here as it might come of use to others. After some research on the internet, it was just 2 lines of codes as suggested in this : How to complete/close a contour in python opencv?



          The code that worked for me is :



          kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
          dilated = cv2.dilate(image, kernel)
          eroded=cv2.erode(dilated,kernel)


          The result is in the image attached that shows before and after results.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53358598%2ffilling-edges-using-flood-fill-not-working-properly%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I see this so often here on SO, everybody wants to use edge detection, and then fill in the area in between the edges.



            Unless you use a method for edge detection that purposefully creates a closed contour, detected edges will likely not form a closed contour. And you cannot flood-fill a region unless you have a closed contour.



            In most of these cases, some filtering and a simple threshold suffice. For example:



            import PyDIP as dip
            import matplotlib.pyplot as pp

            img = dip.Image(pp.imread('oJAo7.jpg')).TensorElement(1) # From OP's other question
            img = img[4:698,6:]

            lines = dip.Tophat(img, 10, polarity='black')
            dip.SetBorder(lines, [0], [2])
            lines = dip.PathOpening(lines, length=100, polarity='opening', mode={'robust'})
            lines = dip.Threshold(lines, method='otsu')[0]


            output of script



            This result is obtained after a simple top-hat filter, which keeps only thin things, followed by a path opening, which keeps only long things. This combination removes large-scale shading, as well as the small bumps and things. After the filtering, a simple Otsu threshold yields a binary image that marks all pixels in the crack.



            Notes:




            • The input image is the one OP posted in another question, and is the input to the images posted in this question.

            • I'm using PyDIP, which you can get on GitHub and need to compile yourself. Hopefully soon we'll have a binary distribution. I'm an author.






            share|improve this answer
























            • I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

              – Eshant
              Nov 23 '18 at 6:15













            • @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

              – Cris Luengo
              Nov 23 '18 at 6:34
















            0














            I see this so often here on SO, everybody wants to use edge detection, and then fill in the area in between the edges.



            Unless you use a method for edge detection that purposefully creates a closed contour, detected edges will likely not form a closed contour. And you cannot flood-fill a region unless you have a closed contour.



            In most of these cases, some filtering and a simple threshold suffice. For example:



            import PyDIP as dip
            import matplotlib.pyplot as pp

            img = dip.Image(pp.imread('oJAo7.jpg')).TensorElement(1) # From OP's other question
            img = img[4:698,6:]

            lines = dip.Tophat(img, 10, polarity='black')
            dip.SetBorder(lines, [0], [2])
            lines = dip.PathOpening(lines, length=100, polarity='opening', mode={'robust'})
            lines = dip.Threshold(lines, method='otsu')[0]


            output of script



            This result is obtained after a simple top-hat filter, which keeps only thin things, followed by a path opening, which keeps only long things. This combination removes large-scale shading, as well as the small bumps and things. After the filtering, a simple Otsu threshold yields a binary image that marks all pixels in the crack.



            Notes:




            • The input image is the one OP posted in another question, and is the input to the images posted in this question.

            • I'm using PyDIP, which you can get on GitHub and need to compile yourself. Hopefully soon we'll have a binary distribution. I'm an author.






            share|improve this answer
























            • I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

              – Eshant
              Nov 23 '18 at 6:15













            • @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

              – Cris Luengo
              Nov 23 '18 at 6:34














            0












            0








            0







            I see this so often here on SO, everybody wants to use edge detection, and then fill in the area in between the edges.



            Unless you use a method for edge detection that purposefully creates a closed contour, detected edges will likely not form a closed contour. And you cannot flood-fill a region unless you have a closed contour.



            In most of these cases, some filtering and a simple threshold suffice. For example:



            import PyDIP as dip
            import matplotlib.pyplot as pp

            img = dip.Image(pp.imread('oJAo7.jpg')).TensorElement(1) # From OP's other question
            img = img[4:698,6:]

            lines = dip.Tophat(img, 10, polarity='black')
            dip.SetBorder(lines, [0], [2])
            lines = dip.PathOpening(lines, length=100, polarity='opening', mode={'robust'})
            lines = dip.Threshold(lines, method='otsu')[0]


            output of script



            This result is obtained after a simple top-hat filter, which keeps only thin things, followed by a path opening, which keeps only long things. This combination removes large-scale shading, as well as the small bumps and things. After the filtering, a simple Otsu threshold yields a binary image that marks all pixels in the crack.



            Notes:




            • The input image is the one OP posted in another question, and is the input to the images posted in this question.

            • I'm using PyDIP, which you can get on GitHub and need to compile yourself. Hopefully soon we'll have a binary distribution. I'm an author.






            share|improve this answer













            I see this so often here on SO, everybody wants to use edge detection, and then fill in the area in between the edges.



            Unless you use a method for edge detection that purposefully creates a closed contour, detected edges will likely not form a closed contour. And you cannot flood-fill a region unless you have a closed contour.



            In most of these cases, some filtering and a simple threshold suffice. For example:



            import PyDIP as dip
            import matplotlib.pyplot as pp

            img = dip.Image(pp.imread('oJAo7.jpg')).TensorElement(1) # From OP's other question
            img = img[4:698,6:]

            lines = dip.Tophat(img, 10, polarity='black')
            dip.SetBorder(lines, [0], [2])
            lines = dip.PathOpening(lines, length=100, polarity='opening', mode={'robust'})
            lines = dip.Threshold(lines, method='otsu')[0]


            output of script



            This result is obtained after a simple top-hat filter, which keeps only thin things, followed by a path opening, which keeps only long things. This combination removes large-scale shading, as well as the small bumps and things. After the filtering, a simple Otsu threshold yields a binary image that marks all pixels in the crack.



            Notes:




            • The input image is the one OP posted in another question, and is the input to the images posted in this question.

            • I'm using PyDIP, which you can get on GitHub and need to compile yourself. Hopefully soon we'll have a binary distribution. I'm an author.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 18 '18 at 8:01









            Cris LuengoCris Luengo

            19.7k52149




            19.7k52149













            • I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

              – Eshant
              Nov 23 '18 at 6:15













            • @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

              – Cris Luengo
              Nov 23 '18 at 6:34



















            • I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

              – Eshant
              Nov 23 '18 at 6:15













            • @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

              – Cris Luengo
              Nov 23 '18 at 6:34

















            I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

            – Eshant
            Nov 23 '18 at 6:15







            I get the error : "module 'pydip' has no attribute 'Image'" when i use the above code. I tried to install the PyDIP library using PIP install PyDIP. Isn't this the correcct way ? Your output looks so promising but not working here !

            – Eshant
            Nov 23 '18 at 6:15















            @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

            – Cris Luengo
            Nov 23 '18 at 6:34





            @Eshant: No, you cannot install PyDIP through pip, we don't have a binary distribution yet, you need to compile from sources.

            – Cris Luengo
            Nov 23 '18 at 6:34













            0














            I found the solution to what i was looking for. Posting it here as it might come of use to others. After some research on the internet, it was just 2 lines of codes as suggested in this : How to complete/close a contour in python opencv?



            The code that worked for me is :



            kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
            dilated = cv2.dilate(image, kernel)
            eroded=cv2.erode(dilated,kernel)


            The result is in the image attached that shows before and after results.






            share|improve this answer




























              0














              I found the solution to what i was looking for. Posting it here as it might come of use to others. After some research on the internet, it was just 2 lines of codes as suggested in this : How to complete/close a contour in python opencv?



              The code that worked for me is :



              kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
              dilated = cv2.dilate(image, kernel)
              eroded=cv2.erode(dilated,kernel)


              The result is in the image attached that shows before and after results.






              share|improve this answer


























                0












                0








                0







                I found the solution to what i was looking for. Posting it here as it might come of use to others. After some research on the internet, it was just 2 lines of codes as suggested in this : How to complete/close a contour in python opencv?



                The code that worked for me is :



                kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
                dilated = cv2.dilate(image, kernel)
                eroded=cv2.erode(dilated,kernel)


                The result is in the image attached that shows before and after results.






                share|improve this answer













                I found the solution to what i was looking for. Posting it here as it might come of use to others. After some research on the internet, it was just 2 lines of codes as suggested in this : How to complete/close a contour in python opencv?



                The code that worked for me is :



                kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
                dilated = cv2.dilate(image, kernel)
                eroded=cv2.erode(dilated,kernel)


                The result is in the image attached that shows before and after results.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 29 '18 at 7:08









                Eshant Eshant

                53




                53






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53358598%2ffilling-edges-using-flood-fill-not-working-properly%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Guess what letter conforming each word

                    Port of Spain

                    Run scheduled task as local user group (not BUILTIN)