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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

第五章 - 图像形态学 - 基于图像金字塔的图像分割(cvPyrSegmentation)

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第五章 - 图像形态学 - 基于图像金字塔的图像分割(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
  • #include?<cv.h>??
  • #include?<stdio.h>??
  • #include?<highgui.h>??
  • ??
  • void?f(?IplImage*?src,?IplImage*?dst?);??
  • ??
  • int?main(int?argc,?char**?argv?)??
  • {??
  • ????cvNamedWindow(?argv[1],?1?);??//create?a?named?window??
  • ????IplImage*?src?=?cvLoadImage(?argv[1]?);?//load?the?image??
  • ????if(?!src?)???
  • ????{??
  • ????????printf(?"Couldn't?seem?to?open?%s",?argv[1]?);??//if?not?exist?the?image??
  • ????????return?-1;??
  • ????}??
  • ????IplImage*?dst?=?cvCreateImage(?cvGetSize(?src?),?src->depth,?src->nChannels?);??//create?the?image?head?and?allocate?the?data??
  • ????f(?src,?dst?);?//call?the?function?f??
  • ??
  • ????cvShowImage(?argv[1],?dst?);??//show?the?image?in?the?named?window??
  • ????while(?1?)?//wait?until?the?user?hits?the?"ESC"?key??
  • ????{??
  • ????????if(?cvWaitKey(?100?)?==?27?)??
  • ????????????break;??
  • ????}??
  • ??
  • ????cvDestroyWindow(?argv[1]?);?//clean?up?the?window?and?release?the?memory??
  • ????cvReleaseImage(?&src?);?//the?parameter?is?a?point??
  • ????cvReleaseImage(?&dst?);??
  • ??
  • ????return?0;??
  • }??
  • ??
  • void?f(?IplImage*?src,?IplImage*?dst?)??
  • {??
  • ????CvMemStorage*?storage?=?cvCreateMemStorage(?0?);??//apply?the?memory?storage?for?the?growing?image?data?structure??
  • ????CvSeq*?comp?=?NULL;??//growable?sequence?of?the?elements??
  • ??????
  • ????cvPyrSegmentation(?src,?dst,?storage,?&comp,?4,?200,?50?);??//image?segmentation?and?store?the?outline?sequence??
  • ????int?n_comp?=?comp->total;??//total?number?of?elements??
  • ??
  • ????for(?int?i?=?0;?i?<?n_comp;?++i?)??
  • ????{??
  • ????????CvConnectedComp*?cc?=?(?CvConnectedComp*?)cvGetSeqElem(?comp,?i?);??//connect?the?image??
  • ????????//??
  • ????}??
  • ????cvReleaseMemStorage(?&storage?);??
  • }??

  • /*結果*/

    總結

    以上是生活随笔為你收集整理的第五章 - 图像形态学 - 基于图像金字塔的图像分割(cvPyrSegmentation)的全部內容,希望文章能夠幫你解決所遇到的問題。

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