如何加快動態輪廓(Active contour)的運算效率? (附程式碼) |
答題得分者是:plihui
|
skybow
一般會員 發表:10 回覆:10 積分:4 註冊:2004-04-30 發送簡訊給我 |
請教各位前輩,以下是我寫的動態輪廓演算法中, 用於計算輪廓上各點的8鄰近能量值的基礎部分~ 此法用於萃取影像物體邊緣(segmentation),常用於醫學影像找出器官的輪廓~ 我使用的初始輪廓是80點的橢圓形, 疊代次數10次,鄰近區域是3x3的範圍 但是由於程式功力有限,一值無法在33ms內完成10次的疊代, (即使目前使用Celeron 2.6G處理器也需要62ms!! ) 以致無法用於即時影像處理,不知各位是否有一些小技巧可以增進程式效率? 謝謝! 註一:本程式有使用Mil; 以下的核心公式主要就是計算輪廓上每一點的八鄰近各點的3個能量,共80點,重複10次=> 80點x9格x10次=7200次; 但是我這3個能量計算式就耗掉許多時間~ 不知是否有更快的寫法?
註二: initial_contour_x[80],initial_contour_y[80]是在別的函數定義的,指的是初始輪廓橢圓的X,Y座標點資料.
#define SNAKE_DIM 3 float Image_Intensity_of_nbpoint_I[SNAKE_DIM][SNAKE_DIM],//外部能量 Cont_of_nbpoint_I[SNAKE_DIM][SNAKE_DIM],//內部能量 Curv_of_nbpoint_I[SNAKE_DIM][SNAKE_DIM],//內部能量 avgdis_contour;//輪廓上每一點距離之平均 long ImagePitch; unsigned char *ImageDataPtr,*NowImageDataPtr; MbufInquire(MilBuffer2Edge,M_HOST_ADDRESS,&ImageDataPtr);//取得影像起始位置 MbufInquire(MilBuffer2Edge,M_PITCH,&ImagePitch);//取得影像pitch //疊代10次 for(int a=0;a<10;a ) { /*Start--of--SNAKE*/ for(int i=0;i<80;i ) //依序共80點 { for(int m=0;m<=2;m ) //3x3的範圍 { for(int n=0;n<=2;n ) { Cont_of_nbpoint_I[m][n]=fabs(avgdis_contour-float(sqrt(pow(double((initial_contour_x[i]-1 m)-initial_contour_x[i-1]),2.0) pow(double((initial_contour_y[i]-1 n)-initial_contour_y[i-1]),2.0)))); Curv_of_nbpoint_I[m][n]=pow(double(initial_contour_x[i-1]-2*(initial_contour_x[i]-1 m) initial_contour_x[i 1]),2.0) pow(double(initial_contour_y[i-1]-2*(initial_contour_y[i]-1 n) initial_contour_y[i 1]),2.0); NowImageDataPtr=ImageDataPtr ImagePitch*(initial_contour_y[i]-1 n); Image_Intensity_of_nbpoint_I[m][n]=NowImageDataPtr[initial_contour_x[i]-1 m]; } } }/*End--of--SNAKE*/ }//end of the redo loop發表人 - skybow 於 2004/06/28 17:12:04 發表人 - skybow 於 2004/06/28 17:14:39 發表人 - skybow 於 2004/06/28 17:15:40 |
dean
一般會員 發表:24 回覆:60 積分:21 註冊:2003-08-23 發送簡訊給我 |
skybow您好:
小弟對影像處理不是很了解,但看您的需求,小弟認為是不是可以用簡單的測邊演算法呢?應該可以用拉普拉資或是SOBEL等等之類的,小弟不是很了解,所以回答您的問題可能不是您所要的,可能您想過這個不是您要的,那小弟就很抱歉了!因為很可能沒幫到您!< >
下面的程式是小弟在站上看到某位大大的文章所教導的,小弟忘記是哪位前輩了,若有哪位前輩知道是誰的程式,請幫小弟提供來源,感激!
< >
for(int j=1; j這樣之後,輪廓應該就很明顯了,接下來應該可以使用區域搜尋法去跑輪廓,應該就滿快的!因為少了很多計算! **我很想學,但又很不懂,所以一直問蠢問題,希望不要不屑我的問題,嘻嘻嘻** |
dean
一般會員 發表:24 回覆:60 積分:21 註冊:2003-08-23 發送簡訊給我 |
|
skybow
一般會員 發表:10 回覆:10 積分:4 註冊:2004-04-30 發送簡訊給我 |
To Dean: 感謝您的回應,您第一篇PO的程式就是Sobel Edge Detector,這部分我沒有問題~~ 而您說的這本書我剛好就有,他只有提到基本的演算法,我也寫出來了,上篇我附的程式碼即是計算能量的部分~ 我想我應該簡化我的問題, 我只是想問,在我的計算公式裡,
有用到乘除/開根號/取絕對值/平方的地方能否有更快的寫法? 譬如說, A除B寫成"A乘以B的倒數" 或是pow(a,2)寫成a*a會不會比較快呢??? 因為我不清楚是否計算過程的微小時間差異在疊代7200次後就被放大,造成時間上的延誤? 我只是想讓這幾行簡單的公式運算速度更快而已...
anyway,感謝您的回應!
引言: 不好意思! 手邊沒有這本書,但裡面有寫關於輪廓追蹤法,小弟沒有去研究過! 但提供您可以去看看,說不定他的寫法會是您要的! http://www.cs.ntust.edu.tw/~klchung/contents.htm 第三章 測邊 3.6 輪廓追蹤法 <=應該就是它吧 |
fnk
高階會員 發表:40 回覆:149 積分:102 註冊:2004-01-02 發送簡訊給我 |
有沒有想過, 使用Look Up Table的做法呢 !! 如你所舉的例子, 數值 a 的平方為 pow(a,2), 在程式的一開始, 或許可以先把 Look Up Table 建起來, 假設你知道 a 的範圍為 -100 <= a <= 100 之間的整數, 那麼在程式的一開始, 就只要用 for 廻圏將計算好的數值存到 buffer 中, 如, 1. 初使存入數值到buffer中,
for (i=0;i<201;i ) buffer[i]=pow(i-100,2);2. 取值時, 只要配合 index 就可以取出之前的計算結果, 在使用 Look Up Table 之前, 若要算出 a=10 的平方, 需要呼叫 pow(10,2), 現在只要, buffer[110], 就可以取出值了, 這算是 "用空間換取時間吧" !! 但, 看你的算式相當複雜, 要實現可能要花一下時間, 希望對你有幫助 !! ^^ |
plihui
初階會員 發表:88 回覆:96 積分:41 註冊:2003-07-03 發送簡訊給我 |
[quote] To Dean: 感謝您的回應,您第一篇PO的程式就是Sobel Edge Detector,這部分我沒有問題~~ 而您說的這本書我剛好就有,他只有提到基本的演算法,我也寫出來了,上篇我附的程式碼即是計算能量的部分~ 我想我應該簡化我的問題, 我只是想問,在我的計算公式裡,
有用到乘除/開根號/取絕對值/平方的地方能否有更快的寫法? 譬如說, A除B寫成"A乘以B的倒數" 或是pow(a,2)寫成a*a會不會比較快呢??? 因為我不清楚是否計算過程的微小時間差異在疊代7200次後就被放大,造成時間上的延誤? 我只是想讓這幾行簡單的公式運算速度更快而已...
anyway,感謝您的回應! [quote]
是的..直接減少函數(ex: pow())的使用,可以減少主程式和函數之間
程式控制權交換和傳出入參數所造成的延遲時間...以作業系統的觀念
(好像改善不大) 查表可以更快速的節省運算時間
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |