【问题标题】:Retinex algorithm implementationRetinex算法实现
【发布时间】:2013-11-29 04:06:16
【问题描述】:

我需要在 C# 中实现Single Scale retinex and multiscale retinex algorithm
我搜索了一下,但找不到任何有用的练习项目和代码
正如我正确理解的那样,我应该:

  1. 将 RGB 转换为 YUV
  2. 使用高斯模糊滤镜模糊图像
  3. 使用 I'(x, y) = 255*log10( I(x, y)/G(x, y) ) + 127.5
    I - 是光照,G - 高斯核,I' - 结果图像
  4. С将 YUV 转换回 RGB

此代码无法正常工作

 public static Image<Bgr, byte> SingleScaleRetinex(this Image<Bgr, byte> img, int gaussianKernelSize, double sigma)
            {
                var radius = gaussianKernelSize / 2;
                var kernelSize = 2 * radius + 1;

                var ycc = img.Convert<Ycc, byte>();

                var sum = 0f;
                var gaussKernel = new float[kernelSize * kernelSize];
                for (int i = -radius, k = 0; i <= radius; i++, k++)
                {
                    for (int j = -radius; j <= radius; j++)
                    {
                        var val = (float)Math.Exp(-(i * i + j * j) / (sigma * sigma));
                        gaussKernel[k] = val;
                        sum += val;
                    }
                }
                for (int i = 0; i < gaussKernel.Length; i++)
                    gaussKernel[i] /= sum;

                var gray = new Image<Gray, byte>(ycc.Size);
                CvInvoke.cvSetImageCOI(ycc, 1);
                CvInvoke.cvCopy(ycc, gray, IntPtr.Zero);

                // Размеры изображения
                var width = img.Width;
                var height = img.Height;

                var bmp = gray.Bitmap;
                var bitmapData = bmp.LockBits(new Rectangle(Point.Empty, gray.Size), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

                unsafe
                {
                    for (var y = 0; y < height; y++)
                    {
                        var row = (byte*)bitmapData.Scan0 + y * bitmapData.Stride;
                        for (var x = 0; x < width; x++)
                        {
                            var color = row + x;

                            float val = 0;

                            for (int i = -radius, k = 0; i <= radius; i++, k++)
                            {
                                var ii = y + i;
                                if (ii < 0) ii = 0; if (ii >= height) ii = height - 1;

                                var row2 = (byte*)bitmapData.Scan0 + ii * bitmapData.Stride;
                                for (int j = -radius; j <= radius; j++)
                                {
                                    var jj = x + j;
                                    if (jj < 0) jj = 0; if (jj >= width) jj = width - 1;

                                    val += *(row2 + jj) * gaussKernel[k];

                                }
                            }

                            var newColor = 127.5 + 255 * Math.Log(*color / val);
                            if (newColor > 255)
                                newColor = 255;
                            else if (newColor < 0)
                                newColor = 0;
                            *color = (byte)newColor;
                        }
                    }
                }
                bmp.UnlockBits(bitmapData);

                CvInvoke.cvCopy(gray, ycc, IntPtr.Zero);
                CvInvoke.cvSetImageCOI(ycc, 0);

                return ycc.Convert<Bgr, byte>();

            }

【问题讨论】:

  • 你的代码修复了吗?

标签: c# .net image image-processing image-enhancement


【解决方案1】:

看看: http://www.fer.unizg.hr/ipg/resources/color_constancy

这些算法是对 Retinex 算法的修改(速度有所提高),尽管作者给它们起了有趣的名字:)

有完整的源代码(C++,但写得很好)。

【讨论】:

    【解决方案2】:

    很抱歉发布了 necro-post,但您的程序的第 3 步似乎有一个错误,可能会误导路过的人。

    为了应用校正,您希望将源图像除以高斯滤波副本,而不是高斯核本身。大约,在伪代码中:

    I_filtered(x,y) = G(x,y) * I(x,y)
    I'(x,y) = log(I(x,y) / I_filtered(x,y))
    

    然后将I'(x,y) 转换为所需的数字类型(uint8,我可以参考原帖)。

    有关该主题的更多信息,请访问this paper

    Ri(x, y) = log(Ii(x, y)) − log(Ii(x, y) ∗ F(x, y))

    Ii 是第 i 个颜色通道上的输入图像,Ri 是第 i 个上的 retinex 输出图像 通道和F 是标准化环绕功能。 .

    【讨论】:

    • 请在论文中包含链接中的相关部分。
    • 更新了评论。
    猜你喜欢
    • 2016-11-06
    • 2020-05-18
    • 2017-12-10
    • 2022-01-05
    • 2011-07-02
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多