我正在制作一个图像去噪程序。它通过将图像的 RGB 值转换为它的 HSI 值,然后对 HSI 值进行运算并将它们转换回 RGB 来实现。我的问题是,出于某种原因,相当多的图像在去噪后得到了错误的颜色(去噪本身有效)。
我现在处于停滞状态,不知道是什么原因造成的(除了它可能在某处 RGB 和 HSI 之间的转换过程中),所以你们中的任何一位绅士/女士有任何想法吗?这是一张错误图片的示例(所有额外的绿色):
这些是公式:
仅供引用,该公式有一个错误,即如果 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;
}
}
}
}
}
输出的第一行是:
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/