亞像素
亞像素
面陣攝像機的成像面以像素為最小單位。例如某CMOS攝像晶元,其像素間距為5.2微米。攝像機拍攝時,將物理世界中連續的圖像進行了離散化處理。到成像面上每一個像素點只代表其附近的顏色。至於“附近”到什麼程度?就很困難解釋。兩個像素之間有5.2微米的距離,在宏觀上可以看作是連在一起的。但是在微觀上,它們之間還有無限的更小的東西存在。這個更小的東西我們稱它為“亞像素”。實際上“亞像素”應該是存在的,只是硬體上沒有個細微的感測器把它檢測出來。於是軟體上把它近似地計算出來。
數碼攝像機的成像面的解析度以像素數量來衡量。隔行TV的解析度是576x768個像素。像素中心之間的距離有幾個至十幾個微米不等。為了最大限度利用圖像信息來提高解析度,有人提出了Sub-Pixel概念。意思是說,在兩個物理像素之間還有像素,稱之為Sub-Pixel,它完全是通過計算方法得出來的。這裡提出計算方法。
如果原始圖像是n行m列的,希望做k細分的Sub-Pixel,這樣就有新的行N和列M,有
N = k*n
M = k*m
原來相鄰4個像素包含的區域現在變成了(k+1)*(k+1)的區域了;要填滿這個(k+1)*(k+1)的區域,實際上就是從一個小正方形映照到一個大正方形的過程。在數學上用雙線性插值得演演算法可以輕鬆搞定。(二次或者三次樣條曲線)。下面是演演算法的代碼:
XYPNT qdot(
XYPNT d[4], //d[4] 順時針排列
XYPNT a //含有要插入的點的位置
){
XYPNT r; //工作單元
int i;
float x0,y0,x1,y1; //
PNT z[4];
float ap,bt,ax,ay;
x0=d[0].q.x;y0=d[0].q.y;
x1=d[2].q.x;y1=d[2].q.y;
r=a;
ax=a.q.x;ay=a.q.y;
for(i=0;i<4;i++)z[i]=d[i].pnt;
ap=(ax-x0)/(x1-x0);bt=(ay-y0)/(y1-y0);
r.pnt.r=(1.-ap)*(1.-bt)*z[0].r+bt*(1.-ap)*z[3].r+ap*(1.-bt)*z[1].r+ap*bt*z[2].r;
r.pnt.g=(1.-ap)*(1.-bt)*z[0].g+bt*(1.-ap)*z[3].g+ap*(1.-bt)*z[1].g+ap*bt*z[2].g;
r.pnt.b=(1.-ap)*(1.-bt)*z[0].b+bt*(1.-ap)*z[3].b+ap*(1.-bt)*z[1].b+ap*bt*z[2].b;
return r;
}
struct PNT{BYTE b,g,r;}; //像素的顏色
struct DXY{short x,y;}; //像素的坐標
struct XYPNT{ //像素的全信息
DXY q;
PNT pnt;};
for(i=0;i
d[0].q.x=j*xf ; d[0].q.y=i*xf; d[0].pnt=*(buf+i*WIdth+j);
d[1].q.x=(j+1)*xf; d[1].q.y=i*xf; d[1].pnt=*(buf+i*WIdth+j+1);
d[2].q.x=(j+1)*xf; d[2].q.y=(i+1)*xf; d[2].pnt=*(buf+(i+1)*WIdth+j+1);
d[3].q.x=j*xf ; d[3].q.y=(i+1)*xf; d[3].pnt=*(buf+(i+1)*WIdth+j);
for(i0=0;i0
aa.q.x=j*xf+j0;aa.q.y=i*xf+i0;
rr=qdot(d,aa);
*(Buf+aa.q.y*WIDTH+aa.q.x)=rr.pnt;
}
}
亞像素精度是指相鄰兩像素之間細分情況。輸入值通常為二分之一,三分之一或四分之一。這意味著每個像素將被分為更小的單元從而對這些更小的單元實施插值演演算法。例如,如果選擇四分之一,就相當於每個像素在橫向和縱向上都被當作四個像素來計算。因此,如果一張5x5像素的圖像選擇了四分之一的亞像素精度之後,就等於創建了一張20x20的離散點陣,進而對該點陣進行插值。
目錄