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

                    鏡平學校

                    ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

                    Why https connections are so slow when debugging (stepping over) in Java?