2012-03-13 108 views
6

我是一个初学者在动作。如果我理解正确,DisplacementMapFilter会根据“MAP图像”中相应像素位置的颜色从“源图像”中移动像素。DisplacementMapFilter如何工作?

问题是我的目标图像包含不在源图像中的像素!

例如,我采取单色10 * 10个像素 '的源图像' 与此BitmapData:

sourceBitmap = new BitmapData(BITMAP_WIDTH, BITMAP_HEIGHT, false, 0x000002); 

produce: 

    0 1 2 3 4 5 6 7 8 9 
[002,002,002,002,002,002,002,002,002,002] Row 0 
[002,002,002,002,002,002,002,002,002,002] Row 1 
[002,002,002,002,002,002,002,002,002,002] Row 2 
[002,002,002,002,002,002,002,002,002,002] Row 3 
[002,002,002,002,002,002,002,002,002,002] Row 4 
[002,002,002,002,002,002,002,002,002,002] Row 5 
[002,002,002,002,002,002,002,002,002,002] Row 6 
[002,002,002,002,002,002,002,002,002,002] Row 7 
[002,002,002,002,002,002,002,002,002,002] Row 8 
[002,002,002,002,002,002,002,002,002,002] Row 9 

现在,我借此BLACK位移MAP和予加少许蓝色正方形:

displacementBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0x000000); 
for(i=5;i<10;i++) 
    for(j=5;j<10;j++) 
     displacementBitmap.setPixel(i,j,255); 

produce: 

0 1 2 3 4 5 6 7 8 9 
[000,000,000,000,000,000,000,000,000,000] Row 0 
[000,000,000,000,000,000,000,000,000,000] Row 1 
[000,000,000,000,000,000,000,000,000,000] Row 2 
[000,000,000,000,000,000,000,000,000,000] Row 3 
[000,000,000,000,000,000,000,000,000,000] Row 4 
[000,000,000,000,000,255,255,255,255,255] Row 5 
[000,000,000,000,000,255,255,255,255,255] Row 6 
[000,000,000,000,000,255,255,255,255,255] Row 7 
[000,000,000,000,000,255,255,255,255,255] Row 8 
[000,000,000,000,000,255,255,255,255,255] Row 9 

结果:

displacementFilter = new DisplacementMapFilter(); 
displacementFilter.alpha=0; 
displacementFilter.color=0; 
displacementFilter.mapPoint=new Point(0,0); 
displacementFilter.scaleX=1; 
displacementFilter.scaleY=1; 
displacementFilter.componentX = flash.display.BitmapDataChannel.BLUE; 
displacementFilter.componentY = flash.display.BitmapDataChannel.BLUE; 
displacementFilter.mapBitmap = displacementBitmap; 

destinationBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0xFFFFFFFF); 
destinationBitmap.applyFilter(
    sourceBitmap.bitmapData, 
    new Rectangle(0,0,BITMAP_WIDTH,BITMAP_HEIGHT), 
    new Point(0,0), 
    displacementFilter 
); 

produce:   

    0 1 2 3 4 5 6 7 8 9 
[002,002,002,002,002,002,002,002,002,002] Row 0 
[002,002,002,002,002,002,002,002,002,002] Row 1 
[002,002,002,002,002,002,002,002,002,002] Row 2 
[002,002,002,002,002,002,002,002,002,002] Row 3 
[002,002,002,002,002,002,002,002,002,002] Row 4 
[002,002,002,002,002,001,001,001,001,001] Row 5 
[002,002,002,002,002,001,001,001,001,001] Row 6 
[002,002,002,002,002,001,001,001,001,001] Row 7 
[002,002,002,002,002,001,001,001,001,001] Row 8 
[002,002,002,002,002,001,001,001,001,001] Row 9 

所以我不明白为什么我有一个不存在于“001”的像素源图像。

非常感谢。

+0

现在,无耻的插件时间到我的[问题](http://stackoverflow.com/questions/9260717/displacement-map-filter-in-opencv)。 – karlphillip 2012-03-29 17:05:10

回答

3

置换图滤波器决定使用this formula源位图抢哪个像素:

dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX)/256, y + ((componentY(x, y) - 128) *scaleY)/256) 

dstPixel是目标位图,srcPixel是源位图,并且是componentX/Y从位移位图。映射取决于组件通道离128的距离。请注意,128是不存在转换的中性值,并且使用相同的源像素。

例如,让我们考虑您的情况下(1,1)处的像素。你的分量通道是蓝色的,位移图中(1,1)的蓝色通道的值为0.所以我们用(0 - 128)/ 256或-0.5来代替。所以我们从源位图抓取的最终像素是(0.5,0.5)。

但是,使用半个像素意味着什么?事实证明,Flash使用bilinear filtering来平滑结果。 (0,0)和(1,1)之间的四个像素中的颜色混合。

这就是您看到不在源图像中的奇数像素的原因。尽管源图像中的所有像素都是相同的颜色,但Flash在颜色之间进行插值时似乎存在一些浮点不准确的情况,所以有时会得到一个仅有关闭的值。请注意,如果您在位移位图中使用“干净地”除以128的值(例如0或64),那么您会得到正确的结果。但是如果你使用255或19的值,你会得到一些错误。

不幸的是,似乎没有任何方法可以关闭过滤并使用简单的最近邻采样。因此,如果您需要确保不会引入新的颜色,那么您必须仔细选择位移贴图中的值。

或者,你可以使用Pixel Bender来创建一个你需要的内核。 Pixel Bender允许您从源位图执行最近邻采样。

+0

完美。非常感谢。 – 2012-04-08 23:13:26