日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图像细化

發布時間:2025/3/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像细化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?在我們進行圖像處理的時候,有可能需要對圖像進行細化,提取出圖像的骨架信息,進行更加有效的分析。

???? 圖像細化(Image Thinning),一般指二值圖像的骨架化(Image Skeletonization) 的一種操作運算。

???? 所謂的細化就是經過一層層的剝離,從原來的圖中去掉一些點,但仍要保持原來的形狀,直到得到圖像的骨架。骨架,可以理解為圖象的中軸。

???? 好的細化算法一定要滿足:
  • 收斂性;
  • 保證細化后細線的連通性;
  • 保持原圖的基本形狀;
  • 減少筆畫相交處的畸變;
  • 細化結果是原圖像的中心線;
  • 細化的快速性和迭代次數少;

????這里,我們對“Zhang并行快速細化算法”進行了實現(注意,該算法為并行算法,而我們在實現過程中并沒有并行化處理,所以,效率并沒有達到最好)。

????參考資料

  • 細化算法
  • 論文 A fast parallel algorithm for thinning digital patterns [cpp]?view plaincopy
  • #include?<opencv2/opencv.hpp>??
  • #include?<opencv2/core/core.hpp>??
  • #include?<iostream>??
  • #include?<vector>??
  • ??
  • ??
  • /**?
  • ?*?@brief?對輸入圖像進行細化?
  • ?*?@param?src為輸入圖像,用cvThreshold函數處理過的8位灰度圖像格式,元素中只有0與1,1代表有元素,0代表為空白?
  • ?*?@param?maxIterations限制迭代次數,如果不進行限制,默認為-1,代表不限制迭代次數,直到獲得最終結果?
  • ?*?@return?為對src細化后的輸出圖像,格式與src格式相同,元素中只有0與1,1代表有元素,0代表為空白?
  • ?*/??
  • cv::Mat?thinImage(const?cv::Mat?&?src,?const?int?maxIterations?=?-1)??
  • {??
  • ????assert(src.type()?==?CV_8UC1);??
  • ????cv::Mat?dst;??
  • ????int?width??=?src.cols;??
  • ????int?height?=?src.rows;??
  • ????src.copyTo(dst);??
  • ????int?count?=?0;??//記錄迭代次數??
  • ????while?(true)??
  • ????{??
  • ????????count++;??
  • ????????if?(maxIterations?!=?-1?&&?count?>?maxIterations)?//限制次數并且迭代次數到達??
  • ????????????break;??
  • ????????std::vector<uchar?*>?mFlag;?//用于標記需要刪除的點??
  • ????????//對點標記??
  • ????????for?(int?i?=?0;?i?<?height?;++i)??
  • ????????{??
  • ????????????uchar?*?p?=?dst.ptr<uchar>(i);??
  • ????????????for?(int?j?=?0;?j?<?width;?++j)??
  • ????????????{??
  • ????????????????//如果滿足四個條件,進行標記??
  • ????????????????//??p9?p2?p3??
  • ????????????????//??p8?p1?p4??
  • ????????????????//??p7?p6?p5??
  • ????????????????uchar?p1?=?p[j];??
  • ????????????????if?(p1?!=?1)?continue;??
  • ????????????????uchar?p4?=?(j?==?width?-?1)???0?:?*(p?+?j?+?1);??
  • ????????????????uchar?p8?=?(j?==?0)???0?:?*(p?+?j?-?1);??
  • ????????????????uchar?p2?=?(i?==?0)???0?:?*(p?-?dst.step?+?j);??
  • ????????????????uchar?p3?=?(i?==?0?||?j?==?width?-?1)???0?:?*(p?-?dst.step?+?j?+?1);??
  • ????????????????uchar?p9?=?(i?==?0?||?j?==?0)???0?:?*(p?-?dst.step?+?j?-?1);??
  • ????????????????uchar?p6?=?(i?==?height?-?1)???0?:?*(p?+?dst.step?+?j);??
  • ????????????????uchar?p5?=?(i?==?height?-?1?||?j?==?width?-?1)???0?:?*(p?+?dst.step?+?j?+?1);??
  • ????????????????uchar?p7?=?(i?==?height?-?1?||?j?==?0)???0?:?*(p?+?dst.step?+?j?-?1);??
  • ????????????????if?((p2?+?p3?+?p4?+?p5?+?p6?+?p7?+?p8?+?p9)?>=?2?&&?(p2?+?p3?+?p4?+?p5?+?p6?+?p7?+?p8?+?p9)?<=?6)??
  • ????????????????{??
  • ????????????????????int?ap?=?0;??
  • ????????????????????if?(p2?==?0?&&?p3?==?1)?++ap;??
  • ????????????????????if?(p3?==?0?&&?p4?==?1)?++ap;??
  • ????????????????????if?(p4?==?0?&&?p5?==?1)?++ap;??
  • ????????????????????if?(p5?==?0?&&?p6?==?1)?++ap;??
  • ????????????????????if?(p6?==?0?&&?p7?==?1)?++ap;??
  • ????????????????????if?(p7?==?0?&&?p8?==?1)?++ap;??
  • ????????????????????if?(p8?==?0?&&?p9?==?1)?++ap;??
  • ????????????????????if?(p9?==?0?&&?p2?==?1)?++ap;??
  • ??
  • ????????????????????if?(ap?==?1?&&?p2?*?p4?*?p6?==?0?&&?p4?*?p6?*?p8?==?0)??
  • ????????????????????{??
  • ????????????????????????//標記??
  • ????????????????????????mFlag.push_back(p+j);??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//將標記的點刪除??
  • ????????for?(std::vector<uchar?*>::iterator?i?=?mFlag.begin();?i?!=?mFlag.end();?++i)??
  • ????????{??
  • ????????????**i?=?0;??
  • ????????}??
  • ??
  • ????????//直到沒有點滿足,算法結束??
  • ????????if?(mFlag.empty())??
  • ????????{??
  • ????????????break;??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????mFlag.clear();//將mFlag清空??
  • ????????}??
  • ??
  • ????????//對點標記??
  • ????????for?(int?i?=?0;?i?<?height;?++i)??
  • ????????{??
  • ????????????uchar?*?p?=?dst.ptr<uchar>(i);??
  • ????????????for?(int?j?=?0;?j?<?width;?++j)??
  • ????????????{??
  • ????????????????//如果滿足四個條件,進行標記??
  • ????????????????//??p9?p2?p3??
  • ????????????????//??p8?p1?p4??
  • ????????????????//??p7?p6?p5??
  • ????????????????uchar?p1?=?p[j];??
  • ????????????????if?(p1?!=?1)?continue;??
  • ????????????????uchar?p4?=?(j?==?width?-?1)???0?:?*(p?+?j?+?1);??
  • ????????????????uchar?p8?=?(j?==?0)???0?:?*(p?+?j?-?1);??
  • ????????????????uchar?p2?=?(i?==?0)???0?:?*(p?-?dst.step?+?j);??
  • ????????????????uchar?p3?=?(i?==?0?||?j?==?width?-?1)???0?:?*(p?-?dst.step?+?j?+?1);??
  • ????????????????uchar?p9?=?(i?==?0?||?j?==?0)???0?:?*(p?-?dst.step?+?j?-?1);??
  • ????????????????uchar?p6?=?(i?==?height?-?1)???0?:?*(p?+?dst.step?+?j);??
  • ????????????????uchar?p5?=?(i?==?height?-?1?||?j?==?width?-?1)???0?:?*(p?+?dst.step?+?j?+?1);??
  • ????????????????uchar?p7?=?(i?==?height?-?1?||?j?==?0)???0?:?*(p?+?dst.step?+?j?-?1);??
  • ??
  • ????????????????if?((p2?+?p3?+?p4?+?p5?+?p6?+?p7?+?p8?+?p9)?>=?2?&&?(p2?+?p3?+?p4?+?p5?+?p6?+?p7?+?p8?+?p9)?<=?6)??
  • ????????????????{??
  • ????????????????????int?ap?=?0;??
  • ????????????????????if?(p2?==?0?&&?p3?==?1)?++ap;??
  • ????????????????????if?(p3?==?0?&&?p4?==?1)?++ap;??
  • ????????????????????if?(p4?==?0?&&?p5?==?1)?++ap;??
  • ????????????????????if?(p5?==?0?&&?p6?==?1)?++ap;??
  • ????????????????????if?(p6?==?0?&&?p7?==?1)?++ap;??
  • ????????????????????if?(p7?==?0?&&?p8?==?1)?++ap;??
  • ????????????????????if?(p8?==?0?&&?p9?==?1)?++ap;??
  • ????????????????????if?(p9?==?0?&&?p2?==?1)?++ap;??
  • ??
  • ????????????????????if?(ap?==?1?&&?p2?*?p4?*?p8?==?0?&&?p2?*?p6?*?p8?==?0)??
  • ????????????????????{??
  • ????????????????????????//標記??
  • ????????????????????????mFlag.push_back(p+j);??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//將標記的點刪除??
  • ????????for?(std::vector<uchar?*>::iterator?i?=?mFlag.begin();?i?!=?mFlag.end();?++i)??
  • ????????{??
  • ????????????**i?=?0;??
  • ????????}??
  • ??
  • ????????//直到沒有點滿足,算法結束??
  • ????????if?(mFlag.empty())??
  • ????????{??
  • ????????????break;??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????mFlag.clear();//將mFlag清空??
  • ????????}??
  • ????}??
  • ????return?dst;??
  • }??
  • ??
  • ??
  • int?main(int?argc,?char*argv[])??
  • {??
  • ????//獲取圖像??
  • ????if?(argc?!=?2)??
  • ????{??
  • ????????std::cout?<<?"參數個數錯誤!"?<<?std::endl;??
  • ????????return?-1;??
  • ????}??
  • ????cv::Mat?src?=?cv::imread(argv[1],?cv::IMREAD_GRAYSCALE);??
  • ????if?(src.empty())??
  • ????{??
  • ????????std::cout?<<?"讀取文件失敗!"?<<?std::endl;??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????//將原圖像轉換為二值圖像??
  • ????cv::threshold(src,?src,?128,?1,?cv::THRESH_BINARY);??
  • ????//圖像細化??
  • ????cv::Mat?dst?=?thinImage(src);??
  • ????//顯示圖像??
  • ????dst?=?dst?*?255;??
  • ????cv::namedWindow("src1",?CV_WINDOW_AUTOSIZE);??
  • ????cv::namedWindow("dst1",?CV_WINDOW_AUTOSIZE);??
  • ????cv::imshow("src1",?src);??
  • ????cv::imshow("dst1",?dst);??
  • ????cv::waitKey(0);??
  • }??
  • 運行效果

    1原圖像


    2.運行效果



總結

以上是生活随笔為你收集整理的图像细化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。