2009-12-29 74 views
2

我目前正在使用Flex编写图像编辑应用程序,并且正在尝试制作像picnik.com中的瑕疵删除功能。删除数字图像中的瑕疵

我到处搜索,但找不到任何东西。 什么是适合这个最好的方法?

我试图只模糊了瑕疵,但结果很糟糕。

+0

为什么结果不好?你能详细说明你做了什么吗? – Andres 2009-12-29 01:34:07

+0

模糊它们之后,我得到了模糊的矩形或圆形形状。并且模糊的部分颜色较深,然后其周围.. – 2009-12-29 01:40:18

+0

我发现了该技术的专利:http://www.patentstorm.us/patents/7277595/claims.html 您可能想要小心以避免此方法或支付版税。 – Andres 2009-12-29 02:09:06

回答

2

你没有得到任何其他答案,所以我会试一试。我不知道柔性什么,但是这可能应该是可行的:

1)用户选择的区域(为了便于讨论它是一个圆)

2)您平均边缘的颜色值的圈子和存储该颜色。

3)在图像和周边的计算平均颜色之间进行高斯混合。也就是说,融合圆的中心比边缘更多。当你接近边缘时,混合的量应该消失。这应该可以防止你的图像上出现模糊的圆形状。这也有助于防止变暗,因为瑕疵色不会成为平均过程的一部分。

祝你好运!

编辑

这里是一个融合操作一些psudocode。

for (each pixel) 
{ 
    blendingConstant = [A number between zero and one which is close 
    to 1.0 near the edge of the circle, and approaches a threshold 
    value the closer you get to the center]; 

    pixelColor = (blendingConstant * pixelColor + (1.0 - blendingConstant ) * averagePerimiterColor); 
} 

阈值可以是零,也可以不是。你将不得不一直玩,直到它看起来不错。

+0

嗯,我已经看到了周边的颜色,但我不知道如何进行混合。是否有一些算法或伪代码? – 2009-12-30 03:01:50

+0

看我的编辑。希望有帮助。让我知道你是否需要更多细节,或者它是否无效。 – Andres 2009-12-30 18:11:25

1
function removeblemish(e:MouseEvent):void 

{

var radius = 16; 

var mX:Number = e.localX; 
var mY:Number = e.localY; 

var ar = 0, ag = 0, ab = 0; 
var cnt = 0; 

for(var i:int = 0; i < 360; i++) 
{ 
    var radians:Number = i * Math.PI/180.0; 

    var posX:Number = Math.floor(radius * Math.cos(radians)) + mX; 
    var posY:Number = Math.floor(radius * Math.sin(radians)) + mY; 

    if(posX >= 0 && posX < newBitmap.width && posY >= 0 && posY < newBitmap.height) 
    { 
     var pixel:uint = newBitmap.getPixel32(posX, posY); 
     ar += (pixel >> 16) & 0xFF; 
     ag += (pixel >> 8) & 0xFF; 
     ab += (pixel >> 0) & 0xFF; 
     cnt++ 
    } 
} 

ar = Math.floor(ar/cnt) % 255; 
ag = Math.floor(ag/cnt) % 255; 
ab = Math.floor(ab/cnt) % 255; 

var threshold:Number = 0.75; 

for(var i:int = 0; i <= radius; i++) 
{ 
    for(var j:int = 0; j < 360; j++) 
    { 
     var radians:Number = j * Math.PI/180.0; 

     var posX:Number = Math.floor(i * Math.cos(radians)) + mX; 
     var posY:Number = Math.floor(i * Math.sin(radians)) + mY; 

     if(posX >= 0 && posX < newBitmap.width && posY >= 0 && posY < newBitmap.height) 
     { 
      var blend = threshold + (i * 1.0/radius) * (1.0 - threshold); 

      var pixel:uint = newBitmap.getPixel32(posX, posY); 
      var cr = (pixel >> 16) & 0xFF; 
      var cg = (pixel >> 8) & 0xFF; 
      var cb = (pixel >> 0) & 0xFF; 

      cr = Math.floor(blend * cr + (1.0 - blend) * ar) % 255; 
      cg = Math.floor(blend * cg + (1.0 - blend) * ag) % 255; 
      cb = Math.floor(blend * cb + (1.0 - blend) * ab) % 255; 

      newBitmap.setPixel32(posX, posY, (255 << 24) | (cr << 16) | (cg << 8) | cb); 
     } 
    } 
} 

}

这一工程!谢谢! 他是我得到的......但如果半径变小,仍然有一些晕圈......有没有办法改进它?

+0

像素中的圆圈有多小?瑕疵是否与周边重叠? – Andres 2010-01-04 17:47:16

+0

顺便说一句,必须有一个更好的方式来遍历你的圈子中的像素。你的错误可能是由此造成的。在0到360之间不仅浪费周期,而且会扰乱数学。尝试在(mx + - radius)和(my + - radius)之间迭代。然后做一个测试,看看像素是在圈内还是在周边,取决于循环。 – Andres 2010-01-04 17:56:24