一:图像金字塔基本操作
对一张图像不断的模糊之后向下采样,得到不同分辨率的图像,同时每次得到的
新的图像宽与高是原来图像的1/2, 最常见就是基于高斯的模糊之后采样,得到的
一系列图像称为高斯金字塔。
高斯金字塔不同(DoG)又称为拉普拉斯金字塔,其计算公式如下:
L(i) = G(i) – expand(G(i+1))
第i层拉普拉斯金字塔是由第i层高斯金字塔减去第i+1层高斯金字塔expand之后得到。
本文得到的DoG(Difference of Gaussian)结果如下:
二:关键代码解析
金字塔reduce操作实现代码如下:
[java] private BufferedImage pyramidReduce(BufferedImage src) {
int width = src.getWidth();
int height = src.getHeight();
BufferedImage dest = createSubCompatibleDestImage(src, null);
int[] inPixels = new int[width*height];
int ow = width/2;
int oh = height/2;
int[] outPixels = new int[ow*oh];
getRGB(src, 0, 0, width, height, inPixels );
int inRow=0, inCol = 0, index = 0, oudex =0, ta = 0;
float[][] keneralData = this.getHVGaussianKeneral();
for(int row=0; row
inCol = 2* col;
if(inRow >= height) {
inRow = 0;
}
if(inCol >= width) {
inCol = 0;
}
float sumRed = 0, sumGreen = 0, sumBlue = 0;
for(int subRow = -2; subRow <= 2; subRow++) {
int inRowOff = inRow + subRow;
if(inRowOff >= height || inRowOff < 0) {
inRowOff = 0;
}
for(int subCol = -2; subCol <= 2; subCol++) {
int inColOff = inCol + subCol;
if(inColOff >= width || inColOff < 0) {
inColOff = 0;
}
index = inRowOff * width + inColOff;
ta = (inPixels[index] >> 24) & 0xff;
int red = (inPixels[index] >> 16) & 0xff;
int green = (inPixels[index] >> 8) & 0xff;
int blue = inPixels[index] & 0xff;
sumRed += keneralData[subRow + 2][subCol + 2] * red;
sumGreen += keneralData[subRow + 2][subCol + 2] * green;
sumBlue += keneralData[subRow + 2][subCol + 2] * blue;
}
}
oudex = row * ow + col;
outPixels[oudex] = (ta << 24) | (clamp(sumRed) << 16) | (clamp(sumGreen) << 8) | clamp(sumBlue);
}
}
setRGB( dest, 0, 0, ow, oh, outPixels );
return dest;
}
private BufferedImage pyramidReduce(BufferedImage src) {
int width = src.getWidth();
int height = src.getHeight();
BufferedImage dest = createSubCompatibleDestImage(src, null);
int[] inPixels = new int[width*height];
int ow = width/2;
int oh = height/2;
int[] outPixels = new int[ow*oh];
getRGB(src, 0, 0, width, height, inPixels );
int inRow=0, inCol = 0, index = 0, oudex =0, ta = 0;
float[][] keneralData = this.getHVGaussianKeneral();
for(int row=0; row
inCol = 2* col;
if(inRow >= height) {
inRow = 0;
}
if(inCol >= width) {
inCol = 0;
}
float sumRed = 0, sumGreen = 0, sumBlue = 0;
for(int subRow = -2; subRow <= 2; subRow++) {
int inRowOff = inRow + subRow;
if(inRowOff >= height || inRowOff < 0) {
inRowOff = 0;
}
for(int subCol = -2; subCol <= 2; subCol++) {
int inColOff = inCol + subCol;
if(inColOff >= width || inColOff < 0) {
inColOff = 0;
}
index = inRowOff * width + in