Qual é o algoritmo por trás da camada de ajuste "preto e branco" do Photoshop?

11

Alguém pode explicar o algoritmo por trás da camada de ajuste "Preto e branco" no photoshop?

Captura de tela do Photoshop

Eu tenho que reproduzi-lo usando C ++ para um aplicativo que enfatiza pixels não vermelhos / magenta (ish) de uma imagem (com uma tolerância configurável em porcentagem), e esse recurso mostrou o comportamento que eu esperava.


Ainda não consegui reproduzi-lo, mas encontrei uma pista:

Cada pixel é definido por até dois controles, um aditivo (RGB) e um subtrativo (CMY).

Blamoo
fonte
Você já chegou mais perto de descobrir o algoritmo? Eu estou tentando descobrir isso também.
pizzafilms
Não, eu não fiz: /
Blamoo 16/05

Respostas:

4

Eu repliquei o algoritmo perfeitamente no MATLAB (com base na resposta de Ivan Kuckir @ ):

function [ mO ] = ApplyBlackWhiteFilter( mI, vCoeffValues )

FALSE   = 0;
TRUE    = 1;

OFF = 0;
ON  = 1;

numRows = size(mI, 1);
numCols = size(mI, 2);
dataClass = class(mI);

numCoeff    = size(vCoeffValues, 1);
hueRadius   = 1 / numCoeff;
vHueVal     = [0:(numCoeff - 1)] * hueRadius;

mHsl = ConvertRgbToHsl(mI);
mO = zeros(numRows, numCols, dataClass);

vCoeffValues = numCoeff * vCoeffValues;

for jj = 1:numCols
    for ii = 1:numRows
        hueVal = mHsl(ii, jj, 1);
        lumCoeff = 0;

        % For kk = 1 we're dealing with circular distance
        diffVal     = min(abs(vHueVal(1) - hueVal), abs(1 - hueVal));
        lumCoeff    = lumCoeff + (vCoeffValues(1) * max(0, hueRadius - diffVal));
        for kk = 2:numCoeff
            lumCoeff = lumCoeff + (vCoeffValues(kk) * max(0, hueRadius - abs(vHueVal(kk) - hueVal)));
        end

        mO(ii, jj) = mHsl(ii, jj, 3) * (1 + lumCoeff);
    end
end


end

Preste atenção que a conversão de vPhotoshopValuespara vCoeffValuesdeve ser feita como vCoeffValues = (vPhotoshopValues - 50) ./ 50.
Como os valores do Photoshop estão em [-200, 300] e devem ser mapeados linearmente em [-5, 5] com 50 -> 0.

Aqui está uma comparação com o Photoshop:

insira a descrição da imagem aqui

O erro máximo é menor que 1 no intervalo [0, 255].

O código completo está disponível no meu Repositório do GitHub do StackExchange Signal Processing Q688 .

Royi
fonte
8

Cada imagem (colorida) é composta por componentes RGB. quando você adiciona (ou reduz) um valor constante a todos os pixels apenas nos componentes RED, você verá o efeito equivalente a mover a guia RED para a direita e, da mesma forma, reduzir o componente RED por uma constante terá o efeito inverso.

Da mesma forma, você pode aumentar / diminuir cada componente por um valor fixo, conforme descrito. Se você aumentar / diminuir TODOS os componentes RGB com o mesmo valor, isso será equivalente à alteração no brilho (basicamente você está adicionando / removendo a cor BRANCA).

Ciano, Azul, Magenta - corresponde a essa transformação no espaço de cores CMYK. (Mas acho que o azul nesse espaço de cores corresponde à mistura de ciano e amarelo. Isso é um pouco complicado. A transformação é essencialmente a mesma para todos.

O último elemento Tint: {Hue and Saturation} corresponde às mesmas operações, mas aqui, as imagens são primeiro transformadas no modelo HSV e, em seguida, HUE e Saturation são adicionados / subtraídos independentemente.

Não sei as relações exatas dos marcadores do mostrador com os números correspondentes, mas você pode descobrir tentando valores práticos.

Dipan Mehta
fonte
11
Há RGB e CMY, então tudo o que você precisa fazer é transformar em qualquer um dos dois espaços de cores e pode ajustar o quanto quiser. Só não se esqueça de atualizar o outro trigêmeo quando terminar de ajustar.
Jonas
Acredito que esta resposta esteja incorreta e incompleta. 1. Na implementação do PS, deslizar o controle deslizante "azul" não afeta o brilho dos pixels ciano-ish e deslizar o controle deslizante "ciano" não afeta o brilho dos pixels azul-ish. Essa abordagem descrita nesta resposta não funcionaria assim. 2. você não descreve como, depois que os componentes RGBCMY são manipulados, eles são convertidos em escala de cinza (embora provavelmente seja uma dotProduct(color, vec3(0.2989, 0.5870, 0.1140)operação). 3. O azul "não corresponde a uma mistura de ciano e amarelo" em nenhum espaço de cor.
Stefan Monov 11/01
4. Você não menciona que a operação de tonalidade é realizada após a conversão em escala de cinza e não antes disso.
Stefan Monov 11/01