Самодельный фильтр Chroma Key, который я разработал в OBS-Studio, не может использовать обычный зеленый или синий фон, но его можно использовать в красном - PullRequest
0 голосов
/ 03 марта 2019

Я ссылаюсь на документацию OBS Studio 20.1.0 и chroma_key_filter.effect на github.У меня была проблема с недавним самодельным фильтром obs-studio.Я не могу придумать, как это решить.Я хочу спросить всех здесь, я надеюсь, что я могу получить некоторые предложения или ответы.

Первая проблема заключается в том, что при захвате презентации Power Point, фон устанавливается красным (рисунок 1), а затем яможно получить края текста с помощью моего собственного ядра обнаружения краев, но обычный зеленый (или синий) цвет не будет показывать эффект (рисунок 2)?(Ресурс OBS-studio использует белый фон для удобства просмотра эффекта) введите описание изображения здесь Рисунок 1.

введите описание изображения здесь Рисунок 2.

Вторая проблема заключается в том, что фильтр изменился на другое ядро.Напротив, параметризованная горизонтальная полоса прокрутки не имеет никакого эффекта.Необходимо ли отрегулировать положение, чтобы заставить работать полную маску (рисунок 3)? введите описание изображения здесь Рисунок 3.

Кодовое представление выглядит следующим образом (язык программирования использует язык HLSL или GLSL):

uniform float4x4 ViewProj;
uniform texture2d image;

uniform float4x4 yuv_mat = { 0.182586,  0.614231,  0.062007, 0.062745,
                            -0.100644, -0.338572,  0.439216, 0.501961,
                             0.439216, -0.398942, -0.040274, 0.501961,
                             0.000000,  0.000000,  0.000000, 1.000000};

uniform float4 color;
uniform float contrast;
uniform float brightness;
uniform float gamma;

uniform float2 chroma_key;
uniform float4 key_rgb;
uniform float2 pixel_size;
uniform float similarity;
uniform float smoothness;
uniform float spill;

// 3x3 kernel for convolution edge detection.
uniform float3 kernel1  = { -1.0, -1.0, -1.0};
uniform float3 kernel2    = {-1.0, 8.0, -1.0};
uniform float3 kernel3    = {-1.0, -1.0, -1.0 };

sampler_state textureSampler {
    Filter    = Linear;
    AddressU  = Clamp;
    AddressV  = Clamp;
};

struct VertData {
    float4 pos : POSITION;
    float2 uv  : TEXCOORD0; //Texture coordinates.
};

VertData VSDefault(VertData v_in)
{
    VertData vert_out;
    vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
    vert_out.uv  = v_in.uv;
    return vert_out;
}

float4 CalcColor(float4 rgba)
{
    return float4(pow(rgba.rgb, float3(gamma, gamma, gamma)) * contrast + brightness, rgba.a);
}

float GetChromaDist(float3 rgb)
{
    float4 yuvx = mul(float4(rgb.rgb, 1.0), yuv_mat); //rgb to yuv
    return distance(chroma_key, yuvx.yz);             // Take the distance scalar value of two vectors.
}

float4 SampleTexture(float2 uv)
{
    return image.Sample(textureSampler, uv); 
}

//  3x3 filter of Edge detection
float GetEdgeDetectionFilteredChromaDist(float3 rgb, float2 texCoord)
{
    float distVal = SampleTexture(-texCoord-pixel_size).rgb * kernel1[0];                        // Top left
    distVal += SampleTexture(texCoord-pixel_size).rgb * kernel1[1];                             // Top center
    distVal += SampleTexture(texCoord-float2(pixel_size.x, 0.0)).rgb * kernel1[2];              // Top right

    distVal += SampleTexture(texCoord-float2(pixel_size.x, -pixel_size.y)).rgb * kernel2[0];    // Middle left
    distVal += SampleTexture(texCoord-float2(0.0, pixel_size.y)).rgb * kernel2[1];              // Current pixel
    distVal += SampleTexture(texCoord+float2(0.0, pixel_size.y)).rgb * kernel2[2];              // Middle right

    distVal += SampleTexture(texCoord+float2(pixel_size.x, -pixel_size.y)).rgb * kernel3[0];    // Bottom left
    distVal += SampleTexture(texCoord+float2(pixel_size.x, 0.0)).rgb * kernel3[1];              // Bottom center
    distVal += SampleTexture(texCoord+pixel_size).rgb * kernel3[2];                             // Bottom right

    return distVal;
}


float4 ProcessChromaKey(float4 rgba, VertData v_in)
{
    float chromaDist = GetEdgeDetectionFilteredChromaDist(rgba.rgb, v_in.uv);//Edge detection filter function.

    float baseMask = chromaDist - similarity;
    float fullMask = pow(saturate(baseMask / smoothness), 1.5);
    float spillVal = pow(saturate(baseMask / spill), 1.5);

    rgba.rgba *= color;
    rgba.a *= fullMask;

    float desat = (rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722);
    rgba.rgb = saturate(float3(desat, desat, desat)) * (1.0 - spillVal) + rgba.rgb * spillVal;

    return CalcColor(rgba);
}

float4 PSChromaKeyRGBA(VertData v_in) : TARGET
{
    float4 rgba = image.Sample(textureSampler, v_in.uv);
    return ProcessChromaKey(rgba, v_in);
}

technique Draw
{
    pass
    {
        vertex_shader = VSDefault(v_in);
        pixel_shader  = PSChromaKeyRGBA(v_in);
    }
}

Спасибо!

...