【深度学习】基于区域生长的图像分割算法!
圖像分割的目的是將圖像劃分為多個不同的區域,所以我們可以直接從尋找圖像中的區域來設計分割算法。區域生長正是一種基于區域尋找的傳統圖像分割算法。
區域生長基本原理
區域生長(Region Growth)算法是一種基于區域的傳統圖像分割算法。區域生長可以根據預先定義的生長規則將像素或者小區域不斷組合為更大區域的過程。具體地,區域生長是從一組初始種子點出發,通過預先定義的區域生長規則,將與種子點性質相似的領域像素不斷添加到每個種子點上,并且滿足區域生長的終止條件時形成最終生長區域的過程。假設為待分割的輸入圖像陣列,為一組種子點陣列,其中種子點處位置為1,其他位置為0,并且假設和具有相同的尺寸。表示在每個像素點的相關屬性。基于8連接的區域生長算法的流程描述如下:
在種子陣列中找到所有的連通分量,將每個連通分量腐蝕為一個像素,并將腐蝕成功的像素標記為1,其他像素標記為0.
在坐標形成圖像,如果輸入圖像在該點坐標處滿足給定的屬性,則令,否則令。
將中為8連通種子點的所有為1的點添加到s中的每個種子點中直至滿足生長結束條件。
最后在不同區域標記出每個連通分量形成最終的分割圖像。
下面我們通過一個簡單的計算例子來更加直觀地理解區域生長算法。
假設有如圖所示的5×5圖像陣列,選定陣列中最大值9作為初始種子點(圖中橙色像素塊),區域生長的像素閾值為2,現按照區域生長算法對該圖像陣列進行分割。
按照區域生長閾值2,取值范圍為[7,11],生長后的區域像素均值為7.8。第一次生長效果如圖2所示,藍色區域即第一次生長后的區域。
第一次生長后的區域均值為7.8,按照生長閾值為2,第二次生長的像素取值范圍應為[5.8,9.8],如圖3所示,綠色部分為第二次生長的區域結果。
第二次生長后的區域均值為7.1,按照生長閾值為2,第三次生長的像素取值范圍應為[5.1,9.1],如圖4所示,黃色部分為第三次生長的區域結果。
第三次生長后的區域均值為6.9,按照生長閾值為2,第三次生長的像素取值范圍應為[4.9,8.9],周邊已沒有滿足繼續生長的像素點,到此我們停止生長。將生長后的區域標記為1,其他區域標記為0,最終的分割區域如圖5所示。
區域生長分割示例
給定一張NBA球星科比的圖像(如圖6所示),我們嘗試實現一個區域生長圖像分割算法來對該圖像進行前景與背景的分割。
現嘗試基于C++代碼來實現一個區域生長分割算法。按照前述基于8連接的區域生長算法的流程描述,實現過程如下代碼所示。
#include <iostream> #include <opencv2/opencv.hpp>using namespace std; using namespace cv; // 定義區域生長分割算法 bool RegionGrowing(Mat img, Mat& result, Point2i seed, int threshold) {// 將圖像全部設置為黑result = Mat::zeros(img.size(), CV_8UC1); // 設置種子點范圍條件if (seed.x < 0 || seed.y < 0 || seed.y > img.rows - 1 || seed.x > img.cols - 1) {return false;}// 種子點集vector<Point2i> seeds; // 壓入初始種子點seeds.push_back(seed); // 種子點設置為白result.ptr<uchar>(seed.y)[seed.x] = 255; // 8連接生長方向int growDirections[8][2] = { {-1,-1}, {0,-1}, {1,-1}, {-1,0}, {1,0}, {-1,1}, {0,1}, {1,1} }; // 開始生長while (!seeds.empty()) {// 取出一個種子點作為現在循環的初始種子點Point2i seed_current = seeds.back();seeds.pop_back();// 遍歷各生長方向的鄰點for (int i = 0; i < 8; i++) {Point2i neighborPoint = { seed_current.x + growDirections[i][0], seed_current.y + growDirections[i][1] }; // 鄰點if (neighborPoint.x < 0 || neighborPoint.y < 0 || neighborPoint.x > img.cols - 1 || neighborPoint.y > img.rows - 1) { // 鄰點超出范圍continue;}if ((result.ptr<uchar>(neighborPoint.y)[neighborPoint.x] == 0) && abs(img.ptr<uchar>(neighborPoint.y)[neighborPoint.x] - img.ptr<uchar>(seed.y)[seed.x]) < threshold) {// 設置為種子點result.ptr<uchar>(neighborPoint.y)[neighborPoint.x] = 255; // 設置為白色seeds.push_back(neighborPoint); // 壓入種子集}}}return true; }基于上述代碼分割后的圖像如圖7所示。可以看到,區域生長算法基本上能分割出目標區域,但因為圖像本身復雜性,在分割效果上仍有待提升的地方。
參考資料:
岡薩雷斯 數字圖像處理
https://gy23333.github.io/2020/01/18/%E5%9F%BA%E4%BA%8E%E5%8C%BA%E5%9F%9F%E7%9A%84%E5%9B%BE%E5%83%8F%E5%88%86%E5%89%B2%E2%80%94%E2%80%94%E5%8C%BA%E5%9F%9F%E7%94%9F%E9%95%BF/
往期精彩回顧適合初學者入門人工智能的路線及資料下載(圖文+視頻)機器學習入門系列下載中國大學慕課《機器學習》(黃海廣主講)機器學習及深度學習筆記等資料打印《統計學習方法》的代碼復現專輯 AI基礎下載機器學習交流qq群955171419,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【深度学习】基于区域生长的图像分割算法!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Maven父子结构的项目依赖使用以及打包
- 下一篇: 【Python】分享几个好用到爆的Pyt