使用 Core Image Kernel Language 进行 RGB 到 HSL 的颜色转换

3
我正在尝试创建一种图像过滤器,可以改变图像的颜色。为了做到这一点,我需要将RGB颜色转换为HSL,并在进行颜色移位后将其转换回RGB。我进行了一些研究,找到了一些可以帮助我完成此任务的公式。
我在我的Swift测试环境中实现了它们,以测试它们是否可靠。我不会在此处发布Swift代码,以保持清洁,但我将展示我的测试结果:
输入:RGB(61、117、237)或(0.24、0.46、0.93)
结果:
rgb2hsl [0.613527 0.831325 0.585] or (221, 83, 58.5) //hsl
hsl2rgb [0.24 0.46 0.93] //back to rgb

#3D75ED

太好了!目前为止一切顺利。

现在我们需要将我们的Swift代码转换为Core Image Kernel Language(CIKL)。 以下是代码:

float hue2rgb(float f1, float f2, float hue) {
   if (hue < 0) {
      hue += 1.0;
   }
   else if (hue > 1) {
      hue -= 1.0;
   }

   float res;
   if (6*hue<1) {
      res = f1 + (f2 - f1) * 6 * hue;
   }
   else if (2*hue<1) { 
      res = f2;
   }
   else if (3*hue<2) {
      res = f1 + (f2 - f1) * (2.0/3.0 - hue) * 6;
   }
   else {
       res = f1;
   }
   return res;
}


vec3 hsl2rgb(vec3 hsl) {
   vec3  rgb;
   if (hsl.y == 0) {
      rgb = vec3(hsl.z,hsl.z,hsl.z);
   }
   else {
      float f2;
      if (hsl.z < 0.5) {
         f2 = hsl.z * (1.0 + hsl.y);
      } 
      else {
         f2 = hsl.z + hsl.y - hsl.y * hsl.z;
      }

      float f1 = 2 * hsl.z - f2;

      float r = hue2rgb(f1, f2, hsl.x + 1.0/3.0);
      float g = hue2rgb(f1, f2, hsl.x);
      float b = hue2rgb(f1, f2, hsl.x - 1.0/3.0);

      rgb = vec3(r,g,b);
   }
   return rgb;
}



vec3 rgb2hsl(vec3 rgb) {

   float maxC = max(rgb.x, max(rgb.y,rgb.z));
   float minC = min(rgb.x, min(rgb.y,rgb.z));

   float l = (maxC + maxC)/2.0;

   float h = 0;
   float s = 0;

   if (maxC != minC) {
      float d = maxC - minC;
      s = l > 0.5 ? d / (2.0 - maxC - minC) : d / (maxC + minC);

      if (maxC == rgb.x) {      
         h =  (rgb.y - rgb.z) / d + (rgb.y < rgb.z ? 6.0 : 0);
      } else if (maxC == rgb.y) {
         h = (rgb.z - rgb.x) / d + 2.0;
      }
      else {
         h = (rgb.x - rgb.y) / d + 4.0;
      }

      h /= 6.0;
   }

   return vec3(h,s,l);
}

这里出现了问题。使用这些函数在我的过滤器中无法获得正确的值。为了检查所有内容,我制作了一个Quartz Composer Patch。 由于我没有在CIKL中找到任何打印/日志选项,因此我制作了这个来检查我的转换是否正确:enter image description here 此补丁的逻辑:我的过滤器将颜色作为输入,将其转换为HSL格式,再转换回RGB格式并返回;图像输入暂时被忽略。 我的过滤器的内核功能如下:
kernel vec4 kernelFunc(__sample pixel, __color color) {
   vec3 vec = color.rgb;

   vec3 hsl = rgb2hsl(vec);

   return vec4(hsl2rgb(hsl), 1);
}

筛选器包含上述列出的函数。

我在查看器中看到的结果是:

enter image description here 右侧的图像是从输入颜色裁剪的常量颜色图像。 左侧的图像是我们筛选器的输出。

数字颜色选择器返回左侧图像的rgb值为(237,239.7,252)。

我已经没有更多的想法来调试这个问题并找到解决方案。任何帮助都将不胜感激。谢谢。

1个回答

4
我发现了问题。问题出在我把Swift代码转换成CIKL时犯了一个非常难以找到的愚蠢错误,因为在CIKL中没有print / log工具,或者我不知道有没有。 无论如何,问题在于rgb2hsl函数:
float l = (maxC + maxC)/2.0; // WRONG

应该是这样的:

float l = (maxC + minC)/2.0;

希望这能帮助以后的人。


有没有一个不含所有这些条件判断的版本?类似于将rgb转换为HSV的简化方法。 - Cristiano Coelho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接