在 CIFilter 内核中使用归一化采样器坐标

Posted

技术标签:

【中文标题】在 CIFilter 内核中使用归一化采样器坐标【英文标题】:Using normalized sampler coordinates in CIFilter kernel 【发布时间】:2021-11-11 19:55:10 【问题描述】:

我正在浏览这个关于自定义 CIFilter 的教程:

https://medium.com/@m_tuzer/using-metal-shading-language-for-custom-cikernels-metal-swift-7bc8e7e913e6

除了采样器的坐标没有标准化之外,一切都完美无缺。因此,例如 pos.y < 0.33 这样的条件不起作用,内核使用实际的图像坐标。

由于本教程较旧,CIFilter 中可能发生了“破坏”此代码的更改。我查看了manual for CI kernels,但找不到获取内核内部采样器标准化坐标的方法。

这是内核的代码:

#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h> // (1)

float3 multiplyColors(float3, float3);
float3 multiplyColors(float3 mainColor, float3 colorMultiplier)  // (2)
    float3 color = float3(0,0,0);
    color.r = mainColor.r * colorMultiplier.r;
    color.g = mainColor.g * colorMultiplier.g;
    color.b = mainColor.b * colorMultiplier.b;
    return color;
;

extern "C"  namespace coreimage                // (3)
    float4 dyeInThree(sampler src, float3 redVector, float3 greenVector, float3 blueVector) 

        float2 pos = src.coord();
        float4 pixelColor = src.sample(pos);     // (4)
        
        float3 pixelRGB = pixelColor.rgb;
        
        float3 color = float3(0,0,0);
        if (pos.y < 0.33)                       // (5)
            color = multiplyColor(pixelRGB, redVector);
         else if (pos.y >= 0.33 && pos.y < 0.66) 
            color = multiplyColor(pixelRGB, greenVector);
         else 
            color = multiplyColor(pixelRGB, blueVector);
        

        return float4(color, 1.0);
    

【问题讨论】:

【参考方案1】:

您可以使用源的范围将源坐标转换为相对值,如下所示:

#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h>


extern "C"  namespace coreimage 
    float4 dyeInThree(sampler src, float3 redVector, float3 greenVector, float3 blueVector) 

        float2 pos = src.coord();
        float4 pixelColor = src.sample(pos);

        // transform to relative coordinates
        pos -= src.origin();
        pos /= src.size();

        float3 color = float3(0,0,0);
        if (pos.y < 0.33) 
            color = pixelColor.rgb * redVector;
         else if (pos.y < 0.66) 
            color = pixelColor.rgb * greenVector;
         else 
            color = pixelColor.rgb * blueVector;
        

        return float4(color, pixelColor.a);
    

【讨论】:

谢谢!这行得通!虽然我认为有一些方法可以切换到规范化坐标以避免两个操作的开销:)

以上是关于在 CIFilter 内核中使用归一化采样器坐标的主要内容,如果未能解决你的问题,请参考以下文章

matlab中直方图归一化问题

matlab中NN输入的坐标归一化

在matlab中怎样在同一坐标对多个函数归一化

从四边形坐标获取边界框坐标(xywh)并对其进行归一化

为啥 z 坐标没有被 glm::ortho() 投影归一化?

数据的归一化处理