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).


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 .


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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.