{"id":81,"date":"2006-09-01T13:27:42","date_gmt":"2006-09-01T17:27:42","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=81"},"modified":"2019-10-22T16:24:37","modified_gmt":"2019-10-22T20:24:37","slug":"showing-image-pixels-associated-with-a-hough-transform-bin","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2006\/09\/01\/showing-image-pixels-associated-with-a-hough-transform-bin\/","title":{"rendered":"Showing image pixels associated with a Hough transform bin"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>Someone here recently puzzled over the output of the Hough transform functions in the Image Processing Toolbox.  The Hough\r\n      transform is used to detect line segments, typically in binary images.  For the example we were looking at, some of the detected\r\n      \"line segments\" didn't seem to correspond to line segments at all.\r\n   <\/p>\r\n   <p>Let me show you what I mean:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">I = imresize(imread(<span style=\"color: #A020F0\">'concordorthophoto.png'<\/span>),0.15);\r\nbw = edge(I, <span style=\"color: #A020F0\">'canny'<\/span>, [], 2);\r\nimshow(bw)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/81\/show_hough_pixels_01.png\"> <p>The function <a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/images\/index.html?\/access\/helpdesk\/help\/toolbox\/images\/hough.html\"><tt>hough<\/tt><\/a> computes the Hough transform; <a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/images\/index.html?\/access\/helpdesk\/help\/toolbox\/images\/houghpeaks.html\"><tt>houghpeaks<\/tt><\/a> finds peaks in the Hough transform; and <a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/images\/index.html?\/access\/helpdesk\/help\/toolbox\/images\/houghlines.html\"><tt>houghlines<\/tt><\/a> detects line segments corresponding to the peaks.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[H,theta,rho] = hough(bw);\r\npeaks  = houghpeaks(H,5);\r\nlines = houghlines(bw,theta,rho,peaks);<\/pre><p>Now superimpose the detected line segments on the original binary image.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(bw)\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\n<span style=\"color: #0000FF\">for<\/span> k = 1:numel(lines)\r\n    x1 = lines(k).point1(1);\r\n    y1 = lines(k).point1(2);\r\n    x2 = lines(k).point2(1);\r\n    y2 = lines(k).point2(2);\r\n    plot([x1 x2],[y1 y2],<span style=\"color: #A020F0\">'Color'<\/span>,<span style=\"color: #A020F0\">'g'<\/span>,<span style=\"color: #A020F0\">'LineWidth'<\/span>, 4)\r\n<span style=\"color: #0000FF\">end<\/span>\r\nhold <span style=\"color: #A020F0\">off<\/span><\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/81\/show_hough_pixels_02.png\"> <p>Several of the green line segments shown above don't seem to correspond to any particular linear feature in the binary image.\r\n       So why are they there?\r\n   <\/p>\r\n   <p>Well, this is a fairly \"busy\" binary image, with many white pixels belonging to small, curvy features.  These pixels do add\r\n      up in the Hough transform accumulator bins.  If you draw a line in any direction across this image, you'll find a lot pixels\r\n      that lie on the line.  All these pixels will contribute to the same accumulator bin.\r\n   <\/p>\r\n   <p>I got to thinking that it would help to be able to visualize this in some way.  That is, how can we see all the white pixels\r\n      to contribute to a given accumulator bin?\r\n   <\/p>\r\n   <p>Inside <tt>houghlines.m<\/tt> there's a subfunction called <tt>houghpixels<\/tt> that does this computation.  I've pulled this out into an M-file called <a title=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectId=12142 (link no longer works)\"><tt>hough_bin_pixels.m<\/tt><\/a>.  You give it a binary image, the theta and rho vectors returned by <tt>hough<\/tt>, and the row\/column coordinates of a particular bin.  It returns a new binary image containing only the white pixels that\r\n      contributed to that particular bin.\r\n   <\/p>\r\n   <p>For example, here are the white pixels corresponding to the fifth peak in the example above:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">bw2 = hough_bin_pixels(bw, theta, rho, peaks(5,:));\r\nimshow(bw2)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/81\/show_hough_pixels_03.png\"> <p>Let's overlay those pixels in color on the original image. (<a title=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectId=10502&amp;objectType=file (link no longer works)\"><tt>imoverlay<\/tt><\/a> is a function available on the MATLAB Central File Exchange.)\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">rgb = imoverlay(bw, imdilate(bw2,ones(3,3)), [.6 .6 1]);\r\nimshow(rgb)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/81\/show_hough_pixels_04.png\"> <p>(I used dilation above to \"thicken\" the overlay pixels so that they are easier to see.)<\/p>\r\n   <p>So I think the Hough transform is not very useful for an image like this. It won't distinguish well between the linear features\r\n      and the large number of other small features that also contribute to the accumulator bins.\r\n   <\/p>\r\n<script language=\"JavaScript\"> \r\n<!--\r\n    function grabCode_81() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='81 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 81';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Steve Eddins';\r\n        copyright = 'Copyright 2006 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n-->\r\n      <\/script>\r\n<noscript>\r\n<em>A JavaScript-enabled browser is required to use the \"Get the MATLAB code\" link.<\/em>\r\n<\/noscript>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_81()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code<\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n81 ##### SOURCE BEGIN #####\r\n%% Showing image pixels associated with a Hough transform bin\r\n% Someone here recently puzzled over the output of the Hough transform\r\n% functions in the Image Processing Toolbox.  The Hough transform is used\r\n% to detect line segments, typically in binary images.  For the example we\r\n% were looking at, some of the detected \"line segments\" didn't seem to\r\n% correspond to line segments at all.\r\n%\r\n% Let me show you what I mean:\r\n\r\nI = imresize(imread('concordorthophoto.png'),0.15);\r\nbw = edge(I, 'canny', [], 2);\r\nimshow(bw)\r\n\r\n%%\r\n% The function \r\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/images\/index.html?\/access\/helpdesk\/help\/toolbox\/images\/hough.html \r\n% |hough|> computes the Hough transform; \r\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/images\/index.html?\/access\/helpdesk\/help\/toolbox\/images\/houghpeaks.html \r\n% |houghpeaks|> finds peaks\r\n% in the Hough transform; and \r\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/images\/index.html?\/access\/helpdesk\/help\/toolbox\/images\/houghlines.html \r\n% |houghlines|> detects line segments\r\n% corresponding to the peaks.\r\n\r\n[H,theta,rho] = hough(bw);\r\npeaks  = houghpeaks(H,5);\r\nlines = houghlines(bw,theta,rho,peaks);\r\n\r\n%%\r\n% Now superimpose the detected line segments on the original binary image.\r\n\r\nimshow(bw)\r\nhold on\r\nfor k = 1:numel(lines)\r\n    x1 = lines(k).point1(1);\r\n    y1 = lines(k).point1(2);\r\n    x2 = lines(k).point2(1);\r\n    y2 = lines(k).point2(2);\r\n    plot([x1 x2],[y1 y2],'Color','g','LineWidth', 4)\r\nend\r\nhold off\r\n\r\n%%\r\n% Several of the green line segments shown above don't seem to correspond\r\n% to any particular linear feature in the binary image.  So why are they\r\n% there?\r\n%\r\n% Well, this is a fairly \"busy\" binary image, with many white pixels\r\n% belonging to small, curvy features.  These pixels do add up in the Hough\r\n% transform accumulator bins.  If you draw a line in any direction across\r\n% this image, you'll find a lot pixels that lie on the line.  All these\r\n% pixels will contribute to the same accumulator bin.\r\n%\r\n% I got to thinking that it would help to be able to visualize this in some\r\n% way.  That is, how can we see all the white pixels to contribute to a\r\n% given accumulator bin?\r\n%\r\n% Inside |houghlines.m| there's a subfunction called |houghpixels| that does\r\n% this computation.  I've pulled this out into an M-file called\r\n% <https:\/\/blogs.mathworks.com\/images\/steve\/81\/hough_bin_pixels.m \r\n% |hough_bin_pixels.m|>.  You give it a binary image, the theta and rho\r\n% vectors returned by |hough|, and the row\/column coordinates of a particular\r\n% bin.  It returns a new binary image containing only the white pixels that\r\n% contributed to that particular bin.\r\n%\r\n% For example, here are the white pixels corresponding to the fifth peak in\r\n% the example above:\r\n\r\nbw2 = hough_bin_pixels(bw, theta, rho, peaks(5,:));\r\nimshow(bw2)\r\n\r\n%%\r\n% Let's overlay those pixels in color on the original image.  \r\n% (<https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectId=10502&objectType=file \r\n% |imoverlay|> is\r\n% a function available on the MATLAB Central File Exchange.)\r\n\r\nrgb = imoverlay(bw, imdilate(bw2,ones(3,3)), [.6 .6 1]);\r\nimshow(rgb)\r\n\r\n%%\r\n% (I used dilation above to \"thicken\" the overlay pixels so that they are\r\n% easier to see.)\r\n%\r\n% So I think the Hough transform is not very useful for an image like this.\r\n% It won't distinguish well between the linear features and the large\r\n% number of other small features that also contribute to the accumulator\r\n% bins.\r\n\r\n##### SOURCE END ##### 81\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   Someone here recently puzzled over the output of the Hough transform functions in the Image Processing Toolbox.  The Hough\r\n      transform is used to detect line segments, typically in binary... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2006\/09\/01\/showing-image-pixels-associated-with-a-hough-transform-bin\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[228,90,230,234,232,76,156,36,162,68],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/81"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=81"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/81\/revisions"}],"predecessor-version":[{"id":3502,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/81\/revisions\/3502"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=81"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=81"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=81"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}