第五章 - 图像形态学 - 基于图像金字塔的图像分割(cvPyrSegmentation)
本例程涉及到幾個數據結構及方法,CvMemStorage、cvPyrSegmentation()、CvConnectedComp、cvGetSeqElem().
?
CvMemStorage
CvMemStorage
Growing memory storage
typedef struct CvMemStorage
{
struct CvMemBlock* bottom;/* first allocated block */
struct CvMemBlock* top; /* the current memory block - top of the stack */
struct CvMemStorage* parent; /* borrows new blocks from */
int block_size; /* block size */
int free_space; /* free space in the top block (in bytes) */
} CvMemStorage;
內存存儲器是一個可用來存儲諸如序列,輪廓,圖形,子劃分等動態增長數據結構的底層結構。它是由一系列以同等大小的內存塊構成,呈列表型 ---bottom 域指的是列首,top 域指的是當前指向的塊但未必是列尾.在bottom和top之間所有的塊(包括bottom, 不包括top)被完全占據了空間;在 top和列尾之間所有的塊(包括塊尾,不包括top)則是空的;而top塊本身則被占據了部分空間 -- free_space 指的是top塊剩馀的空字節數。
新分配的內存緩沖區(或顯式的通過 cvMemStorageAlloc 函數分配,或隱式的通過 cvSeqPush, cvGraphAddEdge等高級函數分配)總是起始于當前塊(即top塊)的剩馀那部分,如果剩馀那部分能滿足要求(夠分配的大小)。分配后,free_space 就減少了新分配的那部分內存大小,外加一些用來保存適當列型的附加大小。當top塊的剩馀空間無法滿足被分配的塊(緩沖區)大小時,top塊的下一個存儲塊被置為當前塊(新的top塊) -- free_space 被置為先前分配的整個塊的大小。
如果已經不存在空的存儲塊(即:top塊已是列尾),則必須再分配一個新的塊(或從parent那繼承,見 cvCreateChildMemStorage)并將該塊加到列尾上去。于是,存儲器(memory storage)就如同棧(Stack)那樣, bottom指向棧底,(top, free_space)對指向棧頂。棧頂可通過 cvSaveMemStoragePos保存,通過 cvRestoreMemStoragePos 恢復指向, 通過 cvClearStorage 重置。
?
cvPyrSegmentation
PyrSegmentation
用金字塔實現圖像分割
void cvPyrSegmentation( IplImage* src, IplImage* dst,
CvMemStorage* storage, CvSeq** comp,
int level, double threshold1, double threshold2 );
src
輸入圖像.
dst
輸出圖像.
storage
Storage: 存儲連通部件的序列結果
comp
分割部件的輸出序列指針 components.
level
建立金字塔的最大層數
threshold1
建立連接的錯誤閾值
threshold2
分割簇的錯誤閾值
函數 cvPyrSegmentation 實現了金字塔方法的圖像分割。金字塔建立到 level 指定的最大層數。如果 p(c(a),c(b))<threshold1,則在層 i 的象素點 a 和它的相鄰層的父親象素 b 之間的連接被建立起來,
定義好連接部件后,它們被加入到某些簇中。如果p(c(A),c(B))<threshold2,則任何兩個分割 A 和 B 屬于同一簇。
如果輸入圖像只有一個通道,那么
p(c1,c2)=|c1-c2|.
如果輸入圖像有單個通道(紅、綠、蘭),那幺
p(c1,c2)=0,3·(c1r-c2r)+0,59·(c1g-c2g)+0,11·(c1b-c2b) .
每一個簇可以有多個連接部件。圖像 src 和 dst 應該是 8-比特、單通道 或 3-通道圖像,且大小一樣
?
CvConnectedComp
CvConnectedComp
連接部件、連接圖像各部分
typedef struct CvConnectedComp
{
double area; /* 連通域的面積 */
float value; /* 分割域的灰度縮放值 */
CvRect rect; /* 分割域的 ROI */
} CvConnectedComp;
cvGetSeqElem
openCV里面的一個函數
作用:直接訪問序列中的元素
格式:char * cvGetSeqElem(seq,index)
用法:
1. 首先返回的是char類型的指針,當然也可以利用強制類型轉換,轉換為序列中實際存儲的數據類型
例如:for(int i = 0; i<seq ->total;++i)
{
??????? CvPoint *p = (CvPoint *)cvGetSeqElem(seq,i);
}
2. seq是需要檢測的序列,而index顧名思義是元素在序列中的索引,即第幾個元素
?
/*整體思路是先分割圖像,形成各部分輪廓,然后連接圖像各部分*/
?
[cpp] view plaincopy
/*結果*/
總結
以上是生活随笔為你收集整理的第五章 - 图像形态学 - 基于图像金字塔的图像分割(cvPyrSegmentation)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: M427手动双面改自动双面
- 下一篇: java经典sql笔试题