這裡首先先講一下金字塔的原理:
影像金字塔就是把一個原始影像處理成一個類似於塔狀的影像結構(請不要糾結於這個概念)
在影像金字塔中最精細層的解析度為16*16,下一層是8*8,依次為4*4,2*2,1*1
如所示:
圖中網格頂點表示原始映像16*16;紅色差號代表8*8;黑色圓圈代表4*4.
按照上述原理,那麼編程實現不過就是隔點採樣,那麼相鄰兩幅映像在對應點上的灰階值應該相等,當然我是這麼想的。
C#在Drawing命名空間下的Bitmap類裡面有一個處理影像金字塔的函數,
複製代碼 代碼如下:public void mipmaping()
{
Bitmap jpgsource =new Bitmap(@"E:\height512.jpg");
Bitmap jpgTarget = new Bitmap(jpgsource, jpgsource.Width>>1, jpgsource.Height>>1);
jpgTarget.Save(@"E:\height256.jpg");
}
但是經過我逐像素對比之後,發現這兩張圖上對應點的像素並不相等,這說明一個問題:C#裡的這個方法肯定不是按照逐點採樣,而是採用某種方法把映像展開的。這似乎不太符合金字塔的原理,所以我又重新寫了一個金字塔的函數:
複製代碼 代碼如下:public void Rescale()
{
Bitmap myImage1024 = new Bitmap(@"E:\height.jpg");
int width = myImage1024.Height; ;
int height = myImage1024.Width; ;
Console.WriteLine(DateTime.Now.ToString());
for (int power = 1; power < 3; power++)
{
Bitmap myImage = new Bitmap(width >> power, height >> power);
int row = myImage.Height;
int column = myImage.Width;
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
{ //這裡是精要,實際上就是按照採樣間距 踩點
int i1024 = getcoor(i, power); int j1024 = getcoor(j, power);
Color color1024 = myImage1024.GetPixel(i1024, j1024);
myImage.SetPixel(i, j, color1024);
}
myImage.Save(string.Format(@"E:\myjpg\height{0}.jpg", width >> power));
}
Console.WriteLine(DateTime.Now.ToString());
}
public int getcoor(int i,int power)
{
if (power > 1)
return 2 * getcoor(i,power-1) +1;
else
return 2 * i + 1;
}
按照我寫的這個函數來建造金字塔,此時相鄰圖層之間的對應點像素值就相等了。