LogPolar 對數極坐標
對數極坐標(logpolar)是仿真生物視網膜中央凹陷的特性,具有數據壓縮的能力,可用於目標跟蹤中快速尺度和旋轉變換不變的模板匹配。
對數極坐標其實就是將圖像像素坐標轉換成極坐標,然后對r求取對數,獲得的坐標。
直角坐標系和極坐標系的變換公式為:


具體過程是怎么樣的呢?首先要選定坐標原點,然后才能變換。一般坐標原點選為圖像的中心點,如果直接對每一個像素點計算對應的坐標,首先得到的結果並不是個矩陣,其次這樣
之后再逆變換到圖像上,信息並沒有變化。
所以在轉換計算時,使用如下圖類似的結構。

這個結構包含32個同心圓,每個同心圓上有64個區域,其中徑向上相鄰的區域大小變化時線性的,距離中心越遠,區域越大。
在變換時,每個區域計算均值,然后該區域轉換到坐標下,就獲得
的矩陣,如下圖示意

如果我們將得到的坐標下的圖像再映射回直角坐標系中,那么離中心近的區域顯然分辨率較高,而距離遠的區域就相當於經過了均值濾波。如下圖

由於圖像都是矩陣,沒有環形的,所以在轉換過程中,肯定會碰到超出圖像邊界的區域,這時候采用0值替代。
OpenCV中logpolar轉換函數為
void cvLogPolar(const CvArrsrc, CvArr dst, CvPoint2D32f center,double M,int flags)
src: 輸入圖像
dst: 輸出圖像
center: 設置的坐標原點位置
M: 尺度參數
flag: 標志位和插值方法
CV_INTER_LINEAR 內部采用線性插值,注意由於M的存在結果可能不會相鄰整數,中間需要差值,逆變換也需要插值
CV_WARP_FILL_OUTLIERS 對於超出圖像邊界區域如何處理
- CV_WARP_INVERSE_MAP 標志位,未設置表示轉換成極坐標,設置表示由極坐標變回直角坐標
示例:
測試圖像

代碼
- #include "highgui.h"
- #include "cv.h"
-
- int main(int argc, char** argv)
- {
- IplImage* img = cvLoadImage(argv[1]);
- cvNamedWindow("Origin");
- cvShowImage("Origin", img);
- IplImage* out = cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels);
- cvLogPolar(img, out, cvPoint2D32f(img->width / 2, img->height / 2), 40, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS);
- cvNamedWindow("logPolar");
- cvShowImage("logPolar", out);
- IplImage* back = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
- cvLogPolar(out, back, cvPoint2D32f(img->width / 2, img->height / 2), 40, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS + CV_WARP_INVERSE_MAP);
- cvNamedWindow("Reconstructure");
- cvShowImage("Reconstructure", back);
- cvWaitKey(0);
- cvReleaseImage(&img);
- cvDestroyWindow("Origin");
- cvReleaseImage(&out);
- cvDestroyWindow("logPolar");
- cvReleaseImage(&back);
- cvDestroyWindow("Reconstructure");
- }
-
得到結果圖像:


可以發現中間分辨率還是可以的,但是周圍顯然模糊了好多。
當然還可以設置不同的中心位置,和不同的尺度參數。
內部不設置插值方式的結果

