c++ - 编织中的降噪算法

标签 c++ image algorithm

我正在制作一个图像去噪程序。它通过将图像的 RGB 值转换为它的 HSI 值,然后对 HSI 值进行运算并将它们转换回 RGB 来实现。我的问题是,出于某种原因,相当多的图像在去噪后得到了错误的颜色(去噪本身有效)。

我现在处于停滞状态,不知道是什么原因造成的(除了它可能在某处 RGB 和 HSI 之间的转换过程中),所以你们中的任何一位绅士/女士有任何想法吗?这是一张错误图片的示例(所有额外的绿色):

image

这些是公式:

formulas

仅供引用,该公式有一个错误,即如果 R==G==B,则 H 和 S 应设置为 0。您会在代码中看到这一点。

这是我针对两种不同转换过程(RGB>HSI、HSI>RGB)的编织代码。 Cos 和 acos 值需要以度为单位,因此需要添加 180/pi 和 pi/180。 G[i]等中的i只是指被转换的像素点(循环遍历图片中的所有像素点)。

恒指:

translateToHSI = r"""
        for (int i=0; i<(m*n); i++)
        {
            I[i] = (R[i]+G[i]+B[i])/3;
            if (I[i] == 0)
            {
                S[i] = 0;
            }
            else
            {
                float fl = fmin(R[i], G[i]);
                fl = fmin(fl, B[i]);
                S[i] = 1-(fl/I[i]);
            }
            float func = (R[i]-(G[i]/2.0)-(B[i]/2.0))/sqrt((R[i]*R[i])+(G[i]*G[i])+(B[i]*B[i])-(R[i]*G[i])-(R[i]*B[i])-(G[i]*B[i]));
            if (R[i]==G[i] && G[i] == B[i])
            {
                H[i] = 0;
                S[i] = 0;
            }
            else if (G[i]<B[i])
            {
                H[i] = 360-(acos(func)*180.0/3.14159265);
            }
            else
            {
                H[i] = acos(func)*180.0/3.1459265;
            }
        }
"""

转RGB:

    translateToRGB = r"""
            for (int i=0; i<(m*n); i++)
            {
                if (H[i] == 0)
                {
                    R[i] = I[i]+2*I[i]*S[i];
                    G[i] = I[i]-I[i]*S[i];
                    B[i] = I[i]-I[i]*S[i];
                }
                else if (H[i] < 120)
                {
                    float func = cos(H[i]*3.14159265/180)/cos(60-H[i]*3.14159265/180);
                    R[i] = I[i]+I[i]*S[i]*func;
                    G[i] = I[i]+I[i]*S[i]*(1-func);
                    B[i] = I[i]-I[i]*S[i];
                }
                else if (H[i] == 120)
                {
                    R[i] = I[i]-I[i]*S[i];
                    G[i] = I[i]+2*I[i]*S[i];
                    B[i] = I[i]-I[i]*S[i];
                }
                else if (H[i] < 240)
                {
                    float func = cos((H[i]-120)*3.14159265/180)/cos((180-H[i])*3.1459265/180);
                    R[i] = I[i]-I[i]*S[i];
                    G[i] = I[i]+I[i]*S[i]*func;
                    B[i] = I[i]+I[i]*S[i]*(1-func);
                }
                else if (H[i] == 240)
                {
                    R[i] = I[i]-I[i]*S[i];
                    G[i] = I[i]-I[i]*S[i];
                    B[i] = I[i]+2*I[i]*S[i];
                }
                else
                {
                    float func = cos((H[i]-240)*3.14159265/180)/cos((300-H[i])*3.14159265/180);
                    R[i] = I[i]+I[i]*S[i]*(1-func);
                    G[i] = I[i]-I[i]*S[i];
                    B[i] = I[i]+I[i]*S[i]*func;
                }
            }
    """

最佳答案

所以我写了下面的代码

#include <iostream>
#include <math.h>


void toHSI(float R, float G, float B, float& H, float& S, float& I) {
    I = (R+G+B)/3;
    if (I == 0)
    {
        S = 0;
    }
    else
    {
        float fl = fmin(R, G);
        fl = fmin(fl, B);
        S = 1-(fl/I);
    }
    float func = (R-(G/2.0)-(B/2.0))/sqrt((R*R)+(G*G)+(B*B)-(R*G)-(R*B)-(G*B));
    if (R==G && G == B)
    {
        H = 0;
        S = 0;
    }
    else if (G<B)
    {
        H = 360-(acos(func)*180.0/3.14159265);
    }
    else
    {
        H = acos(func)*180.0/3.1459265;
    }
}

void toRGB(float H, float S, float I, float& R, float& G, float& B) {
    if (H == 0)
    {
        R = I+2*I*S;
        G = I-I*S;
        B = I-I*S;
    }
    else if (H < 120)
    {
        float func = cos(H*3.14159265/180)/cos(60-H*3.14159265/180);
        R = I+I*S*func;
        G = I+I*S*(1-func);
        B = I-I*S;
    }
    else if (H == 120)
    {
        R = I-I*S;
        G = I+2*I*S;
        B = I-I*S;
    }
    else if (H < 240)
    {
        float func = cos((H-120)*3.14159265/180)/cos((180-H)*3.1459265/180);
        R = I-I*S;
        G = I+I*S*func;
        B = I+I*S*(1-func);
    }
    else if (H == 240)
    {
        R = I-I*S;
        G = I-I*S;
        B = I+2*I*S;
    }
    else
    {
        float func = cos((H-240)*3.14159265/180)/cos((300-H)*3.14159265/180);
        R = I+I*S*(1-func);
        G = I-I*S;
        B = I+I*S*func;
    }
}

int main() {
    for (int r = 0; r < 255; r += 10) {
        for (int g = 0; g < 255; g += 10) {
            for (int b = 0; b < 255; b += 10) {
                float r1, g1, b1, h, s, i;
                toHSI(r, g, b, h, s, i);
                toRGB(h, s, i, r1, g1, b1);
                if (fabs(r - r1) > 5 || fabs(g - g1) > 5 || fabs(b - b1) > 5) {
                    std::cout << r << ' ' << g << ' ' << b << " --> "
                        << h << ' ' << s << ' ' << i << " --> "
                        << r1 << ' ' << g1 << ' ' << b1 << std::endl;
                }
            }
        }
    }
}

Demo for convenience

输出的第一行是:

0 20 0 --> 119.835 1 6.66667 --> -9.17128 29.1713 0
0 30 0 --> 119.835 1 10 --> -13.7569 43.7569 0
0 40 0 --> 119.835 1 13.3333 --> -18.3426 58.3426 0
0 50 0 --> 119.835 1 16.6667 --> -22.9282 72.9282 0
0 60 0 --> 119.835 1 20 --> -27.5138 87.5138 0

现在您可以使用给出错误结果的任何值调试此代码并找到错误所在。

关于c++ - 编织中的降噪算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26893746/

相关文章:

c++ - 如何为库PCRE2生成单个 header ?

algorithm - 闭合多边形链与线的交点

python - 给定 k 个标记的最大项目

c++ - 静态常量 : why does it need to be templated?

c++ - 字符串流问题,我认为我的代码看起来不错,但它显示奇怪的符号

css - 导航栏上的背景图片

php - 如何像在 Twitter 上一样在后台显示存储在数据库中的重复图像?

c# - 使用 FreeImage 库 (C#) 减少 PNG-8 调色板中的颜色计数

algorithm - 将数组的每个元素减少为零

c++ - 是否有任何 SVM 库支持可与 Visual Studio C++ 一起使用的自定义内核?