{"id":877,"date":"2018-04-05T12:21:17","date_gmt":"2018-04-05T04:21:17","guid":{"rendered":"http:\/\/www.whudj.cn\/?p=877"},"modified":"2018-04-05T12:21:17","modified_gmt":"2018-04-05T04:21:17","slug":"3d-hough%e5%8f%98%e6%8d%a2%e7%82%b9%e4%ba%91%e5%b9%b3%e9%9d%a2%e6%a3%80%e6%b5%8b%e7%ae%97%e6%b3%95","status":"publish","type":"post","link":"http:\/\/www.whudj.cn\/?p=877","title":{"rendered":"3D Hough\u53d8\u6362\u70b9\u4e91\u5e73\u9762\u68c0\u6d4b\u7b97\u6cd5"},"content":{"rendered":"<p>\u672c\u6587\u7684\u4e3b\u8981\u76ee\u6807\uff1a1.\u4ecb\u7ecd3D Hough Transform\u7684\u5e94\u7528\u573a\u666f\uff0c\u7b97\u6cd5\u601d\u8def\uff0c\u7b97\u6cd5\u6b65\u9aa4\u4ee5\u53ca\u4ee3\u7801\u30022.\u5bf9\u5176\u5e94\u7528\u573a\u666f\u8fdb\u884c\u66f4\u8fdb\u4e00\u6b65\u5206\u6790\uff0c\u4e0e\u76f8\u4f3c\u7528\u9014\u7684\u7b97\u6cd5\uff08RandSAC\uff09\u8fdb\u884c\u6bd4\u8f83,\u5206\u6790\u4f18\u7f3a\u70b9\u3002<!--more--><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>1.\u9002\u7528\u573a\u666f\u5206\u6790\uff1a<\/strong><\/span><\/p>\n<p>\u62df\u5408\u95ee\u9898\u4e5f\u53ef\u4ee5\u770b\u6210\u662f\u5728\u53c2\u6570\u7a7a\u95f4\u5185\u8fdb\u884c\u7684\u641c\u7d22\u3002\u5728\u6211\u4eec\u9047\u5230\u62df\u5408\u95ee\u9898\u65f6\uff0c\u6211\u4eec\u9700\u8981\u89e3\u7b54\u7684\u95ee\u9898\u901a\u5e38\u662f\u4ee5\u4e0b\u51e0\u4e2a\u65b9\u9762\u4e2d\u7684\u4e00\u4e2a\uff1a<\/p>\n<ol>\n<li>\u5df2\u77e5\u70b9\u96c6\u5408\u5c5e\u4e8e\u67d0\u4e00\u4e2a\u5e73\u9762\uff08\u6a21\u578b\uff09\uff0c\u8fd9\u4e2a\u6a21\u578b\u7684\u53c2\u6570\u662f\u591a\u5c11\uff1f<\/li>\n<li>\u70b9\u96c6\u4e2d\u53ef\u80fd\u5b58\u57280\u5230\u591a\u4e2a\u5e73\u9762\uff08\u6a21\u578b\uff09\uff0c\u627e\u5230\u5177\u4f53\u6709\u591a\u5c11\u6a21\u578b\u5b9e\u4f8b\uff1f<\/li>\n<li>\u627e\u5230\u70b9\u96c6\u4e2d\u7684\u54ea\u4e9b\u70b9\u5bf9\u5e94\u54ea\u4e9b\u5e73\u9762\uff08\u6a21\u578b\uff09\uff1f<\/li>\n<\/ol>\n<p>\u9488\u5bf9\u6bcf\u4e00\u4e2a\u95ee\u9898\uff0c\u8003\u8651\u5230\u566a\u97f3\u7684\u5206\u5e03\u3001\u8ba1\u7b97\u7684\u4ee3\u4ef7\uff0c\u4e00\u822c\u90fd\u80fd\u627e\u5230\u6bd4\u8f83\u9002\u5408\u7684\u89e3\u51b3\u65b9\u6cd5\u3002Hough Tranform(\u4e0b\u6587\u79f0HT)\u65b9\u6cd5\uff0c\u53ef\u4ee5\u7528\u4e8e\u89e3\u51b3\uff08\u4f46\u4e0d\u4e00\u5b9a\u662f\u6700\u9002\u7528\uff09\u5168\u90e8\u4ee5\u4e0a\u95ee\u9898\u3002\u5728\u540e\u9762\u7684\u5177\u4f53\u5206\u6790\u4e2d\uff0c\u6211\u4eec\u4f1a\u77e5\u9053\u90a3\u79cd\u573a\u666f\u9002\u5408\u7528\u54ea\u79cd\u65b9\u6cd5\u89e3\u51b3\u3002<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>2.\u7b97\u6cd5\u601d\u8def\uff1a<\/strong><\/span><\/p>\n<p><span style=\"text-decoration: underline;\">2.1\u201c\u6295\u7968\u201d\u7b97\u6cd5<\/span><\/p>\n<p>\u5df2\u77e5\u70b9\u96c6\\(\\{p_1,&#8230;,p_n\\}\\) \u4e2d\u5b58\u5728\u5e73\u9762\u4ee5\u53ca\u4e00\u5b9a\u6570\u91cf\u7684\u566a\u97f3\uff0c\u6c42\u89e3\u6700\u597d\u5e73\u9762\u7684\u53c2\u6570m\u3002\u62df\u5408\u95ee\u9898\u7684\u89e3\u51b3\u601d\u8def\u53ef\u4ee5\u7528\u201c\u6295\u7968(voting)\u201d\u6765\u6982\u62ec\uff1a\u7531\u70b9 \\(p_i\\)\u5411\u5176\u7b26\u5408\u7684\u6a21\u578b\\(m_x\\)\u6295\u7968\uff0c\u5f97\u7968\u8005\u6700\u591a\u7684\u6a21\u578b\u80dc\u51fa\u6210\u4e3a\u201c\u6700\u597d\u5e73\u9762\u201d\u3002\u4ece\u7406\u8bba\u4e0a\u6765\u8bf4\uff0c\u8fd9\u79cd\u65b9\u6cd5\u975e\u5e38\u901a\u7528\uff0c\u4e0d\u8fc7\uff0cn\u4e2a\u70b9\u7684\\(p_i\\)\u4e0e\u6570\u91cf\u4e0d\u786e\u5b9a\u7684\u6a21\u578b\u4e4b\u95f4\u7684\u7ec4\u5408\u5f15\u53d1\u4e86\u53ef\u7a77\u4e3e\u6027\u7684\u95ee\u9898\uff0c\u600e\u6837\u786e\u5b9a\u6a21\u578b\u7684\u6570\u91cf\uff1fHT\u89e3\u51b3\u7684\u5c31\u662f\u8fd9\u4e2a\u95ee\u9898\u3002<\/p>\n<p><span style=\"text-decoration: underline;\">2.2\u6cd5\u5411\u91cf\u7684\u8f6c\u6362<\/span><\/p>\n<p>\u5e73\u9762\u7684\u65b9\u7a0b:\\(Ax+By+Cz+D=0\\),\u5176\u4e2d\\(\\vec v = \\begin{bmatrix}A\\\\B\\\\C\\end{bmatrix}\\)\u4e3a\u5e73\u9762\u7684\u6cd5\u5411\u91cf\u3002D\u4e3a\u539f\u70b9\\((0,0,0)\\)\u5230\u5e73\u9762\u7684\u8ddd\u79bb(\u6709\u7b26\u53f7)\u3002\u6211\u4eec\u53ef\u4ee5\u5c06\u6cd5\u5411\u91cf\\(\\vec v\\)\u5e26\u5165\u7403\u6781\u5750\u6807\u7cfb\u8003\u8651\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-895\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/polar_coor_sys.jpg\" alt=\"\" width=\"220\" height=\"162\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-897\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/coordinates-spherical.png\" alt=\"\" width=\"240\" height=\"180\" \/><\/p>\n<p>\u5728\u6781\u5750\u6807\u7cfb\u4e0b$$\\vec v=\\begin{bmatrix}<br \/>\ncos\\phi sin\\theta \\\\<br \/>\nsin\\phi sin\\theta \\\\<br \/>\ncos\\theta \\\\<br \/>\n\\end{bmatrix}$$\u56e0\u4e3a \\(\\theta \\in [0,2\\pi],\\phi \\in[0,2\\pi]\\),\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u79bb\u6563\\(\\theta,\\phi\\)\u4ee5\u53ca\u539f\u70b9\u5230\u5e73\u9762\u7684\u8ddd\u79bb\\(\\rho\\)\u6765\u5b9e\u73b0\u5bf9\u53c2\u6570\u7a7a\u95f4\u7684\u79bb\u6563\u5316\u679a\u4e3e\u3002<\/p>\n<p><span style=\"text-decoration: underline;\">2.3\u7d2f\u52a0\u5668<\/span><\/p>\n<p>\u76f4\u7ebf\u65b9\u7a0b\u4e3a : \\( (cos\\phi sin\\theta) x +\u00a0 (sin\\phi sin\\theta) y +\u00a0cos\\theta + \\rho =0 \\)\uff0c\u5bf9\u4e8e\u70b9\\(p_i\\)\uff0c\u5176\u9488\u5bf9\u6240\u6709\u7684 \\((\\theta,\\phi)\\)\u5e26\u5165\u65b9\u7a0b\u5747\u53ef\u6c42\u5f97\u5bf9\u5e94\u7684\\(\\rho\\)\uff0c\u56e0\u6b64\u6bcf\u4e2a\u70b9\\(p_i\\)\u90fd\u53ef\u5728\u53c2\u6570\u7a7a\u95f4\u5f62\u6210\u4e86\u5bf9\u5e94\u53c2\u6570\u66f2\u9762\u5982\u4e0b\u56fe\u6240\u793a\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-903\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/onepoint_parameter.png\" alt=\"\" width=\"383\" height=\"222\" \/><\/p>\n<p>\u591a\u4e2a\u70b9\u5bf9\u5e94\u7684\u53c2\u6570\u66f2\u9762\u4f1a\u5f62\u6210\u591a\u4e2a\u4ea4\u70b9\uff0c\u5176\u4e2d\u4ea4\u70b9\u6700\u591a\u7684\u53c2\u6570\\((\\theta,\\phi,\\rho)\\)\u5373\u5bf9\u5e94\u7684\u70b9\u6570\u6700\u591a\u7684\u5e73\u9762\u3002\u5982\u4e0b\u56fe\u6240\u793a\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-904\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/multi_parameters.png\" alt=\"\" width=\"400\" height=\"234\" \/><\/p>\n<p>\u4ece\u5b9e\u73b0\u7684\u89d2\u5ea6\u8003\u8651\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u4e00\u4e2a\u4e09\u7ef4\u7684\u6570\u7ec4\uff0c\u7b2c\u4e09\u7ef4\u4fdd\u5b58\u7b26\u5408\u5e73\u9762\u7684\u70b9\u7684\u4e2a\u6570\uff0c\u79f0\u4e3a\u7d2f\u52a0\u5668\u3002\u9488\u5bf9\u6bcf\u4e2a\u70b9\\(p_i\\)\uff0c\u5747\u5bf9\u5176\u5bf9\u5e94\u7684\\((\\theta,\\phi,\\rho)\\)\u8fdb\u884c\u7d2f\u52a0\u3002<\/p>\n<p><span style=\"text-decoration: underline;\">2.4\u9700\u8981\u8003\u8651\u7684\u95ee\u9898\uff1a<\/span><\/p>\n<p>\u4ee5\u4e8c\u7ef4HT\u7ebf\u68c0\u6d4b\u4e3a\u4f8b\uff0c\u51fa\u4e8e\u566a\u58f0\u7684\u5f71\u54cd\uff0c\u6211\u4eec\u8ba4\u4e3a\u7684\u540c\u4e00\u6761\u7ebf\u53ef\u80fd\u5728HT\u7a7a\u95f4\u4e0a\u5212\u5206\u4e3a\u591a\u4e2a\\((\\theta,\\phi,\\rho)\\) \u56e0\u800c\u5f15\u53d1\u5176\u5728\u7d2f\u52a0\u5668\u4e0a\u7684\u5cf0\u503c\u53d8\u7684\u6a21\u7cca\uff08fuzzy\uff09\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-906\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/ht_noise_effects.png\" alt=\"\" width=\"300\" height=\"280\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-907\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/ht_noise_effects_curve.png\" alt=\"\" width=\"300\" height=\"289\" \/><\/p>\n<p>\u89e3\u51b3\u65b9\u6848\u662f\u5728\u8fdb\u884c\u7d2f\u52a0\u503c\u5cf0\u503c\u7edf\u8ba1\u65f6\uff0c\u5e76\u4e0d\u7edf\u8ba1\u6bcf\u4e2a\u57fa\u672c\u5355\u5143\u7684\u70b9\u4e2a\u6570\u800c\u5f97\u5230\u6700\u5927\u503c\uff0c\u800c\u662f\u5bf9\u6bcf\u4e2a\u5355\u5143\u7684\u4e00\u4e2a\u90bb\u57df\u8fdb\u884c\u5408\u5e76\u7edf\u8ba1\uff0c\u53ef\u4ee5\u5e2e\u52a9\u89e3\u51b3\u566a\u97f3\u5bfc\u81f4\u7684\u5cf0\u503c\u5206\u6563\u7684\u95ee\u9898\u3002<\/p>\n<p>\u7b2c\u4e8c\u4e2a\u95ee\u9898\u662f\uff0c\u6211\u4eec\u8ba4\u4e3a\u5e73\u9762\u6cd5\u5411\u91cf\\(v(x,y,z)\\)\u4e0e\\((-x,-y,-z)\\)\u662f\u7b49\u540c\u7684\uff0c\u6240\u4ee5\u5728\\(\\theta,\\phi\\)\u89d2\u5ea6\u7684\u503c\u57df\u4e0a\uff0c\u6211\u4eec\u4ec5\u9009\u53d6\u534a\u7403\\(\\theta\\in[0,\\pi],\\phi\\in[0,\\pi]\\)\u5373\u53ef\u3002\u8fd9\u6837\u4e5f\u7f29\u5c0f\u4e86\u8ba1\u7b97\u91cf\u3002\u540c\u65f6\uff0c\u56e0\u4e3a\u6cd5\u5411\u91cf\u7684\u8fd9\u79cd\u5bf9\u79f0\u6027\uff0c\u5728\u7edf\u8ba1\u7d2f\u52a0\u5668\u4e2a\u6570\u65f6\uff0c\u6211\u4eec\u4e5f\u8981\u8ba4\u4e3a\\(\\theta=0\\)\u4e0e\\(\\theta=\\pi\\)\u662f\u6bd7\u8fde\u7684\uff0c\u5bf9\\(\\phi\\)\u4ea6\u7136\u3002<\/p>\n<p><strong><span style=\"text-decoration: underline;\">3.\u9488\u5bf9\u5177\u4f53\u5e94\u7528\u7684\u6539\u8fdb\uff1a<\/span><\/strong><\/p>\n<p>\u5728\u7279\u5b9a\u7684\u5e94\u7528\u4e2d\uff0c\u6211\u4eec\u53ef\u80fd\u5bf9\u5e73\u9762\u7684\u67d0\u4e9b\u7279\u5f81\u8fdb\u884c\u4e86\u66f4\u8fdb\u4e00\u6b65\u7684\u786e\u5b9a\u3002\u6bd4\u5982\u8bf4\u4ea4\u901a\u6807\u724c\uff0c\u5176\u6cd5\u5411\u91cf\u901a\u5e38\u671d\u5411\u884c\u8f66\u65b9\u5411\uff0c\u7ed3\u5408HT\u7a7a\u95f4\\((\\theta,\\phi)\\)\u7684\u5177\u4f53\u542b\u4e49\uff0c\u6211\u4eec\u53ef\u4ee5\u7f29\u5c0f\u4e0a\u8ff0\u53c2\u6570\u7684\u503c\u57df\u8303\u56f4\uff0c\u56e0\u6b64\u4e0d\u4f46\u53ef\u4ee5\u6392\u9664\u65e0\u5173\u5e73\u9762\u7684\u201c\u4e71\u5165\u201d,\u800c\u4e14\u6781\u5927\u7684\u52a0\u901f\u4e86\u7b97\u6cd5\u7684\u6548\u7387\uff0c\u51cf\u5c0f\u4e86\u4e0d\u5c0f\u7684\u4e00\u7b14\u8ba1\u7b97\u91cf\u3002<\/p>\n<p><strong><span style=\"text-decoration: underline;\">4.\u5206\u6790\u4ee5\u53ca\u4e0e\u7c7b\u4f3c\u7b97\u6cd5\u8fdb\u884c\u5bf9\u6bd4\uff1a<\/span><\/strong><\/p>\n<p>HT\u7b97\u6cd5\u7684\u4f18\u70b9\uff1a<\/p>\n<ol>\n<li>\u6240\u6709\u70b9\u90fd\u662f\u72ec\u7acb\u5904\u7406\u7684\uff0c\u56e0\u6b64\u4e0d\u53d7\u79bb\u7fa4\u70b9\u7684\u5f71\u54cd\u3002<\/li>\n<li>\u5bf9\u566a\u97f3\u6709\u4e00\u5b9a\u7684\u9c81\u68d2\u6027\uff08\u9c81\u68d2\u6027\u8f83\u5176\u4ed6\u7b97\u6cd5\u597d\uff09<\/li>\n<li>\u80fd\u591f\u8fdb\u884c\u591a\u4e2a\u53c2\u6570\u5b9e\u4f8b\uff08\u6bd4\u5982\u8bf4\u591a\u4e2a\u4e0d\u540c\u5e73\u9762\uff09\u7684\u8bc6\u522b\uff0c<strong>\u662fHT\u7684\u72ec\u95e8\u7edd\u6280\u3002<\/strong><\/li>\n<\/ol>\n<p>HT\u7684\u7f3a\u70b9\uff1a<\/p>\n<ol>\n<li>\u8ba1\u7b97\u91cf\u6781\u5927\uff0c\u8ba1\u7b97\u590d\u6742\u7a0b\u5ea6\u662f\u53c2\u6570\u4e2a\u6570\u7684\u6307\u6570\u500d\u3002<\/li>\n<li>\u975e\u76ee\u6807\u8981\u7d20\u4f1a\u9020\u6210\u4f2a\u5cf0\u503c(\u8fd9\u4e00\u6761\u5728\u5e94\u7528\u5f97\u5230\u70b9\u4e91\u5e73\u9762\u68c0\u6d4b\u65f6\u5e76\u672a\u53d1\u73b0)<\/li>\n<li>\u53c2\u6570\u79bb\u6563\u5316\u7684\u6b65\u957f\u6bd4\u8f83\u4e0d\u597d\u9009\u3002<\/li>\n<\/ol>\n<p>\u540c\u4e3a\u201c\u6295\u7968\u201d\u7b97\u6cd5\u5e76\u4e14\u5e7f\u6cdb\u4f7f\u7528\u7684\u8fd8\u6709RandSAC\u7b97\u6cd5\u3002\u5728\u62df\u5408\u7b97\u6cd5\u4e2d\uff0c\u57fa\u672c\u7684\u7b97\u6cd5\u8fd8\u6709\u6700\u5c0f\u4e8c\u4e58\u62df\u5408\u65b9\u6cd5\u3002\u5bf9\u8fd9\u4e09\u79cd\u65b9\u6cd5\u7684\u9002\u7528\u573a\u666f\u3001\u8ba1\u7b97\u91cf\u3001\u566a\u97f3\u5f71\u54cd\u7b49\u8fdb\u884c\u8bc4\u4f30\uff0c\u53ef\u4ee5\u5f97\u5230\u4e0b\u8868\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-917\" src=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/04\/hough_vs_lq_randsac.png\" alt=\"\" width=\"1294\" height=\"379\" \/><\/p>\n<p><strong><span style=\"text-decoration: underline;\">5.\u53c2\u8003\u6587\u732e\uff1a<\/span><\/strong><\/p>\n<ol>\n<li><a href=\"http:\/\/www.whudj.cn\/wp-content\/uploads\/2018\/03\/3dresearch2011.pdf\">The 3D Hough Transform for Plane Detection in Point Clouds:A Review and a new Accumulator Design<\/a><\/li>\n<li><a href=\"http:\/\/vision.stanford.edu\/teaching\/cs231a_autumn1112\/lecture\/lecture4_edges_lines_cs231a_marked.pdf\">Feifei Li: Finding lines: from detection to model fittinig<\/a><\/li>\n<li><a href=\"http:\/\/www.cs.unc.edu\/~lazebnik\/spring11\/lec10_hough.pdf\">Fitting: the Hough Transform<\/a><\/li>\n<li><a href=\"http:\/\/soe.rutgers.edu\/~meer\/UGRAD\/cv9lsransac.pdf\">Least Squares. RandSAC.Hough Transform<\/a><\/li>\n<\/ol>\n<p><span style=\"text-decoration: underline;\"><strong>6.\u5b9e\u73b0\u4ee3\u7801\uff1a<\/strong><\/span><\/p>\n<p>\u6309\u7167\u53c2\u8003\u6587\u732e1\u4e2d\u7684\u8fdb\u884c\u5b9e\u73b0\uff0c\u6587\u732e1\u4e2d\u7684\u65b9\u4f4d\u89d2\u4e3a\\(\\theta\\)\uff0c\u4fef\u4ef0\u89d2\u4e3a\\(\\phi\\)\uff0c\u4e0e\u672c\u6587\u4ee5\u53ca\u901a\u884c\u7684\u79f0\u547c\u6b63\u597d\u76f8\u53cd\uff0c\u8bf7\u8bfb\u8005\u5728\u53c2\u8003\u65f6\u6ce8\u610f\u533a\u522b\u3002<\/p>\n<pre class=\"lang:c++ decode:true\">#define  PI 3.141592653\r\nvoid HoughTransform(const std::vector&lt;Point&gt;&amp; input, double&amp; A, double&amp; B, double&amp; C, double&amp; D)\r\n{\r\n\tint n = input.size();\r\n\tif (n &lt; 3)\r\n\t\treturn;\r\n\r\n\tdouble theta_start=0, theta_end=PI;\r\n\tdouble phi_start=0, phi_end=PI;\r\n\t\/\/double phi_start = 0.25*PI, phi_end = 0.75*PI;\r\n\tdouble anglestep=PI\/90, disstep=0.1;\r\n\r\n\tboundingbox box;\r\n\tcalcboundbox(input, box);\r\n\tdouble d_start = -box.diag() \/ 2.0, d_end = box.diag() \/ 2.0;\r\n\r\n\tint thetas = ceil((theta_end - theta_start) \/ anglestep);\r\n\tint phis = ceil((phi_end - phi_start) \/ anglestep);\r\n\tint dises = ceil( box.diag()\/disstep);\r\n\r\n\tint*** cube = new int**[thetas];\r\n\tfor (int i = 0; i &lt; thetas;++i)\r\n\t{\r\n\t\tcube[i] = new int*[phis];\r\n\t\tfor (int j = 0; j &lt; phis; ++j)\r\n\t\t{\r\n\t\t\tcube[i][j] = new int[dises];\r\n\t\t\tmemset(cube[i][j], 0, sizeof(int)*dises);\r\n\t\t}\r\n\t}\r\n\r\n\t\/\/cos(theta)sin(phi)X+sin(theta)sin(phi)Y+cos(phi)Z = D\r\n\tPoint ptCenter = box.center();\r\n\tfor (int i = 0; i &lt; n;++i)\r\n\t{\r\n\t\tconst Point&amp; ptOrigin = input[i];\r\n\t\tPoint point = ptOrigin - ptCenter;\r\n\r\n\t\tdouble theta = theta_start;\r\n\t\tfor(int j = 0; j &lt; thetas; ++j)\r\n\t\t{\r\n\t\t\tint** row = cube[j];\r\n\t\t\tdouble phi = phi_start;\r\n\t\t\tfor (int k = 0; k &lt; phis; ++k)\r\n\t\t\t{\r\n\t\t\t\tint* col = row[k];\r\n\r\n\t\t\t\tdouble sinphi = sin(phi);\r\n\t\t\t\tdouble d = cos(theta)*sinphi*point.x + sin(theta)*sinphi*point.y + cos(phi)*point.z;\r\n\r\n\t\t\t\tint d_index = floor((d - d_start) \/ disstep);\r\n\t\t\t\t++(col[d_index]);\r\n\r\n\t\t\t\tphi += anglestep;\r\n\t\t\t\tif (phi &gt; phi_end)\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\ttheta += anglestep;\r\n\t\t\tif (theta &gt; theta_end)\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\/\/all points\r\n\r\n\tint buf = 1;\r\n\tint maxcount = 0;\r\n\tint xmax, ymax, zmax;\r\n\r\n\tfor (int i = 0; i &lt; thetas;++i)\r\n\t\tfor (int j = 0; j &lt; phis; ++j)\r\n\t\t\t\tfor (int k = buf; k &lt; dises - buf;++k)\r\n\t\t\t{\r\n\t\t\t\tint count = 0;\r\n\t\t\t\tfor (int x = i - buf; x &lt;= i + buf; ++x)\r\n\t\t\t\t\tfor (int y = j - buf; y &lt;= j + buf; ++y)\r\n\t\t\t\t\t\tfor (int z = k - buf; z &lt;= k + buf; ++z)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tcount += cube[x&lt;0?x+thetas:x%thetas][y&lt;0?y+phis:y%phis][z];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\tif (count &gt; maxcount)\r\n\t\t\t\t{\r\n\t\t\t\t\txmax = i;\r\n\t\t\t\t\tymax = j;\r\n\t\t\t\t\tzmax = k;\r\n\t\t\t\t\tmaxcount = count;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\r\n\tdouble theta = theta_start + xmax*anglestep;\r\n\tdouble phi = phi_start + ymax*anglestep;\r\n\tdouble d = d_start + zmax*disstep;\r\n\r\n\tA = cos(theta)*sin(phi);\r\n\tB = sin(theta)*sin(phi);\r\n\tC = cos(phi);\r\n\tD = -d - (A*ptCenter.x + B*ptCenter.y+C*ptCenter.z);\r\n\t\/\/std::cout &lt;&lt; A &lt;&lt; \" , \" &lt;&lt; B &lt;&lt; \" , \" &lt;&lt; C &lt;&lt; \" , \"&lt;&lt; D &lt;&lt; std::endl;\r\n\t\/\/\u91ca\u653ecube\r\n\tfor (int i = 0; i &lt; thetas; ++i)\r\n\t{\r\n\t\tint** row = cube[i];\r\n\t\tfor (int j = 0; j &lt; phis;++j)\r\n\t\t{\r\n\t\t\tint* col = row[j];\r\n\t\t\tdelete[] col;\r\n\t\t}\r\n\t\tdelete[] row;\r\n\t}\r\n\tdelete[] cube;\r\n}<\/pre>\n<p>\u4f9d\u8d56\u7684<span class=\"lang:c++ decode:true crayon-inline \">Point <\/span>\u00a0\u4ee5\u53ca <span class=\"lang:c++ decode:true crayon-inline \">BoundingBox<\/span>\u00a0\u7684\u5b9e\u73b0\u5982\u4e0b\uff1a<\/p>\n<pre class=\"lang:c++ decode:true \">class Point\r\n{\r\npublic: \r\n\tdouble x, y, z;\r\n\tPoint(double ix,double iy,double iz) :\r\n\t\tx(ix), y(iy), z(iz){}\r\n\r\n\tPoint operator-(const Point&amp; pt) const\r\n\t{\r\n\t\treturn Point(x - pt.x, y - pt.y, z - pt.z);\r\n\t}\r\n};\r\ntypedef Point Vector;\r\n\r\nclass boundingbox\r\n{\r\npublic:\r\n\tdouble x_min, x_max;\r\n\tdouble y_min, y_max;\r\n\tdouble z_min, z_max;\r\n\r\npublic:\r\n\tdouble diag() const\r\n\t{\r\n\t\tdouble dx = x_max - x_min;\r\n\t\tdouble dy = y_max - y_min;\r\n\t\tdouble dz = z_max - z_min;\r\n\r\n\t\treturn sqrt(dx*dx + dy*dy + dz*dz);\r\n\t}\r\n\r\n\tboundingbox():\r\n\t\tx_min(std::numeric_limits&lt;double&gt;::max()),\r\n\t\ty_min(std::numeric_limits&lt;double&gt;::max()),\r\n\t\tz_min(std::numeric_limits&lt;double&gt;::max()),\r\n\t\tx_max(-std::numeric_limits&lt;double&gt;::max()),\r\n\t\ty_max(-std::numeric_limits&lt;double&gt;::max()),\r\n\t\tz_max(-std::numeric_limits&lt;double&gt;::max())\r\n\t{}\r\n\r\n\tPoint center() const\r\n\t{\r\n\t\treturn Point((x_max + x_min) \/ 2.0,(y_min+y_max) \/ 2.0, (z_min+z_max) \/ 2.0);\r\n\t}\r\n};\r\n\r\nvoid calcboundbox(const std::vector&lt;Point&gt;&amp; input, boundingbox&amp; box)\r\n{\r\n\tfor (int i = 0, n = input.size(); i &lt; n;++i)\r\n\t{\r\n\t\tauto point = input[i];\r\n\t\tif (point.x &lt; box.x_min)\r\n\t\t\tbox.x_min = point.x;\r\n\t\tif (point.y &lt; box.y_min)\r\n\t\t\tbox.y_min = point.y;\r\n\t\tif (point.z &lt; box.z_min)\r\n\t\t\tbox.z_min = point.z;\r\n\t\tif (point.x &gt; box.x_max)\r\n\t\t\tbox.x_max = point.x;\r\n\t\tif (point.y &gt; box.y_max)\r\n\t\t\tbox.y_max = point.y;\r\n\t\tif (point.z &gt; box.z_max)\r\n\t\t\tbox.z_max = point.z;\r\n\t}\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u7684\u4e3b\u8981\u76ee\u6807\uff1a1.\u4ecb\u7ecd3D Hough Transform\u7684\u5e94\u7528\u573a\u666f\uff0c\u7b97\u6cd5\u601d\u8def &hellip; <a href=\"http:\/\/www.whudj.cn\/?p=877\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[34],"_links":{"self":[{"href":"http:\/\/www.whudj.cn\/index.php?rest_route=\/wp\/v2\/posts\/877"}],"collection":[{"href":"http:\/\/www.whudj.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.whudj.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.whudj.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.whudj.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=877"}],"version-history":[{"count":23,"href":"http:\/\/www.whudj.cn\/index.php?rest_route=\/wp\/v2\/posts\/877\/revisions"}],"predecessor-version":[{"id":919,"href":"http:\/\/www.whudj.cn\/index.php?rest_route=\/wp\/v2\/posts\/877\/revisions\/919"}],"wp:attachment":[{"href":"http:\/\/www.whudj.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.whudj.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=877"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.whudj.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}