红眼减lessalgorithm

我需要为我正在处理的应用程序实施红眼减less。

谷歌search主要提供商业terminal用户产品的链接。

你知道一个好的红眼减lessalgorithm,可以在GPL应用程序中使用吗?

我在这里参加派对的时间已经晚了,但对于未来的search者,我使用了以下algorithm来编写我写的个人应用程序。

首先,用户select要缩小的区域,并以红眼减less方法作为中心点和半径。 该方法遍历半径内的每个像素并进行以下计算:

//Value of red divided by average of blue and green: Pixel pixel = image.getPixel(x,y); float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2)); if (redIntensity > 1.5f) // 1.5 because it gives the best results { // reduce red to the average of blue and green bm.SetPixel(i, j, Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B)); } 

我非常喜欢这个结果,因为它们保持了颜色的强度,这意味着眼睛的光线reflection不会减less。 (这意味着眼睛保持“活”的外观。)

一个伟大的图书馆find眼睛是openCV 。 它具有非常丰富的image processingfunction。 另请参阅本文,标题为Ilia V. Safonov的“自动红眼检测”。

首先你需要find眼睛! 标准的方法是运行一个边缘检测器,然后Hough变换来find两个相同大小的圆,但是可能有更简单的algorithm来简单地find红色像素的簇。

然后,您需要决定如何replace它们,假设图像中有足够的绿色/蓝色数据,您可以忽略红色通道。

OpenCV是一个非常好的image processing免费库,它可能是你想要的矫枉过正 – 但有很多的例子和一个非常活跃的社区。 您还可以search对象跟踪algorithm,跟踪场景中的有色物体是非常类似和常见的问题。

如果没有人提出更直接的答案,你可以随时下载GIMP的源代码 ,看看他们是如何做到的。

最简单的algorithm,仍然是一个非常有效的方法,就是将感兴趣区域的RGB三元组的R值归零。

红色消失,但其他颜色保留。

该algorithm的进一步扩展可能涉及仅针对以红色为主色的三元组(R> G且R> B)对R值进行归零。

你可以尝试imagemagick – 在这个页面上的一些提示如何做到这一点

http://www.cit.gu.edu.au/~anthony/info/graphics/imagemagick.hints

search页面上的红眼

开源项目Paint.NET在C#中有一个实现。

这是java实现解决scheme

 public void corrigirRedEye(int posStartX, int maxX, int posStartY, int maxY, BufferedImage image) { for(int x = posStartX; x < maxX; x++) { for(int y = posStartY; y < maxY; y++) { int c = image.getRGB(x,y); int red = (c & 0x00ff0000) >> 16; int green = (c & 0x0000ff00) >> 8; int blue = c & 0x000000ff; float redIntensity = ((float)red / ((green + blue) / 2)); if (redIntensity > 2.2) { Color newColor = new Color(90, green, blue); image.setRGB(x, y, newColor.getRGB()); } } } } 

作为从应用程序检测到的两个矩形检索的参数,如打开cv(这应该是一个涉及眼睛位置的矩形)

 int posStartY = (int) leftEye.getY(); int maxX = (int) (leftEye.getX() + leftEye.getWidth()); int maxY = (int) (leftEye.getY() + leftEye.getHeight()); this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image); // right eye posStartX = (int) rightEye.getX(); posStartY = (int) rightEye.getY(); maxX = (int) (rightEye.getX() + rightEye.getWidth()); maxY = (int) (rightEye.getY() + rightEye.getHeight()); this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image); 

这是Benry提供的答案的更完整的实现:

  using SD = System.Drawing; public static SD.Image ReduceRedEye(SD.Image img, SD.Rectangle eyesRect) { if ( (eyesRect.Height > 0) && (eyesRect.Width > 0)) { SD.Bitmap bmpImage = new SD.Bitmap(img); for (int x=eyesRect.X;x<(eyesRect.X+eyesRect.Width);x++) { for (int y=eyesRect.Y;y<(eyesRect.Y+eyesRect.Height);y++) { //Value of red divided by average of blue and green: SD.Color pixel = bmpImage.GetPixel(x,y); float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2)); if (redIntensity > 2.2f) { // reduce red to the average of blue and green bmpImage.SetPixel(x, y, SD.Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B)); pixel = bmpImage.GetPixel(x,y); // for debug } } } return (SD.Image)(bmpImage); } return null; } 

阅读这个博客,关于检测和纠正红眼有一个很好的解释。 用OpenCV和Python进行红眼校正