{"id":5146,"date":"2024-09-27T07:01:01","date_gmt":"2024-09-26T23:01:01","guid":{"rendered":""},"modified":"2024-09-27T07:01:01","modified_gmt":"2024-09-26T23:01:01","slug":"\u5206\u6c34\u5cad\u7b97\u6cd5\u5206\u6790_\u5206\u6c34\u5cad\u5206\u5272\u7b97\u6cd5\u7684\u6b65\u9aa4","status":"publish","type":"post","link":"https:\/\/mushiming.com\/5146.html","title":{"rendered":"\u5206\u6c34\u5cad\u7b97\u6cd5\u5206\u6790_\u5206\u6c34\u5cad\u5206\u5272\u7b97\u6cd5\u7684\u6b65\u9aa4"},"content":{"rendered":"

\n <\/path> \n<\/svg> <\/p>\n

1.\u5206\u6c34\u5cad\u5b9e\u73b0\u539f\u7406<\/h3>\n

\u5206\u6c34\u5cad\u7b97\u6cd5\u5e38\u7528\u4e8e\u76ee\u6807\u5206\u5272\u7814\u7a76\uff0c\u5176\u5c06\u56fe\u50cf\u4ee5\u7070\u5ea6\u4e3a\u53c2\u8003\u53ef\u89c6\u5316\u4e3a\u4e00\u79cd\u62d3\u6251\u5730\u8c8c\uff0c\u7070\u5ea6\u5927\u5c0f\u7b49\u4ef7\u4e8e\u6d77\u62d4\u9ad8\u4f4e\uff0c\u5982\u679c\u5411\u5730\u8c8c\u4e2d\u7684\u5c71\u8c37\u8fdb\u884c\u6f2b\u6c34\uff0c\u4e00\u5b9a\u7a0b\u5ea6\u65f6\u5c71\u4e18\u5c06\u88ab\u5206\u5f00\u6210\u72ec\u7acb\u4e2a\u4f53
1.1\u57fa\u4e8e\u964d\u96e8\u6cd5\u5b9e\u73b0\u5206\u6c34\u5cad
\"\u5206\u6c34\u5cad\u7b97\u6cd5\u5206\u6790_\u5206\u6c34\u5cad\u5206\u5272\u7b97\u6cd5\u7684\u6b65\u9aa4
\u5982\u4e0a\u56fe\u6240\u793a\uff0c\u5047\u8bbe\u96e8\u6c34\u4ece\u800c\u7ed9\u9ad8\u51fa\u964d\u843d\uff0c\u6700\u7ec8\u5728\u5c71\u8c37\u805a\u96c6\uff0c\u4e0d\u540c\u7684\u5c71\u8c37\u88ab\u8d4b\u4e88\u4e0d\u540c\u989c\u8272\uff0c\u7136\u800c\uff0c\u5728\u4e0d\u540c\u989c\u8272\u51fa\u73b0\u6c47\u805a\u7684\u5730\u65b9\uff0c\u6df7\u5408\u989c\u8272\u7684\u4f4d\u7f6e\u5c31\u53ef\u4ee5\u4fee\u5efa\u5927\u575d\uff0c\u5c06\u76ee\u6807\u5206\u5272\u5f00<\/p>\n

1.2\u57fa\u4e8e\u704c\u6c34\u6cd5\u5b9e\u73b0\u5206\u6c34\u5cad
\"\u5206\u6c34\u5cad\u7b97\u6cd5\u5206\u6790_\u5206\u6c34\u5cad\u5206\u5272\u7b97\u6cd5\u7684\u6b65\u9aa4
\u5982\u4e0a\u56fe\u6240\u793a\u5e73\u9762\u56fe\uff0c\u4ece\u5404\u4e2a\u5c71\u8c37\u6316\u4e2a\u6d1e\u5411\u4e0a\u704c\u6c34(\u704c\u6c34\u4f4d\u7f6e\u5bf9\u5e94\u5c40\u90e8\u6781\u5c0f\u503c,\u4f34\u968f\u6c34\u4f4d\u4e0a\u5347\uff0c\u4e0d\u540c\u5c71\u8c37\u7684\u6c34\u76f8\u9047\u65f6\uff0c\u5c31\u53ef\u4ee5\u4fee\u5efa\u5927\u575d<\/p>\n

2.\u5177\u4f53\u5b9e\u73b0<\/h3>\n

\u9644\uff1aopencv\u5b98\u65b9\u5e94\u7528\u4e3e\u4f8b\uff1a
\u57fa\u4e8e\u8ddd\u79bb\u53d8\u6362\u6807\u8bb0\u5206\u6c34\u5cad\u5b9e\u73b0\u5206\u5272<\/p>\n

const<\/span> int<\/span> SHED =<\/span> -<\/span>1<\/span>;<\/span> const<\/span> int<\/span> INQUEUE =<\/span> -<\/span>2<\/span>;<\/span> struct<\/span> point2D<\/span> { \n   <\/span> int<\/span> r,<\/span> c;<\/span> }<\/span>;<\/span> void<\/span> WaterShed_<\/span>(<\/span>Mat &<\/span> gray_img,<\/span> cv::<\/span>Mat &<\/span> markers)<\/span> \/* * gray_img: a 1 channel 8-bit img. * markers: different basins marked as different positive integers, * other position is 0.(32-bit 1 channel img) * * return: watershed mask.(1 channel) *\/<\/span> { \n   <\/span> if<\/span> (<\/span>gray_img.<\/span>channels<\/span>(<\/span>)<\/span> ==<\/span> 3<\/span>)<\/span> { \n   <\/span> cvtColor<\/span>(<\/span>gray_img,<\/span> gray_img,<\/span> COLOR_BGR2GRAY)<\/span>;<\/span> }<\/span> const<\/span> int<\/span> graylevelnum =<\/span> 256<\/span>;<\/span> vector<<\/span>queue<<\/span>point2D>><\/span> queues;<\/span> queues.<\/span>reserve<\/span>(<\/span>graylevelnum)<\/span>;<\/span> for<\/span> (<\/span>int<\/span> i =<\/span> 0<\/span>;<\/span> i <<\/span> graylevelnum;<\/span> i++<\/span>)<\/span> { \n   <\/span> queues.<\/span>emplace_back<\/span>(<\/span>queue<\/span><<\/span>point2D><\/span><\/span><\/span>(<\/span>)<\/span>)<\/span>;<\/span> }<\/span> \/\/res\u8bbe\u4e3a\u8f93\u51fa\u6807\u8bb0\u56fe\u50cf<\/span> int<\/span> Rows =<\/span> res.<\/span>rows -<\/span> 1<\/span>,<\/span> Cols =<\/span> res.<\/span>cols -<\/span> 1<\/span>;<\/span> int<\/span> *<\/span>p =<\/span> res.<\/span>ptr<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>0<\/span>)<\/span>;<\/span> for<\/span> (<\/span>int<\/span> i =<\/span> 0<\/span>;<\/span> i <<\/span> res.<\/span>cols;<\/span> i++<\/span>)<\/span> { \n   <\/span> p[<\/span>i]<\/span> =<\/span> SHED;<\/span> }<\/span>\/\/\u7b2c\u4e00\u884c\u7f6e\u4e3a-1<\/span> p =<\/span> res.<\/span>ptr<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>Rows)<\/span>;<\/span> for<\/span> (<\/span>int<\/span> i =<\/span> 0<\/span>;<\/span> i <<\/span> res.<\/span>cols;<\/span> i++<\/span>)<\/span> { \n   <\/span> p[<\/span>i]<\/span> =<\/span> SHED;<\/span> }<\/span>\/\/\u6700\u540e\u4e00\u884c\u7f6e\u4e3a-1<\/span> for<\/span> (<\/span>int<\/span> i =<\/span> 1<\/span>;<\/span> i <<\/span> Rows;<\/span> i++<\/span>)<\/span>\/\/\u5f53\u524dres\u4ee3\u8868\u6807\u8bb0\u56fe\u50cf<\/span> { \n   <\/span> int<\/span> *<\/span>res_p_pre =<\/span> res.<\/span>ptr<\/span><<\/span>int<\/span> ><\/span><\/span><\/span>(<\/span>i -<\/span> 1<\/span>)<\/span>;<\/span> int<\/span> *<\/span>res_p_cur =<\/span> res.<\/span>ptr<\/span><<\/span>int<\/span> ><\/span><\/span><\/span>(<\/span>i)<\/span>;<\/span> int<\/span> *<\/span>res_p_next =<\/span> res.<\/span>ptr<\/span><<\/span>int<\/span> ><\/span><\/span><\/span>(<\/span>i +<\/span> 1<\/span>)<\/span>;<\/span> uchar *<\/span>gray_p =<\/span> gray.<\/span>ptr<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>i)<\/span>;<\/span> res_p_cur[<\/span>0<\/span>]<\/span> =<\/span> SHED;<\/span> res_p_cur[<\/span>Cols]<\/span> =<\/span> SHED;<\/span>\/\/\u7ed3\u679c\u56fe\u7b2c\u4e00\u5217\u548c\u6700\u540e\u4e00\u5217\u7f6e\u4e3a-1<\/span> for<\/span> (<\/span>int<\/span> j =<\/span> 1<\/span>;<\/span> j <<\/span> Cols;<\/span> j++<\/span>)<\/span>\/\/\u904d\u5386\u6bcf\u4e00\u5217<\/span> { \n   <\/span> if<\/span> (<\/span>res_p_cur[<\/span>j]<\/span> <<\/span> 0<\/span>)<\/span> { \n   <\/span> res_p_cur[<\/span>j]<\/span> =<\/span> 0<\/span>;<\/span> }<\/span>\/\/\uff1f\u4e0d\u5b58\u5728<0\u7684\u60c5\u51b5\u5427<\/span> \/\/check 4 neighbors.<\/span> int<\/span> intensity =<\/span> graylevelnum;<\/span>\/\/\u5f3a\u5ea6\u521d\u59cb\u5316\u4e3a256<\/span> if<\/span> (<\/span>res_p_cur[<\/span>j]<\/span> ==<\/span> 0<\/span> &&<\/span> (<\/span>res_p_pre[<\/span>j]<\/span> ><\/span> 0<\/span> ||<\/span> res_p_next[<\/span>j]<\/span> ><\/span> 0<\/span> ||<\/span> res_p_cur[<\/span>j -<\/span> 1<\/span>]<\/span> ><\/span> 0<\/span> ||<\/span> res_p_cur[<\/span>j +<\/span> 1<\/span>]<\/span> ><\/span> 0<\/span>)<\/span>)<\/span>\/\/\u5982\u679c\u6807\u8bb0\u5f53\u524d\u70b9\u4e3a0+\u5de6\u4e00\u70b9>0+\u53f3\u4e00\u70b9>0+\u4e0a\u4e00\u70b9>0+\u4e0b\u4e00\u70b9>0<\/span> { \n   <\/span> intensity =<\/span> gray_p[<\/span>j]<\/span>;<\/span> }<\/span> \/\/\u5f3a\u5ea6\u7f6e\u4e3a\u6807\u8bb0\u70b9\u5728\u539f\u56fe\u7684\u7070\u5ea6<\/span> if<\/span> (<\/span>intensity <<\/span> graylevelnum)<\/span> \/\/\u5982\u679c\u5c0f\u4e8e256\uff0c\u4fdd\u5b58\u5230\u6bcf\u4e2a\u7070\u5ea6\u7ea7\u5bf9\u5e94\u7684\u5bb9\u5668\u4e2d\uff0c\u5c06\u5176\u89c6\u4e3a\u5c06\u8981\u64cd\u4f5c\u7684\u70b9\uff0c\u6682\u65f6\u7070\u5ea6\u503c\u8bbe\u4e3a-2<\/span> { \n   <\/span> queues[<\/span>intensity]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> i,<\/span>j }<\/span>)<\/span>;<\/span> res_p_cur[<\/span>j]<\/span> =<\/span> INQUEUE;<\/span> }<\/span> }<\/span> }<\/span> int<\/span> ind =<\/span> 0<\/span>;<\/span> for<\/span> (<\/span>;<\/span> ind <<\/span> graylevelnum;<\/span> ind++<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>!<\/span>queues[<\/span>ind]<\/span>.<\/span>empty<\/span>(<\/span>)<\/span>)<\/span> { \n   <\/span> break<\/span>;<\/span> }<\/span>\/\/\u627e\u5230\u7b2c\u4e00\u4e2a\u50a8\u5b58\u7070\u5ea6\u7ea7\u7684\u4e0d\u4e3a\u7a7a\u7684\u5bb9\u5668\u7d22\u5f15<\/span> }<\/span> if<\/span> (<\/span>ind <<\/span> graylevelnum)<\/span>\/\/\u5982\u679c\u5c0f\u4e8e\u6700\u5927\u7070\u5ea6\u7ea7<\/span> { \n   <\/span> int<\/span> lab,<\/span> t;<\/span> while<\/span> (<\/span>true<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>queues[<\/span>ind]<\/span>.<\/span>empty<\/span>(<\/span>)<\/span>)<\/span> { \n   <\/span> for<\/span> (<\/span>;<\/span> ind <<\/span> graylevelnum;<\/span> ind++<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>!<\/span>queues[<\/span>ind]<\/span>.<\/span>empty<\/span>(<\/span>)<\/span>)<\/span> { \n   <\/span> break<\/span>;<\/span> }<\/span>\/\/\u7070\u5ea6\u7ea7\u904d\u5386\u65f6\u4e5f\u4f1a\u51fa\u73b0\u5927\u5c0f\u4e3a0\u7684\u7070\u5ea6\u7ea7\u5bb9\u5668\uff0c\u8df3\u8fc7\u5b83\u627e\u51fa\u4e0b\u4e00\u4e2a\u7d22\u5f15<\/span> }<\/span> }<\/span> if<\/span> (<\/span>ind >=<\/span> graylevelnum)<\/span> { \n   <\/span> break<\/span>;<\/span> }<\/span> point2D cur =<\/span> queues[<\/span>ind]<\/span>.<\/span>front<\/span>(<\/span>)<\/span>;<\/span>\/\/\u8bfb\u53d6\u5f53\u524d\u79cd\u5b50\u70b9<\/span> queues[<\/span>ind]<\/span>.<\/span>pop<\/span>(<\/span>)<\/span>;<\/span>\/\/\u5220\u9664\u6808\u9876\u5143\u7d20<\/span> \/\/std::cout << ind << \" \" << cur.r << \" \" << cur.c << std::endl;<\/span> \/\/mark current pixel.\u83b7\u53d6label\u503c\uff0c\u7528\u4e8e\u6807\u8bb0\uff1f<\/span> lab =<\/span> 0<\/span>;<\/span> t =<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>cur.<\/span>r -<\/span> 1<\/span>,<\/span> cur.<\/span>c)<\/span>;<\/span>\/\/\u6b64\u5904\u56db\u90bb\u57df\u4e0e\u4e0a\u8fb9\u8bb0\u5f55\u56db\u90bb\u57df\u70b9\u5b58\u90bb\u57df\u65f6\u4fdd\u6301\u4e00\u81f4<\/span> if<\/span> (<\/span>t ><\/span> 0<\/span>)<\/span> lab =<\/span> t;<\/span> t =<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>cur.<\/span>r +<\/span> 1<\/span>,<\/span> cur.<\/span>c)<\/span>;<\/span>\/\/\u516c\u5171\u533a\u57df\u4fee\u5efa\u5927\u575d\uff1f<\/span> if<\/span> (<\/span>t ><\/span> 0<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>lab ==<\/span> 0<\/span>)<\/span> { \n   <\/span> lab =<\/span> t;<\/span> }<\/span> else<\/span> if<\/span> (<\/span>lab !=<\/span> t)<\/span> { \n   <\/span> lab =<\/span> SHED;<\/span> }<\/span> }<\/span> t =<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>cur.<\/span>r,<\/span> cur.<\/span>c -<\/span> 1<\/span>)<\/span>;<\/span> if<\/span> (<\/span>t ><\/span> 0<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>lab ==<\/span> 0<\/span>)<\/span> { \n   <\/span> lab =<\/span> t;<\/span> }<\/span> else<\/span> if<\/span> (<\/span>lab !=<\/span> t)<\/span> { \n   <\/span> lab =<\/span> SHED;<\/span> }<\/span> }<\/span> t =<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>cur.<\/span>r,<\/span> cur.<\/span>c +<\/span> 1<\/span>)<\/span>;<\/span> if<\/span> (<\/span>t ><\/span> 0<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>lab ==<\/span> 0<\/span>)<\/span> { \n   <\/span> lab =<\/span> t;<\/span> }<\/span> else<\/span> if<\/span> (<\/span>lab !=<\/span> t)<\/span> { \n   <\/span> lab =<\/span> SHED;<\/span> }<\/span> }<\/span> assert<\/span>(<\/span>lab !=<\/span> 0<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>cur.<\/span>r,<\/span> cur.<\/span>c)<\/span> =<\/span> lab;<\/span>\/\/\u5f53\u524d\u79cd\u5b50\u70b9\u5728\u7ed3\u679c\u56fe\u50cf\u6807\u8bb0\u4e3alab<\/span> \/\/std::cout << \"lab:\" << lab << std::endl;<\/span> if<\/span> (<\/span>lab !=<\/span> SHED)<\/span>\/\/\u5982\u679c\u6807\u8bb0\u4e0d\u662f\u5927\u575d\uff0c\u5e94\u7ee7\u7eed\u8fdb\u884c\u751f\u957f\u6f2b\u6c34==>\u5c06\u539f\u59cb\u6807\u8bb0\u56fe\u4e2d\u672a\u6807\u8bb0\u7684\u70b9\u538b\u5165\u5bb9\u5668\u8fdb\u884c\u6807\u8bb0<\/span> { \n   <\/span> \/\/check 4 neighbors for unmarked pixels.<\/span> int<\/span> r_ind =<\/span> cur.<\/span>r -<\/span> 1<\/span>,<\/span> c_ind =<\/span> cur.<\/span>c;<\/span>\/\/r\u3001c\u8868\u793a\u884c\u4e0e\u5217<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span>\/\/\u672a\u8fdb\u884c\u6807\u8bb0\u7684\u70b9<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span>\/\/ind\u4e3a\u5f53\u524d\u904d\u5386\u7684\u7070\u5ea6\u7ea7<\/span> }<\/span> r_ind =<\/span> cur.<\/span>r +<\/span> 1<\/span>;<\/span> c_ind =<\/span> cur.<\/span>c;<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span> }<\/span> r_ind =<\/span> cur.<\/span>r;<\/span> c_ind =<\/span> cur.<\/span>c -<\/span> 1<\/span>;<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span> }<\/span> r_ind =<\/span> cur.<\/span>r;<\/span> c_ind =<\/span> cur.<\/span>c +<\/span> 1<\/span>;<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span> }<\/span> }<\/span> }<\/span> }<\/span> markers =<\/span> res.<\/span>clone<\/span>(<\/span>)<\/span>;<\/span> }<\/span> <\/code><\/pre>\n

\u52a0\u5165\u68af\u5ea6\u56fe\u8fdb\u884c\u6539\u8fdb\uff1a<\/p>\n

Mat sobel_x,<\/span> sobel_y;<\/span> Sobel<\/span>(<\/span>gray_img,<\/span> sobel_x,<\/span> CV_64F,<\/span> 1<\/span>,<\/span> 0<\/span>,<\/span> 3<\/span>)<\/span>;<\/span> Sobel<\/span>(<\/span>gray_img,<\/span> sobel_y,<\/span> CV_64F,<\/span> 0<\/span>,<\/span> 1<\/span>,<\/span> 3<\/span>)<\/span>;<\/span> convertScaleAbs<\/span>(<\/span>sobel_x,<\/span> sobel_x)<\/span>;<\/span> convertScaleAbs<\/span>(<\/span>sobel_y,<\/span> sobel_y)<\/span>;<\/span> Mat grad =<\/span> sobel_x +<\/span> sobel_y;<\/span> <\/code><\/pre>\n

\u9488\u5bf9\u68af\u5ea6\u56fe\u4e2d\u7684\u80cc\u666f\u70b9\u5e76\u8fdb\u884c\u64cd\u4f5c<\/p>\n

if<\/span> (<\/span>lab !=<\/span> SHED)<\/span>\/\/\u5982\u679c\u6807\u8bb0\u4e0d\u662f\u5927\u575d\uff0c\u5e94\u7ee7\u7eed\u8fdb\u884c\u751f\u957f\u6f2b\u6c34==>\u5c06\u539f\u59cb\u6807\u8bb0\u56fe\u4e2d\u672a\u6807\u8bb0\u7684\u70b9\u538b\u5165\u5bb9\u5668\u8fdb\u884c\u6807\u8bb0<\/span> { \n   <\/span> \/\/check 4 neighbors for unmarked pixels.<\/span> int<\/span> r_ind =<\/span> cur.<\/span>r -<\/span> 1<\/span>,<\/span> c_ind =<\/span> cur.<\/span>c;<\/span>\/\/r\u3001c\u8868\u793a\u884c\u4e0e\u5217<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span>\/\/\u672a\u8fdb\u884c\u6807\u8bb0\u7684\u70b9<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> if<\/span> (<\/span>t !=<\/span> 0<\/span>)<\/span> { \n   <\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span>\/\/ind\u4e3a\u5f53\u524d\u904d\u5386\u7684\u7070\u5ea6\u7ea7<\/span> }<\/span> \/\/queues[t].push({ r_ind,c_ind });<\/span> \/\/res.at<int>(r_ind, c_ind) = INQUEUE;<\/span> \/\/ind = ind < t ? ind : t;\/\/ind\u4e3a\u5f53\u524d\u904d\u5386\u7684\u7070\u5ea6\u7ea7<\/span> }<\/span> r_ind =<\/span> cur.<\/span>r +<\/span> 1<\/span>;<\/span> c_ind =<\/span> cur.<\/span>c;<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> if<\/span> (<\/span>t !=<\/span> 0<\/span>)<\/span> { \n   <\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span>\/\/ind\u4e3a\u5f53\u524d\u904d\u5386\u7684\u7070\u5ea6\u7ea7<\/span> }<\/span> \/*queues[t].push({ r_ind,c_ind }); res.at<int>(r_ind, c_ind) = INQUEUE; ind = ind < t ? ind : t;*\/<\/span> }<\/span> r_ind =<\/span> cur.<\/span>r;<\/span> c_ind =<\/span> cur.<\/span>c -<\/span> 1<\/span>;<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> if<\/span> (<\/span>t !=<\/span> 0<\/span>)<\/span> { \n   <\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span>\/\/ind\u4e3a\u5f53\u524d\u904d\u5386\u7684\u7070\u5ea6\u7ea7<\/span> }<\/span> \/*queues[t].push({ r_ind,c_ind }); res.at<int>(r_ind, c_ind) = INQUEUE; ind = ind < t ? ind : t;*\/<\/span> }<\/span> r_ind =<\/span> cur.<\/span>r;<\/span> c_ind =<\/span> cur.<\/span>c +<\/span> 1<\/span>;<\/span> if<\/span> (<\/span>res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> ==<\/span> 0<\/span>)<\/span> { \n   <\/span> t =<\/span> gray.<\/span>at<\/span><<\/span>uchar ><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span>;<\/span> \/\/std::cout << \"t:\" << t << std::endl;<\/span> if<\/span> (<\/span>t !=<\/span> 0<\/span>)<\/span> { \n   <\/span> queues[<\/span>t]<\/span>.<\/span>push<\/span>(<\/span>{ \n   <\/span> r_ind,<\/span>c_ind }<\/span>)<\/span>;<\/span> res.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>r_ind,<\/span> c_ind)<\/span> =<\/span> INQUEUE;<\/span> ind =<\/span> ind <<\/span> t ?<\/span> ind :<\/span> t;<\/span>\/\/ind\u4e3a\u5f53\u524d\u904d\u5386\u7684\u7070\u5ea6\u7ea7<\/span> }<\/span> \/*queues[t].push({ r_ind,c_ind }); res.at<int>(r_ind, c_ind) = INQUEUE; ind = ind < t ? ind : t;*\/<\/span> }<\/span> }<\/span> <\/code><\/pre>\n

\u4e3b\u7a0b\u5e8f\uff1a<\/p>\n

static<\/span> void<\/span> help<\/span>(<\/span>char<\/span>*<\/span>*<\/span> argv)<\/span> { \n   <\/span> cout <<<\/span> \"\\nThis program demonstrates the famous watershed segmentation algorithm in OpenCV: watershed()\\n\"<\/span> \"Usage:\\n\"<\/span> <<<\/span> argv[<\/span>0<\/span>]<\/span> <<<\/span> \" [image_name -- default is fruits.jpg]\\n\"<\/span> <<<\/span> endl;<\/span> cout <<<\/span> \"Hot keys: \\n\"<\/span> \"\\tESC - quit the program\\n\"<\/span> \"\\tr - restore the original image\\n\"<\/span> \"\\tw or SPACE - run watershed segmentation algorithm\\n\"<\/span> \"\\t\\t(before running it, *roughly* mark the areas to segment on the image)\\n\"<\/span> \"\\t (before that, roughly outline several markers on the image)\\n\"<\/span>;<\/span> }<\/span> Mat markerMask,<\/span> img;<\/span> Point prevPt<\/span>(<\/span>-<\/span>1<\/span>,<\/span> -<\/span>1<\/span>)<\/span>;<\/span> static<\/span> void<\/span> onMouse<\/span>(<\/span>int<\/span> event,<\/span> int<\/span> x,<\/span> int<\/span> y,<\/span> int<\/span> flags,<\/span> void<\/span>*<\/span>)<\/span> { \n   <\/span> if<\/span> (<\/span>x <<\/span> 0<\/span> ||<\/span> x >=<\/span> img.<\/span>cols ||<\/span> y <<\/span> 0<\/span> ||<\/span> y >=<\/span> img.<\/span>rows)<\/span> return<\/span>;<\/span> if<\/span> (<\/span>event ==<\/span> EVENT_LBUTTONUP ||<\/span> !<\/span>(<\/span>flags &<\/span> EVENT_FLAG_LBUTTON)<\/span>)<\/span> prevPt =<\/span> Point<\/span>(<\/span>-<\/span>1<\/span>,<\/span> -<\/span>1<\/span>)<\/span>;<\/span> else<\/span> if<\/span> (<\/span>event ==<\/span> EVENT_LBUTTONDOWN)<\/span> prevPt =<\/span> Point<\/span>(<\/span>x,<\/span> y)<\/span>;<\/span> else<\/span> if<\/span> (<\/span>event ==<\/span> EVENT_MOUSEMOVE &&<\/span> (<\/span>flags &<\/span> EVENT_FLAG_LBUTTON)<\/span>)<\/span> { \n   <\/span> Point pt<\/span>(<\/span>x,<\/span> y)<\/span>;<\/span> if<\/span> (<\/span>prevPt.<\/span>x <<\/span> 0<\/span>)<\/span> prevPt =<\/span> pt;<\/span> line<\/span>(<\/span>markerMask,<\/span> prevPt,<\/span> pt,<\/span> Scalar<\/span>(<\/span>12<\/span>,<\/span>234<\/span>,<\/span>12<\/span>)<\/span>,<\/span> 40<\/span>,<\/span> 8<\/span>,<\/span> 0<\/span>)<\/span>;<\/span> line<\/span>(<\/span>img,<\/span> prevPt,<\/span> pt,<\/span> Scalar<\/span>(<\/span>12<\/span>,<\/span>234<\/span>,<\/span>12<\/span>)<\/span>,<\/span> 40<\/span>,<\/span> 8<\/span>,<\/span> 0<\/span>)<\/span>;<\/span> prevPt =<\/span> pt;<\/span> imshow<\/span>(<\/span>\"image\"<\/span>,<\/span> img)<\/span>;<\/span> }<\/span> }<\/span> int<\/span> main<\/span>(<\/span>int<\/span> argc,<\/span> char<\/span>*<\/span>*<\/span> argv)<\/span> { \n   <\/span> cv::<\/span>CommandLineParser parser<\/span>(<\/span>argc,<\/span> argv,<\/span> \"{help h | | }{ @input | fruits.jpg | }\"<\/span>)<\/span>;<\/span> if<\/span> (<\/span>parser.<\/span>has<\/span>(<\/span>\"help\"<\/span>)<\/span>)<\/span> { \n   <\/span> help<\/span>(<\/span>argv)<\/span>;<\/span> return<\/span> 0<\/span>;<\/span> }<\/span> \/\/string filename = samples::findFile(parser.get<string>(\"@input\"));<\/span> Mat img0 =<\/span> imread<\/span>(<\/span>\"...\"<\/span>)<\/span>,<\/span> imgGray;<\/span> if<\/span> (<\/span>img0.<\/span>empty<\/span>(<\/span>)<\/span>)<\/span> { \n   <\/span> cout <<<\/span> \"Couldn't open image \"<\/span>;<\/span> help<\/span>(<\/span>argv)<\/span>;<\/span> return<\/span> 0<\/span>;<\/span> }<\/span> help<\/span>(<\/span>argv)<\/span>;<\/span> \/\/img0 = img0(Rect(1000, 1000, 800, 800));<\/span> namedWindow<\/span>(<\/span>\"image\"<\/span>,<\/span> WINDOW_NORMAL)<\/span>;<\/span> img0.<\/span>copyTo<\/span>(<\/span>img)<\/span>;<\/span> cvtColor<\/span>(<\/span>img,<\/span> markerMask,<\/span> COLOR_BGR2GRAY)<\/span>;<\/span> cvtColor<\/span>(<\/span>markerMask,<\/span> imgGray,<\/span> COLOR_GRAY2BGR)<\/span>;<\/span> markerMask =<\/span> Scalar<\/span>::<\/span>all<\/span>(<\/span>0<\/span>)<\/span>;<\/span> imshow<\/span>(<\/span>\"image\"<\/span>,<\/span> img)<\/span>;<\/span> setMouseCallback<\/span>(<\/span>\"image\"<\/span>,<\/span> onMouse,<\/span> 0<\/span>)<\/span>;<\/span> for<\/span> (<\/span>;<\/span>;<\/span>)<\/span> { \n   <\/span> char<\/span> c =<\/span> (<\/span>char<\/span>)<\/span>waitKey<\/span>(<\/span>0<\/span>)<\/span>;<\/span> if<\/span> (<\/span>c ==<\/span> 27<\/span>)<\/span> break<\/span>;<\/span> if<\/span> (<\/span>c ==<\/span> 'r'<\/span>)<\/span> { \n   <\/span> markerMask =<\/span> Scalar<\/span>::<\/span>all<\/span>(<\/span>0<\/span>)<\/span>;<\/span> img0.<\/span>copyTo<\/span>(<\/span>img)<\/span>;<\/span> namedWindow<\/span>(<\/span>\"image\"<\/span>,<\/span> WINDOW_NORMAL)<\/span>;<\/span> imshow<\/span>(<\/span>\"image\"<\/span>,<\/span> img)<\/span>;<\/span> }<\/span> if<\/span> (<\/span>c ==<\/span> 'w'<\/span> ||<\/span> c ==<\/span> ' '<\/span>)<\/span> { \n   <\/span> int<\/span> i,<\/span> j,<\/span> compCount =<\/span> 0<\/span>;<\/span> vector<<\/span>vector<<\/span>Point><\/span> ><\/span> contours;<\/span> vector<<\/span>Vec4i><\/span> hierarchy;<\/span> findContours<\/span>(<\/span>markerMask,<\/span> contours,<\/span> hierarchy,<\/span> RETR_CCOMP,<\/span> CHAIN_APPROX_SIMPLE)<\/span>;<\/span> if<\/span> (<\/span>contours.<\/span>empty<\/span>(<\/span>)<\/span>)<\/span> continue<\/span>;<\/span> Mat markers<\/span>(<\/span>markerMask.<\/span>size<\/span>(<\/span>)<\/span>,<\/span> CV_32S)<\/span>;<\/span> markers =<\/span> Scalar<\/span>::<\/span>all<\/span>(<\/span>0<\/span>)<\/span>;<\/span> int<\/span> idx =<\/span> 0<\/span>;<\/span> for<\/span> (<\/span>;<\/span> idx >=<\/span> 0<\/span>;<\/span> idx =<\/span> hierarchy[<\/span>idx]<\/span>[<\/span>0<\/span>]<\/span>,<\/span> compCount++<\/span>)<\/span> drawContours<\/span>(<\/span>markers,<\/span> contours,<\/span> idx,<\/span> Scalar<\/span>::<\/span>all<\/span>(<\/span>compCount +<\/span> 1<\/span>)<\/span>,<\/span> -<\/span>1<\/span>,<\/span> 8<\/span>,<\/span> hierarchy,<\/span> INT_MAX)<\/span>;<\/span> if<\/span> (<\/span>compCount ==<\/span> 0<\/span>)<\/span> continue<\/span>;<\/span> vector<<\/span>Vec3b><\/span> colorTab;<\/span> for<\/span> (<\/span>i =<\/span> 0<\/span>;<\/span> i <<\/span> compCount;<\/span> i++<\/span>)<\/span> { \n   <\/span> int<\/span> b =<\/span> theRNG<\/span>(<\/span>)<\/span>.<\/span>uniform<\/span>(<\/span>0<\/span>,<\/span> 255<\/span>)<\/span>;<\/span> int<\/span> g =<\/span> theRNG<\/span>(<\/span>)<\/span>.<\/span>uniform<\/span>(<\/span>0<\/span>,<\/span> 255<\/span>)<\/span>;<\/span> int<\/span> r =<\/span> theRNG<\/span>(<\/span>)<\/span>.<\/span>uniform<\/span>(<\/span>0<\/span>,<\/span> 255<\/span>)<\/span>;<\/span> colorTab.<\/span>push_back<\/span>(<\/span>Vec3b<\/span>(<\/span>(<\/span>uchar)<\/span>b,<\/span> (<\/span>uchar)<\/span>g,<\/span> (<\/span>uchar)<\/span>r)<\/span>)<\/span>;<\/span> }<\/span> double<\/span> t =<\/span> (<\/span>double<\/span>)<\/span>getTickCount<\/span>(<\/span>)<\/span>;<\/span> medianBlur<\/span>(<\/span>img0,<\/span> img0,<\/span> 7<\/span>)<\/span>;<\/span> \/\/watershed(img0, markers);<\/span> \/\/myWatered(img0, markers);<\/span> \/\/myWaterThred(img0, markers);<\/span> WaterShed_<\/span>(<\/span>img0,<\/span> markers)<\/span>;<\/span> \/\/imgseg::watershedColor(img0, markers);<\/span> \/\/imgseg::vfWatershed(img0, markers);<\/span> t =<\/span> (<\/span>double<\/span>)<\/span>getTickCount<\/span>(<\/span>)<\/span> -<\/span> t;<\/span> printf<\/span>(<\/span>\"execution time = %gms\\n\"<\/span>,<\/span> t*<\/span>1000.<\/span> \/<\/span> getTickFrequency<\/span>(<\/span>)<\/span>)<\/span>;<\/span> Mat wshed<\/span>(<\/span>markers.<\/span>size<\/span>(<\/span>)<\/span>,<\/span> CV_8UC3)<\/span>;<\/span> \/\/ paint the watershed image<\/span> for<\/span> (<\/span>i =<\/span> 0<\/span>;<\/span> i <<\/span> markers.<\/span>rows;<\/span> i++<\/span>)<\/span> for<\/span> (<\/span>j =<\/span> 0<\/span>;<\/span> j <<\/span> markers.<\/span>cols;<\/span> j++<\/span>)<\/span> { \n   <\/span> int<\/span> index =<\/span> markers.<\/span>at<\/span><<\/span>int<\/span>><\/span><\/span><\/span>(<\/span>i,<\/span> j)<\/span>;<\/span> if<\/span> (<\/span>index ==<\/span> -<\/span>1<\/span>)<\/span> wshed.<\/span>at<\/span><<\/span>Vec3b><\/span><\/span><\/span>(<\/span>i,<\/span> j)<\/span> =<\/span> Vec3b<\/span>(<\/span>255<\/span>,<\/span> 255<\/span>,<\/span> 255<\/span>)<\/span>;<\/span> else<\/span> if<\/span> (<\/span>index <=<\/span> 0<\/span> ||<\/span> index ><\/span> compCount)<\/span> wshed.<\/span>at<\/span><<\/span>Vec3b><\/span><\/span><\/span>(<\/span>i,<\/span> j)<\/span> =<\/span> Vec3b<\/span>(<\/span>0<\/span>,<\/span> 0<\/span>,<\/span> 0<\/span>)<\/span>;<\/span> else<\/span> wshed.<\/span>at<\/span><<\/span>Vec3b><\/span><\/span><\/span>(<\/span>i,<\/span> j)<\/span> =<\/span> colorTab[<\/span>index -<\/span> 1<\/span>]<\/span>;<\/span> }<\/span> wshed =<\/span> wshed *<\/span> 0.5<\/span> +<\/span> imgGray *<\/span> 0.5<\/span>;<\/span> namedWindow<\/span>(<\/span>\"watershed transform\"<\/span>,<\/span> WINDOW_NORMAL)<\/span>;<\/span> imshow<\/span>(<\/span>\"watershed transform\"<\/span>,<\/span> wshed)<\/span>;<\/span> }<\/span> }<\/span> return<\/span> 0<\/span>;<\/span> }<\/span> <\/code><\/pre>\n

\u4e3b\u8981\u53c2\u8003\uff1a\u51fa\u81ea\u2014\u4f1a\u98de\u7684\u5434\u514b<\/p>\n","protected":false},"excerpt":{"rendered":"\u5206\u6c34\u5cad\u7b97\u6cd5\u5206\u6790_\u5206\u6c34\u5cad\u5206\u5272\u7b97\u6cd5\u7684\u6b65\u9aa41.\u5206\u6c34\u5cad\u5b9e\u73b0\u539f\u7406\u5206\u6c34\u5cad\u7b97\u6cd5\u5e38\u7528\u4e8e\u76ee\u6807\u5206\u5272\u7814\u7a76\uff0c\u5176\u5c06\u56fe\u50cf\u4ee5\u7070\u5ea6\u4e3a\u53c2\u8003\u53ef\u89c6\u5316\u4e3a\u4e00\u79cd\u62d3\u6251...","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"_links":{"self":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/posts\/5146"}],"collection":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/comments?post=5146"}],"version-history":[{"count":0,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/posts\/5146\/revisions"}],"wp:attachment":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/media?parent=5146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/categories?post=5146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/tags?post=5146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}