¿Cuál es el algoritmo detrás de la capa de ajuste "blanco y negro" de Photoshop?

11

¿Alguien puede explicar el algoritmo detrás de la capa de ajuste "Blanco y negro" en Photoshop?

Captura de pantalla de Photoshop

Tengo que reproducirlo usando C ++ para una aplicación que enfatiza píxeles no rojos / magenta (ish) de una imagen (con una tolerancia configurable similar al porcentaje), y este recurso mostró el comportamiento que estoy esperando.


Todavía no podía reproducirlo, pero encontré una pista:

Cada píxel está definido por hasta dos controles, uno aditivo (RGB) y uno sustractivo (CMY).

Blamoo
fuente
¿Alguna vez te acercaste a descifrar el algoritmo? Estoy tratando de resolver esto también.
pizzafilms
No, no lo hice: /
Blamoo

Respuestas:

4

Repliqué el algoritmo perfectamente en MATLAB (Basado en la respuesta 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

Tenga en cuenta que la conversión de vPhotoshopValuesa vCoeffValuesdebe hacerse como vCoeffValues = (vPhotoshopValues - 50) ./ 50.
Como los valores de Photoshop están en [-200, 300] y deben asignarse linealmente en [-5, 5] con 50 -> 0.

Aquí hay una comparación con Photoshop:

ingrese la descripción de la imagen aquí

El error máximo es inferior a 1 en el rango [0, 255].

El código completo está disponible en mi repositorio de GitHub de procesamiento de señales StackExchange Q688 .

Royi
fuente
8

Cada imagen (en color) está compuesta de componentes RGB. cuando agrega (o reduce) un valor constante a todos los píxeles solo en los componentes ROJOS, verá el efecto equivalente a mover la pestaña ROJA hacia la derecha, y de la misma manera, reducir el componente ROJO en una constante tendrá el efecto inverso.

Del mismo modo, puede aumentar / disminuir cada componente en un valor fijo como se describe. Si aumenta / disminuye TODOS los componentes RGB en un mismo valor, esto será equivalente a un cambio en el brillo (básicamente está agregando / eliminando el color BLANCO).

El Cian, Azul, Magenta - corresponde a dicha transformación en el espacio de color CMYK. (Pero supongo que el azul en este espacio de color corresponde a una mezcla de Cian y Amarillo. Entonces, eso es un poco complicado. La transformación es esencialmente la misma para todos.

El último elemento Tinte: {Hue and Saturation} corresponde a las mismas operaciones, pero aquí, las imágenes se transforman primero en el modelo HSV y luego HUE y Saturation se suman / restan de forma independiente.

No sé acerca de las relaciones exactas de los marcadores del dial con los números correspondientes, pero eso se puede averiguar probando valores prácticos.

Dipan Mehta
fuente
1
Hay RGB y CMY, por lo que todo lo que necesita hacer es transformarse en cualquiera de los dos espacios de color y puede ajustar todo lo que desee. Simplemente no olvide actualizar el otro triplete una vez que haya terminado de ajustar.
Jonas
Creo que esta respuesta es incorrecta e incompleta. 1. En la implementación de PS, deslizar el control deslizante "azul" no afecta el brillo de los píxeles cian-ish y deslizar el control deslizante "cian" no afecta el brillo de los píxeles azul-ish. Este enfoque descrito en esta respuesta no funcionaría así. 2. no describe cómo, después de manipular los componentes RGBCMY, se convierten en escala de grises (aunque probablemente sea una dotProduct(color, vec3(0.2989, 0.5870, 0.1140)operación). 3. El azul no "corresponde a una mezcla de cian y amarillo" en ningún espacio de color.
Stefan Monov
4. No menciona que la operación de tinte se realiza después de la conversión a escala de grises y no antes de eso.
Stefan Monov