Ejemplos de ImageMagick -- Modificaciones de color
- Ejemplos de ImageMagick: prefacio e índice
- Conversión de color a escala de grises
- Ajustes de nivel de la imagen
- Negativizar imágenes (invertir blanco y negro)
- Operador de ajuste de niveles (ajuste de contraste y de blanco/negro)
- Ajustes de nivel inversos (reducción de contraste)
- Ajuste de nivel por gamma (ajustes de tonos medios)
- Ajuste con el operador gamma (gamma sin ajuste de niveles)
- Ajustes de nivel por color (ajustar los niveles de la imagen mediante colores)
- Contraste no lineal sigmoideo (ajuste de contraste no lineal)
-
Ajustes mediante modificación del histograma (cambiar el histograma de una imagen)
- Normalize (estiramiento automático de niveles)
- Contrast Stretch (estiramiento controlado)
- Linear-Stretch (estiramiento alternativo)
- Redistribución del histograma
- Equalize (redistribución uniforme del histograma)
- Redistribución gaussiana
-
Metodología de redistribución del histograma
Ajustes de nivel DIY (operadores de tintado generales)
- Ajustes no lineales matemáticos
-
Tintar los tonos medios de las imágenes (operadores de tintado generales)
- Tintado de color de tonos medios
- Coloración en tono sepia
- Efecto duotono
- Tintado de color, DIY
- Modular el ciclo de matiz del color
- Modulate DIY
- Modular en otros espacios de color
- Modular en LCHuv y otros espacios de color
- Operador de matriz de color
- Conversión de función a LUT de color
- Manejo de CLUT y transparencia
- Tablas de búsqueda de color Hald 3D
- Limitaciones de Hald CLUT
- Reemplazo de color mediante Hald CLUT
- Reemplazo completo del mapa de colores (sin solución, solo ideas)
Aquí veremos técnicas para modificar todos los colores de una imagen en su conjunto. Ya sea para aclarar u oscurecer la imagen, o para hacer modificaciones de color más drásticas. Para explorar estas técnicas necesitaremos una imagen de prueba...
No te preocupes por cómo generé realmente esta imagen, no es importante para el ejercicio. La diseñé para que contuviera una variedad de colores, transparencias y otras características, específicamente para poner a prueba IM a fondo cuando se utiliza. | ![[IM Output]](../static/img/images/test.png)
---|---
Si de verdad te interesan los comandos usados para generar esta imagen, puedes consultar el script especial "[**generate_test**](../static/img/scripts/generate_test)" que utilizo para crearla. | ADVERTENCIA: Los procesos de color que siguen suponen, por lo general, que la imagen usa un espacio de color lineal. Sin embargo, la mayoría de las imágenes se guardan usando un espacio de color sRGB o corregido por gamma, por lo que, para hacerlo bien, conviene aplicar primero también la corrección de espacio de color.
---|---
Conversión de color a escala de grises
Las imágenes en escala de grises pueden ser muy útiles para muchos usos, como continuar el procesamiento de la imagen original o emplearlas en composiciones de fondo. El mejor método para convertir una imagen a escala de grises es simplemente pedirle a IM que transforme la imagen en una representación de espacio de color en escala de grises.
magick test.png -colorspace Gray gray_colorspace.png
Observa cómo el azul es mucho más oscuro que el rojo, debido a la ponderación que iguala la intensidad tal como la percibe el ojo humano. Es decir, 'red' es un color bastante brillante en comparación con 'blue', que se ve más oscuro. Esto equivale a usar la fórmula de conversión 'rec709luma' con el operador dedicado "[-grayscale](https://imagemagick.org/command-line-options/#grayscale)" (añadido en IM v6.8.3-10). |
magick test.png -grayscale rec709luma gray_grayscale.png
![[IM Output]](../static/img/color_mods/gray_grayscale.png)
El valor 'rec709luma' es solo una de las muchas fórmulas de conversión a escala de grises definidas para usarse con el ajuste "[-intensity](https://imagemagick.org/command-line-options/#intensity)" (ver más abajo). Aquí, por ejemplo, está la otra fórmula común de conversión a escala de grises, 'rec601luma' |
magick test.png -grayscale rec601luma gray_grayscale_601.png
![[IM Output]](../static/img/color_mods/gray_grayscale_601.png)
Como puedes ver, hay una ligera diferencia en los niveles de intensidad de los distintos canales de color rojo, verde y azul.
Sin embargo, existen muchos otros métodos y significados de 'escala de grises'... Por ejemplo, puedes vaciar todo el color de la imagen usando el operador Modulate para fijar todos los niveles de saturación de color a cero. |
magick test.png -modulate 100,0 gray_modulate.png
![[IM Output]](../static/img/color_mods/gray_modulate.png)
Esto convierte esencialmente la imagen al espacio de color HSL y extrae de él el valor de 'Lightness' (luminosidad) en escala de grises. Sin embargo, usando "-define modulate:colorspace" puedes especificar otros modelos de espacio de color. Consulta Modular en otros espacios de color más abajo. Observa que el color 'green' de IM que usé para el disco coloreado del centro de mi imagen de prueba no es en realidad un verde puro, como el empleado en el arcoíris de colores, sino el verde a media intensidad definido por el nuevo estándar SVG -- Scalable Vector Graphics. Si necesitas un verde RGB puro, puedes usar en su lugar el color 'lime'. Consulta Conflictos de nombres de color para más detalles. Otra forma es usar el operador DIY FX para promediar los tres canales y obtener un significado puramente matemático de la escala de grises. |
magick test.png -fx '(r+g+b)/3' gray_fx_average.png
![[IM Output]](../static/img/color_mods/gray_fx_average.png)
| El promedio de los valores de los canales sRGB también equivale al canal de intensidad del espacio de color 'OHTA' (canal rojo). O al canal 'I' del espacio de color HSI.
---|---
Otra técnica consiste en sumar simplemente los tres canales (una medida de color conocida como distancia de Manhattan); aunque la imagen resultante no perderá información por efectos de 'redondeo cuántico', sí puedes perder información sobre los colores más brillantes. Por desgracia, también pierdes el canal de transparencia. |
magick test.png -separate \
-background black -compose plus -flatten gray_added.png
![[IM Output]](../static/img/color_mods/gray_added.png)
Puedes usar la misma técnica de suma de canales para controlar la ponderación de cada canal de color. Por ejemplo, esta es una fórmula DIY que puedes utilizar... |
magick test.png -fx '0.3*r+0.6*g+0.1*b' gray_diy.png
![[IM Output]](../static/img/color_mods/gray_diy.png)
También puedes usar 'intensity' si quieres el mismo significado dentro del operador "[-fx](https://imagemagick.org/command-line-options/#fx)". |
magick test.png -fx intensity gray_intensity.png
Sin embargo, como el operador DIY FX se interpreta, puede ejecutarse muy muy lentamente. Para operaciones más complejas puedes usar el más sencillo operador Evaluate, "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)". Por ejemplo, esta es una imagen en escala de grises con relación 2/5/3, aunque de nuevo no intento preservar el canal de transparencia de la imagen original. | |
magick test.png -channel R -evaluate multiply .2 \
-channel G -evaluate multiply .5 \
-channel B -evaluate multiply .3 \
-channel RGB -separate -compose add -flatten gray_253.png
![[IM Output]](../static/img/color_mods/gray_253.png)
| _Lo anterior sufriría efectos de 'cuantización' en un ImageMagick compilado con un nivel de calidad 'Q8'. Esto se debe a que los resultados de "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" se guardan en un pequeño entero de 8 bits, usado para los valores de la imagen. Solo después se suman esos valores, con la consiguiente pérdida de precisión.
Un ImageMagick compilado con 'Q16', o mejor aún con las opciones de compilación de calidad HDRI, producirá un resultado mucho más exacto. Otra alternativa nueva es el operador Poly -- de fusión ponderada de imágenes, que hará la ponderación y la suma de los canales de imagen separados en una sola operación, evitando así los efectos de 'redondeo cuántico'.
_
---|---
Se puede usar una técnica similar para generar una escala de grises puramente matemática, promediando directamente y por igual los tres canales RGB. |
magick test.png -separate -evaluate-sequence mean gray_average.png
![[IM Output]](../static/img/color_mods/gray_average.png)
Sin embargo, como puedes ver, no intenté preservar el canal alfa de la imagen resultante. Otra alternativa rápida es usar el operador de matriz de color "[-recolor](https://imagemagick.org/command-line-options/#recolor)", que te permite especificar la ponderación de los tres canales de color. |
magick test.png -recolor '.2 .5 .3
.2 .5 .3
.2 .5 .3' gray_recolor.png
![[IM Output]](../static/img/color_mods/gray_recolor.png)
Esto no afecta a la transparencia y constituye una forma mucho mejor de convertir colores usando una ponderación específica. Básicamente, la primera fila de números es la ponderación de canal para el canal rojo de la imagen resultante, los tres siguientes para el verde y los tres últimos para el azul. También puedes usar "[-type](https://imagemagick.org/command-line-options/#type)" para indicarle a IM que trate la imagen como escala de grises, ya sea al leerla o al escribirla. |
magick test.png -type GrayScaleAlpha gray_type.png
![[IM Output]](../static/img/color_mods/gray_type.png)
| El ajuste "[-type](https://imagemagick.org/command-line-options/#type)" se usa por lo general solo como guía cuando una imagen se está leyendo o escribiendo en un archivo. Por ello, su acción se retrasa hasta la escritura final de la imagen. Su efecto también depende en gran medida de las capacidades del formato de archivo de imagen implicado y sirve para anular la determinación normal de ImageMagick durante ese proceso. Consulta los ejemplos de Type para más información.
---|---
| Antes de IM v6.3.5-9, lo anterior habría eliminado, por un error, cualquier transparencia de la imagen escrita (equivalente a un "[-type](https://imagemagick.org/command-line-options/#type) Grayscale"). Esto se corrigió en cuanto noté el problema y lo reporté. (Aquí hay una lección :-)
---|---
Una técnica mucho más interesante es extraer una variedad de significados distintos de brillo extrayendo el canal de color apropiado de las diversas representaciones de espacio de color de la imagen. Para ver ejemplos, consulta Canales de escala de grises a partir de representaciones de espacio de color.
Ajustes de nivel de imagen
La forma más básica de ajuste que puede aplicar a las imágenes se conoce como ajuste de 'nivel'. Esto significa básicamente tomar los valores de color RGB individuales (o incluso los valores del canal alfa) y ajustarlos para estirar o comprimir dichos valores. Como solo se ajustan valores de canal, se demuestran mejor sobre una imagen en escala de grises que sobre una imagen en color. Sin embargo, si ajusta todos los canales de color de una imagen en la misma medida, puede usarlos con imágenes en color, con el fin de realzar o ajustar la imagen. No confunda esto con la forma más automática de ajustes de nivel, que veremos en la siguiente sección principal de ejemplos más abajo, Ajustes de normalización. Esta función realiza exactamente la misma operación con independencia del contenido real de la imagen. No importa si la imagen es clara u oscura, o si tiene un tinte azulado o amarillento. Las operaciones son ciegas al contenido real de la imagen.
Para demostrar estas operaciones usaré una gráfica de "[gnuplot](http://www.gnuplot.info/)" modificada como la que se muestra a la derecha, que genero mediante un script especial "[im_graph](../static/img/scripts/im_graph)". La gráfica tiene una línea roja que asigna el valor 'x' original dado (que representa el valor en escala de grises del degradado superior) al valor 'y' mostrado. El degradado de color resultante también se muestra debajo del degradado lineal de entrada. La gráfica mostrada a la derecha corresponde al operador "[-noop](https://imagemagick.org/command-line-options/#noop)" de IM, que en realidad no hace nada a una imagen. Por ello, cada uno de los valores de color de la imagen se asigna exactamente al mismo valor sin cambios. El degradado inferior es, por tanto, igual al degradado superior.
Negación de imagen
El ajuste de nivel global más simple y básico que puede hacer es negar la imagen, usando el operador de imagen "[-negate](https://imagemagick.org/command-line-options/#negate)". Esencialmente, esto convierte el blanco en negro y el negro en blanco, ajustando todos los colores para que coincidan. Es decir, convertirá el color rojo en su color complementario, el cian, y el azul en amarillo, etc. Puede verlo con la gráfica de asignación mostrada abajo, al usar el operador "[-negate](https://imagemagick.org/command-line-options/#negate)" tanto en la imagen 'test' como en la imagen integrada estándar 'rose' de IM. Observe cómo el degradado inferior de la imagen de la gráfica de asignación está ahora invertido, de modo que el negro y el blanco quedan intercambiados, y cómo esa misma inversión aparece en la imagen 'test' negada.
magick test.png -negate test_negate.png
magick rose: -negate rose_negate.gif
Internamente, negate es en realidad bastante simple. Maneja los tres canales de color de forma independiente y, por defecto, ignora el canal alfa. Si no fuera así, obtendría un resultado muy absurdo como este...
magick test.png -channel RGBA -negate negate_rgba.png
La imagen está negada, como puede ver por el degradado de color semitransparente. Pero como el canal de transparencia también ha sido negado, pierde todos los colores opacos de la imagen. Por eso la configuración por defecto de "[-channel](https://imagemagick.org/command-line-options/#channel)" es 'RGB'. Consulte Canales de color para más información. Puede limitar la negación a un solo canal, por ejemplo el canal de color verde. Esto puede no parecer muy útil, pero a veces es de importancia vital.
magick test.png -channel green -negate negate_green.png
El operador "[-negate](https://imagemagick.org/command-line-options/#negate)" es en realidad su propio inverso. Realizar dos negaciones con la misma configuración de "[-channel](https://imagemagick.org/command-line-options/#channel)" las anula mutuamente.
magick negate_green.png -channel green -negate negate_restore.png
La negación es extremadamente común en el procesamiento de imágenes, especialmente al trabajar con imágenes en escala de grises como paso previo o posterior a otras opciones de procesamiento. Por ello, le recomiendo que experimente con ella y la tenga presente siempre que haga cualquier cosa, ya que trabajar con imágenes negadas puede resolver algunos problemas que de otro modo serían difíciles.
Ajustes de nivel directos
El operador "[-level](https://imagemagick.org/command-line-options/#level)" es el operador de ajuste de nivel más general. Básicamente le da dos valores, un 'black_point' y un 'white_point', así como un tercer valor opcional (ajuste de gamma), que veremos más adelante. Lo que hace es asignar cualquier valor de color de la imagen que sea igual o inferior al 'black_point' y convertirlo en negro (o un valor 0). De forma similar, cualquier valor de color que sea igual o más claro que el 'white_point' lo convertirá en blanco (o un valor máximo). Los colores que quedan entre estos dos puntos se 'estiran' entonces linealmente para llenar todo el rango de valores. El efecto de esto es mejorar el contraste, realzando los colores de una imagen. Por ejemplo, aquí tiene un realce de contraste del 25% de nuestra imagen de prueba, usando los mismos valores que muestra la gráfica. Como habitualmente se ajustan tanto el punto negro como el blanco en la misma medida respecto a los valores 0% y 100%, puede especificar solo el 'black_point'. El punto blanco se ajustará en la misma medida hacia dentro.
magick test.png -level 25%,75% test_level.png
magick rose: -level 25% rose_level.gif
Tenga en cuenta que 25% es un realce de contraste enorme para cualquier imagen, pero muestra claramente lo que hace. No tiene que cambiar a la vez el punto 'negro' y el 'blanco'. En su lugar, es perfectamente admisible ajustar solo un extremo del rango de color. Por ejemplo, podemos crear una imagen de rose muy clara o muy oscura.
magick rose: -level 0,75% rose_level_light.gif
magick rose: -level 25%,100% rose_level_dark.gif
Sin embargo, le advierto de nuevo que los colores fuera del rango dado quedan 'recortados' o 'quemados' y, por tanto, ya no estarán disponibles para un procesamiento de imagen posterior. Este es el mayor problema de usar un operador "[-level](https://imagemagick.org/command-line-options/#level)".
Usando un valor negativo puede hacer una reducción aproximada del contraste de una imagen. Esto significa que, en lugar de proporcionar un valor de color que se asigne a 'negro' y 'blanco' y así estirar los colores intermedios, en su lugar comprime los valores de color para asignar el color negativo imaginario a negro o blanco. El resultado es un agrisamiento general de la imagen. |
magick rose: -level -25% rose_decontrast.gif
Sin embargo, este método de reducir el contraste de una imagen es muy impreciso y no se recomienda, a menos que tenga una versión de IM anterior a la 6.4.2, donde no tiene acceso al nuevo Operador de nivel invertido.
Puede usar el operador "[-level](https://imagemagick.org/command-line-options/#level)" para negar una imagen (como se mostró antes arriba), simplemente intercambiando los valores del punto 'negro' y 'blanco' dados, usando "-level 100%,0". |
magick rose: -level 100%,0 rose_level_neg.gif
O, fijándolos al mismo valor, puede hacer que todos los valores de color de la imagen se sometan efectivamente a un umbral. Usar "[-level](https://imagemagick.org/command-line-options/#level)" para aplicar un umbral a una imagen es exactamente igual que si usara un Operador de umbral con ese valor. La gráfica de asignación mostrada a la derecha muestra los resultados de una operación "-level 50%,50%" y su efecto sobre un degradado en escala de grises. |
magick rose: -level 50%,50% rose_level_thres.gif
Tenga en cuenta que, a diferencia de "[-threshold](https://imagemagick.org/command-line-options/#threshold)", la imagen no se convierte automáticamente en una imagen en escala de grises cuando se usa con la configuración de "[-channel](https://imagemagick.org/command-line-options/#channel)" por defecto. La naturaleza general de usar level para modificar una imagen linealmente hace que el operador "[-level](https://imagemagick.org/command-line-options/#level)" sea bueno para modificaciones generales de imágenes en escala de grises y ajustes de máscara. Si a esto se añade el hecho de que puede modificar canales individuales (usando la configuración de "[-channel](https://imagemagick.org/command-line-options/#channel)") en lugar de la imagen completa, se convierte en uno de los mejores operadores de modificación de color disponibles para los usuarios de IM. |
Tenga en cuenta que también puede usar losOperadores Evaluate y Function para una modificación matemática más directa de los valores de color, logrando los mismos resultados para -level tanto en su forma + como -). |
|---|---|
Tenga cuidado, ya que el operador "[-level](https://imagemagick.org/command-line-options/#level)" trata el canal de transparencia como valores 'mate'. Por ello, el 100% es completamente transparente y el 0% es opaco. Tenga esto en cuenta al usar "[-level](https://imagemagick.org/command-line-options/#level)" con una imagen de forma difuminada. Esto se hace lo más habitualmente después de difuminar una imagen de 'forma', para expandir y estirar los resultados. Para ejemplos de esto, consulte Bordes suaves y Contornos de sombra. |
|
| --- | --- |
Ajustes de nivel invertidos -- Reducción del contraste de imágenes
A partir de la versión 6.4.2 de IM, el Operador de nivel se amplió para proporcionar una forma 'invertida' "[+level](https://imagemagick.org/command-line-options/#level)" (observe el 'plus'). Como alternativa, puede usar la forma original "[-level](https://imagemagick.org/command-line-options/#level)" del operador, pero añadiendo un '!' al argumento de level dado (para interfaces de API más antiguas). Los argumentos de esta variante son exactamente los mismos, pero en lugar de estirar los valores para asignar el 'black_point' y el 'white_point' a 'negro' y 'blanco', asigna 'negro' y 'blanco' a los puntos dados. En otras palabras, "[+level](https://imagemagick.org/command-line-options/#level)" es exactamente lo inverso de "[-level](https://imagemagick.org/command-line-options/#level)". Por ejemplo, aquí asignamos 'negro' a un gris del 25% y blanco a un gris del 75%, reduciendo efectivamente el contraste de la imagen de una forma muy exacta, usando los dos métodos para especificar la forma 'invertida'.
magick test.png +level 25% test_level_plus.png
magick rose: -level 25%\! rose_level_plus.gif
Si compara la operación "+level 25%" anterior con el uso de una reducción de contraste negativa, el operador "-level -25%" que mostramos antes, verá que no son lo mismo. La versión 'plus' produce una imagen con el contraste reducido de forma mucho más intensa (es más gris), pero lo hace asignando a los valores exactos que le da al operador, y no a los valores 'imaginarios' que usaba la forma 'minus'. Este uso de valores exactos es importante y una de las razones por las que se añadió la forma 'plus' del operador. Por supuesto, un '25%' es de nuevo un valor muy grande, y no se recomienda para el trabajo habitual con imágenes. Tenga en cuenta que "[-level](https://imagemagick.org/command-line-options/#level)" y "[+level](https://imagemagick.org/command-line-options/#level)" son, de hecho, exactamente lo inverso uno del otro cuando se les da el mismo argumento. Es decir, uno asigna los valores a los extremos del rango, mientras que el otro asigna desde los extremos del rango. Por ejemplo, aquí comprimimos los colores de la imagen de prueba usando "[+level](https://imagemagick.org/command-line-options/#level)", y luego los descomprimimos de nuevo usando "[-level](https://imagemagick.org/command-line-options/#level)", para restaurar la imagen a un estado cercano a su aspecto original.
magick test.png +level 20% -level 20% test_level_undo.png
Las dos imágenes parecen muy muy similares y, como estoy usando una versión 'Q16' de IM de alta calidad, le costará mucho notar diferencia alguna. Sin embargo, los valores pueden no ser exactamente iguales, ya que ha comprimido efectivamente los valores de color de la imagen a un rango de enteros más pequeño y luego los ha restaurado de nuevo. En casos extremos, esto puede dar lugar a Efectos de redondeo de cuanto. Hacer estas dos operaciones en el orden opuesto (estirar y luego comprimir los valores de color) producirá Efectos de recorte de cuanto. Otro aspecto útil del operador "[+level](https://imagemagick.org/command-line-options/#level)" es que puede comprimir por completo todos los valores de color de una imagen al mismo nivel de escala de grises.
magick test.png +level 30%,30% test_level_const.png
Especificando los niveles según los valores de colores específicos para cada canal individual, puede convertir efectivamente un degradado en escala de grises en un degradado de un color específico. Sin embargo, esto es bastante difícil de calcular y de hacer. Por ello, también se ha proporcionado un operador "[-level-colors](https://imagemagick.org/command-line-options/#level-colors)" que le permite especificar los puntos negro y blanco en términos de colores específicos en lugar de valores de 'nivel'. Consulte Nivel por color más abajo.
Ajustes de gamma de nivel
Ambas variantes anteriores de "[-level](https://imagemagick.org/command-line-options/#level)" también le permiten usar un tercer ajuste: el valor de ajuste de 'gamma'. Por defecto, está fijado en un valor de 1.0, que no realiza ningún tipo de ajuste de los tonos medios de la imagen resultante, produciendo una asignación puramente lineal de los valores de la imagen antigua a la nueva. Sin embargo, al hacer este valor mayor, curvará la línea resultante de modo que aclare la imagen, mientras que reducir ese valor oscurecerá la imagen. Por ejemplo, aquí uso solo el ajuste de 'gamma' para aclarar y oscurecer únicamente los tonos medios de la imagen.
magick rose: -level 0%,100%,2.0 rose_level_gamma_light.gif
magick rose: -level 0%,100%,0.5 rose_level_gamma_dark.gif
Los valores van generalmente desde 10 para una imagen cegadoramente brillante, hasta 0.2 para una imagen muy oscura. Como se ha mencionado, un valor de 1.0 no realizará cambios de 'gamma' en la imagen. Sin embargo, el valor especial de '2.0' (véase arriba) puede usarse para obtener la raíz cuadrada del color normalizado de la imagen. Ambas versiones del operador "[-level](https://imagemagick.org/command-line-options/#level)" manejan la 'gamma' de la misma manera. Esto significa que puede combinar el ajuste de nivel de los extremos 'negro' y 'blanco' con un ajuste de 'gamma' no lineal. También puede ajustar un solo canal de una imagen. Por ejemplo, aquí damos a una imagen un tinte sutil en el extremo negro únicamente del canal azul, usando gamma para preservar los niveles de color de los tonos medios de la imagen.
magick test.png -channel B +level 25%,100%,.6 test_blue_tint.png
Este ejemplo concreto podría usarse para teñir una foto de satélite meteorológico, donde solo el mar es negro puro, mientras que la tierra es más gris. Otras alternativas a este ajuste del canal azul se dan más abajo en Ajustes no lineales matemáticos caseros (DIY).
Ajustes mediante la operación de gamma
El operador "[-gamma](https://imagemagick.org/command-line-options/#gamma)" también se proporciona y tiene exactamente el mismo efecto que el ajuste de 'gamma' del operador "[-level](https://imagemagick.org/command-line-options/#level)". Sin embargo, también le permite ajustar el nivel de ajuste de 'gamma' para cada canal individual. Su uso real está en ajustar la función de 'gamma' de una imagen antes de realizar operaciones lineales sobre ellas. Para más detalles, consulte Percepción humana del color y corrección de gamma. También podemos usar esta función para aclarar la imagen de forma diferente para cada canal RGB individual. |
magick rose: -gamma 0.8,1.3,1.0 gamma_channel.gif
![[IM Output]](../static/img/color_mods/gamma_channel.gif)
Como puede ver, esto puede usarse para hacer algunos tintes y ajustes de color sutiles a una imagen, o para corregir imágenes que contienen demasiado de un color específico. | _Para conocer las razones de por qué debería usar esta función, consulteCorrección de gamma.
_
---|---
Esta función es en realidad equivalente a la función Evaluate POW, pero con el argumento invertido. Por ello, un "-evaluate POW 2.2" realizará en realidad una operación "-gamma 0.45455" (0.45455 es igual a 1/2.2), que es lo inverso de un "-gamma 2.2".
Uno de los usos menos obvios de "[-gamma](https://imagemagick.org/command-line-options/#gamma)" es poner a cero canales de imagen específicos (consulte Poner a cero canales de color). O colorear una imagen completamente de 'negro', 'blanco' o algún otro color primario (consulte Lienzos de colores primarios).
Ajuste de nivel por color
El operador "[-level-colors](https://imagemagick.org/command-line-options/#level-colors)" se añadió a IM v6.2.4-1. Esencialmente, es exactamente igual que el Operador de nivel que comentamos arriba, pero con el valor de cada canal especificado como un valor de color. Es decir, la opción "[-level-colors](https://imagemagick.org/command-line-options/#level-colors)" asignará los colores dados a 'negro' y 'blanco', estirando todos los demás colores entre ellos de forma lineal. Esto elimina efectivamente de la imagen el rango de colores dado. Y aunque funciona, no es especialmente útil, ya que es propenso a fallar con colores que tienen valores comunes en algún canal. Por ejemplo, los colores 'DodgerBlue' y 'White' tienen los mismos valores de color en el canal azul. Por ello, "-level-colors DodgerBlue,White" puede no asignar siempre esos colores a negro y blanco. La mejor técnica en ese caso es extraer una imagen en escala de grises del canal con las mayores diferencias (como el rojo) y aplicar level o normalize a ese canal. ADVERTENCIA: tenga cuidado con los colores 'transparentes'.
La forma plus del operador "[+level-colors](https://imagemagick.org/command-line-options/#level-colors)", por otro lado, es extremadamente útil, ya que asignará el color 'negro' y 'blanco' a los valores dados, comprimiendo todos los demás colores de forma lineal para encajar entre los dos colores que indique. Por ejemplo, asignemos 'black' y 'white' a 'green' y 'gold'...
magick test.png +level-colors green,gold levelc_grn-gold.png
Como puede ver, el degradado en escala de grises se reasigna a un degradado delimitado por los colores dados y, aunque los colores fuera del rango de escala de grises también se modifican, también seguirán el estilo básico del rango de color especificado. Esto hace que el operador "[+level-colors](https://imagemagick.org/command-line-options/#level-colors)" sea extremadamente útil, especialmente al asignar imágenes en escala de grises. Si solo proporciona un nombre de color pero incluye una coma, el color que falta tomará por defecto 'black' o 'white' según corresponda.
magick test.png +level-colors ,DodgerBlue levelc_dodger.png
magick test.png +level-colors ,Gold levelc_gold.png
magick test.png +level-colors ,Lime levelc_lime.png
magick test.png +level-colors ,Red levelc_red.png
magick test.png +level-colors Navy, levelc_navy.png
magick test.png +level-colors DarkGreen, levelc_darkgreen.png
magick test.png +level-colors Firebrick, levelc_firebrick.png
Esto facilita convertir imágenes en escala de grises en un degradado de cualquier color que desee. Por ejemplo, aquí reasigno un degradado en blanco y negro a un degradado en rojo y blanco (observe la ',' en el argumento)...
magick cow.gif +level-colors red, cow_red.gif
Esto no se limitó a reemplazar 'negro' por 'rojo', sino que también reasignó todos los colores grises suavizados (anti-aliasing) a una mezcla adecuada de 'rojo' y 'blanco', produciendo un resultado muy suave.
Si simplemente hubiera realizado un Reemplazo de color directo convirtiendo los colores negros puros en rojo, habría acabado con la horrible imagen (mostrada a la derecha). Consulte Factor de difuminado (Fuzz) para ver el ejemplo usado para generar esa imagen. Por supuesto, si quiere que uno de los colores se haga transparente en su lugar, es mejor que use el operador -alpha Shape, ya que esto requiere que transfiera el degradado al canal alfa.
Si solo especifica un único color, sin ningún separador 'coma', ese color se usará tanto para el punto negro como para el blanco. Esto significa que todos los colores de la imagen se restablecerán a ese único color (según las limitaciones de la configuración actual de "[-channel](https://imagemagick.org/command-line-options/#channel)"). |
magick test.png +level-colors dodgerblue levelc_blue.png
![[IM Output]](../static/img/color_mods/levelc_blue.png)
Este resultado es idéntico a usar "-fill DodgerBlue -colorize 100%" para Colorear imágenes (véase más abajo). Si quiere fijar también el ajuste de transparencia de la imagen, deberá configurar "[-channel](https://imagemagick.org/command-line-options/#channel)" para incluir el canal de transparencia, O fijar el Canal alfa como completamente opaco, usando "-alpha opaque" o "-alpha off". |
magick test.png -channel ALL +level-colors dodgerblue levelc_blue2.png
![[IM Output]](../static/img/color_mods/levelc_blue2.png)
Consulte también Vaciar imágenes existentes. Aquí tiene unos cuantos ejemplos más de uso de esto para ajustar o 'teñir' una imagen colorida, en lugar de una imagen en escala de grises.
magick rose: +level-colors navy,lemonchiffon levelc_faded.gif
magick rose: +level-colors firebrick,yellow levelc_fire.gif
magick rose: +level-colors 'rgb(102,75,25)',lemonchiffon levelc_tan.gif
En resumen, "[+level-colors](https://imagemagick.org/command-line-options/#level-colors)" es un reemplazo de color por degradado, un operador de tintado lineal y también puede restablecer colores por completo.
Contraste por no linealidad sigmoidal
A partir de un artículo en PDF sobre 'Fundamentos del procesamiento de imágenes' (página 44), se presenta una alternativa al uso de un control de contraste lineal (level), mediante uno que usa corrección de gamma conocido como 'control de contraste por no linealidad sigmoidal'. El resultado es un cambio de contraste no lineal y suave (una 'función sigmoidal' en términos matemáticos) sobre todo el rango de color, preservando los colores blanco y negro, mucho mejor para los ajustes de color de fotografías. La fórmula exacta del artículo es muy compleja, e incluso tiene un error, pero esencialmente requiere dos valores de ajuste. Un nivel de umbral en el que centrar la función de contraste (típicamente centrado en '50%') y un factor de contraste ('10' siendo muy alto, y '0.5' muy bajo). | Para los interesados, la fórmula corregida del 'control de contraste por no linealidad sigmoidal' es... ( 1/(1+exp(**β** *(**α** -u))) - 1/(1+exp(**β** *(**α**)) ) / ( 1/(1+exp(**β** *(**α** -1))) - 1/(1+exp(**β** * **α**)) ) _Dondeα es el nivel de umbral, y β el factor de contraste a aplicar.
Aquí tiene una versión alternativa de la fórmula usando variables intermedias. x = exp(**β** * (**α** - u)) y = exp(**β** + 1 result (x / y + 1) * (1 / (x + 1) - 1 / y) _La fórmula es en realidad una curva exponencial muy simple, y el grueso de la fórmula anterior está diseñado para asegurar que 0 siga siendo cero y 1 siga siendo uno. Es decir, la gráfica siempre pasa por los puntos 0,0 y 1,1. Y el mayor gradiente de cambio está en el umbral dado.
---|---
Aquí, por ejemplo, hay una implementación con "[-fx](https://imagemagick.org/command-line-options/#fx)" de la fórmula anterior, resultante de un valor de contraste muy alto de '10' y un valor de umbral del '50%'. Estos valores se han incorporado a las constantes de punto flotante para acelerar la función.
magick test.png -fx '(1/(1+exp(10*(.5-u)))-0.006693)*1.013567' \
sigmoidal.png
Por suerte para nosotros, IM v6.2.1 tenía esta compleja función integrada como un nuevo operador "[-sigmoidal-contrast](https://imagemagick.org/command-line-options/#sigmoidal-contrast)", lo que permite una aplicación mucho más sencilla. |
magick test.png -sigmoidal-contrast 10,50% test_sigmoidal.png
![[IM Output]](../static/img/color_mods/test_sigmoidal.png)
Como extra, IM también proporciona la inversa, una función de 'reducción de contraste sigmoidal' (como forma plus '+' del operador), que, si se aplica con los mismos argumentos, restaura nuestra imagen original (casi exactamente). |
magick test_sigmoidal.png +sigmoidal-contrast 10,50% \
test_sigmoidal_inv.png
![[IM Output]](../static/img/color_mods/test_sigmoidal_inv.png)
Y aquí lo aplicamos a la imagen de rose... |
magick rose: -sigmoidal-contrast 10,50% rose_sigmoidal.gif
![[IM Output]](../static/img/color_mods/rose_sigmoidal.gif)
Ya dije que '10' era un factor de contraste muy intenso. De hecho, cualquier valor superior a este puede considerarse más como una operación de umbral difuso que como un realce de contraste. Para un ejemplo práctico del uso de este operador, consulte el ejemplo avanzado Efectos "Gel", donde se usa para dar nitidez al área brillante que se añade al color de un área con forma.
Operadores de contraste varios
En construcción
-contrast and +contrast
Operador de ajuste menor de contraste, bastante inútil
<a id="threshold"></a>-threshold
Aplica un umbral a la imagen; cualquier valor menor o igual al valor dado se
fija a 0 y cualquier valor mayor se fija al valor máximo.
Tenga en cuenta que, como level, este es un operador de canal, pero si se usa
la 'configuración de canal' por defecto, solo se aplica el umbral a la
intensidad en escala de grises de la imagen, produciendo una imagen en blanco y negro.
magick rose: -threshold 45% x:
Puede forzar el comportamiento normal de canal, donde a cada canal se le aplica
el umbral individualmente, usando "-channel All"
magick rose: -channel All -threshold 45% x:
<a id="black-threshold"></a>-black-threshold
<a id="white-threshold"></a>-white-threshold
Esto es como -threshold, salvo que solo se modifica realmente uno de los
lados del valor de umbral.
Por ejemplo, aquí todo lo que sea más oscuro que el 30% se fija a negro.
magick rose: -black-threshold 30% x:
magick rose: -white-threshold 50% x:
Sin embargo, estos operadores no parecen verse afectados por el canal, por lo que
quizá solo sean adecuados para imágenes en escala de grises.
Ajustes mediante modificación del histograma
Esta sección fue un esfuerzo conjunto deFred Weinhaus y Anthony Thyssen. ¿Qué es un histograma? Un histograma es un tipo especial de gráfico. Simplemente clasifica los niveles de color de los píxeles de una imagen en un número fijo de 'contenedores' (bins), cada uno de los cuales abarca un pequeño rango de valores. Así, cada contenedor incluye un recuento del número de niveles de color (valores de píxel) de la imagen que caen dentro de ese rango. El resultado es una representación de cómo se distribuyen los valores de color que componen una imagen, desde el negro a la izquierda hasta el blanco a la derecha. El histograma puede generarse para cada canal por separado o como un histograma global que considera los valores de todos los canales combinados. El resultado suele mostrarse como una imagen de un gráfico de barras. En IM, esto se hace usando el formato de salida especial Histogram:. Por ejemplo... |
magick rose: histogram:histogram.gif
![[Salida de IM]](../static/img/color_mods/histogram.gif)
Pero también puede mostrarse como un gráfico de líneas en el que la línea conecta las cimas de las barras. Esto se demostrará más adelante en la discusión siguiente. Consulte Histogram: para más detalles sobre este formato de salida especial. Su lectura es recomendable en este punto, ya que es la mejor manera de extraer información del histograma de las imágenes usando IM. La altura real de un gráfico de histograma tiene poco significado real, ya que normalmente se escala de modo que el pico más alto toque la parte superior de la imagen. Por ello, la altura de cada 'barra' individual no es relevante. Lo que es mucho más importante es la distribución del histograma sobre todo el rango, y cómo las alturas relativas se relacionan entre sí en el conjunto del gráfico. Al observar un histograma se considerarían los siguientes factores.
- ¿Forma el histograma una banda ancha de valores? Esto significa que la imagen hace un amplio uso del espacio de color y, por tanto, tiene un buen contraste.
- ¿O está todo en un grupo apretado en el centro o en un extremo del rango? Esto significa que la imagen tiene un contraste bajo, lo que le da un aspecto 'brumoso' o 'agrisado', o quizá excesivamente claro u oscuro.
- ¿Forma dos o más picos? Como resultado de áreas o regiones muy diferentes en la imagen.
- ¿Dónde están la mayoría de los píxeles? A la izquierda, lo que significa que la imagen es muy oscura. O a la derecha, lo que significa que es muy brillante. ¿O repartidos alrededor del centro?
- ¿Hay huecos regulares o espacios vacíos entre barras individuales? Esto suele significar o bien que la imagen tiene muy pocos píxeles, por lo que no pudo llenar por completo todo el histograma, o bien que la imagen fue reducida en color, o modificada de algún modo, de manera que se produjeron esos huecos.
Esencialmente, un histograma es una representación más sencilla de una imagen y, como tal, es mucho más fácil cambiar o ajustar una imagen en términos de su histograma. Casi cualquier transformación de color matemática que se aplique a una imagen normalmente provocará no solo que la imagen se modifique, sino también su histograma. Esto incluye operaciones lineales como el operador Level u operaciones no lineales como el operador Gamma, (véase arriba). Los gráficos de mapeo que vimos arriba representan cómo se transforman los niveles de gris de una imagen y, por tanto, cómo se transforma el histograma de la imagen. Por ejemplo, hagamos una imagen de bajo contraste para demostrarlo. Sin embargo, el resultado final es que no solo modifica la imagen, sino que lo hace modificando el histograma de la imagen (comprimiéndolo).
magick chinese_chess.jpg -contrast -contrast -contrast -contrast \
chinese_contrast.png
magick chinese_chess.jpg histogram:chinese_chess_hist.gif
magick chinese_contrast.png histogram:chinese_contrast_hist.gif
En el caso anterior, "-contrast" es un sencillo operador de tipo Level que añade solo un poco más de contraste a la imagen. El resultado es que el histograma en sí se ensancha más, haciendo que cubra mejor todo el rango de color posible. También puede verse, a partir de los histogramas de antes y después, que los colores acabarán teniendo huecos y agujeros entre los 'contenedores', debido a la forma en que se realizó el estiramiento. En concreto, crea un 'histograma' colocando todos los colores en 'contenedores'. Estos colores 'agrupados en contenedores' se modifican entonces en conjunto, lo que provoca que los colores de la imagen queden agrupados. No es una manera particularmente buena de tratar los colores de una imagen. Sin embargo, este operador trabaja a ciegas, sin ningún conocimiento del contenido de la imagen ni de la distribución de color. Por ello, no puede aplicarse sin algún control del usuario, ya que el operador podría con mucha facilidad empeorar cualquier imagen a la que se aplique, en lugar de mejorarla. En esta sección examinaremos operadores de procesamiento de imágenes que estudian el histograma de la imagen como parte de su proceso de toma de decisiones. Luego modifican las imágenes usando el resultado de ese estudio, para realzar alguna cualidad de la distribución de color de la imagen. Como estos operadores hacen uso de información real procedente de la imagen que se procesa, a menudo pueden usarse de forma más global sobre muchas imágenes sin demasiada comprobación por parte del usuario. Los operadores de este tipo incluyen operadores lineales automáticos de tipo 'level' como "[-normalize](https://imagemagick.org/command-line-options/#normalize)", "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" y "[-linear-stretch](https://imagemagick.org/command-line-options/#linear-stretch)", pero también otros no lineales como "[-equalize](https://imagemagick.org/command-line-options/#equalize)", y otros que con el tiempo podrían incluirse en ImageMagick, como el script "redist" de Fred Weinhaus.
Estiramiento del histograma
Las técnicas más sencillas, como el ejemplo anterior, simplemente estiran el histograma de la imagen hacia afuera para mejorar el rango de color. Sin embargo, en lugar de elegir a ciegas el punto negro y el punto blanco para la operación Level, seleccionan los puntos basándose en el histograma de la imagen. Básicamente, cuentan el número de valores de color de cada contenedor del histograma, desde cada uno de los dos extremos hacia adentro, hasta alcanzar cierto umbral. Estos puntos se usarán entonces como el punto negro y el punto blanco para el estiramiento del histograma (level). Se necesita un diagrama Básicamente, los recuentos del histograma proporcionan los valores de nivel de gris que el estiramiento forzará a negro y blanco. Esto significa que todos los píxeles de la imagen que caigan dentro del rango de contenedores desde el negro puro hasta el nivel de gris correspondiente al contenedor del punto negro seleccionado acabarán siendo negro puro. Del mismo modo, los píxeles de la imagen que caigan dentro del rango de contenedores desde el blanco puro hasta el nivel de gris correspondiente al contenedor del punto blanco acabarán siendo blanco puro. Sin embargo, los píxeles que estén fuera de estos puntos habrán sido estirados fuera del rango de valores de color posible y, como resultado, simplemente se fijarán en los límites del rango. Es decir, estos píxeles quedan 'recortados' o 'quemados' al convertirse en los valores de color extremos del negro puro o del blanco puro. Por ello, si los límites de 'umbral' para seleccionar el punto negro y el punto blanco se fijan demasiado altos, obtendrá muchas áreas blancas y negras en la imagen, con el histograma resultante mostrando grandes recuentos (barras altas) en los contenedores de los extremos. ¿Ejemplo de quemado severo -- imagen de Chinese Chess? Resumen de los operadores de 'estiramiento'... -contrast-stretch y -linear-stretch generan ambos un histograma (usando 1024 contenedores) para determinar la posición de color que estirar. por ello no es 'exacto'. La otra diferencia es cómo se maneja el 'cero', y que -linear-stretch realmente realiza una operación -level para hacer el estiramiento, mientras que -contrast-stretch usa los valores de los contenedores del histograma para el estiramiento por reemplazo de color (lo que introduce un efecto de redondeo de 1024 cuantos). -normalize usa -contrast-stretch internamente. Un operador de estiramiento de normalización matemáticamente perfecto es -auto-level. Aunque es posible una versión perfecta de 'solo punto blanco' o 'solo punto negro', no se ha implementado por el momento.
Auto-Level - normalización matemática perfecta
El "[-auto-level](https://imagemagick.org/command-line-options/#auto-level)" encuentra los valores mayor y menor de la imagen para usarlos al estirar la imagen al rango de cuantos completo. En ningún momento los valores quedarán 'recortados' o 'quemados' como resultado de que el histograma se estire más allá del rango de valores. El ajuste "[-channel](https://imagemagick.org/command-line-options/#channel)" determinará si todos los canales se estiran por igual 'en sincronía' (usando el máximo y el mínimo de todos los canales) o por separado (cada canal individual como una entidad separada). Por el momento, el color oculto de los píxeles totalmente transparentes también se utiliza para determinar los niveles, lo que puede causar algunos problemas cuando hay transparencia de por medio. Esto se considera un error.
FUTURO: En realidad necesitamos tres modos de funcionamiento...
canales de color sincronizados con enmascaramiento 'alpha' (y 'read').
canales sincronizados (según los defina channel) (predeterminado actual)
canales separados individuales (actualmente si el usuario fija -channel)
Es un estiramiento del histograma puramente matemático, igual que el operador Level manual. Es decir, el mínimo se ajustará a cero y el máximo al rango de cuantos, y se usa una ecuación lineal para ajustar todos los demás valores de la imagen. No usa 'contenedores del histograma' ni ninguna otra 'agrupación de valores' que otros métodos puedan usar, ya sea para determinar los niveles que emplear, o para otros ajustes del histograma.
Normalize
El operador "[-normalize](https://imagemagick.org/command-line-options/#normalize)" es el más sencillo de estos tres operadores. Simplemente expande el histograma de escala de grises para que ocupe todo el rango dinámico de valores de gris, mientras recorta o quema un 2% en el extremo bajo (negro) y un 1% en el extremo alto (blanco) del histograma. Es decir, el 2% de los grises más oscuros de la imagen se convertirán en negro y el 1% de los grises más claros se convertirán en blanco. Esto no es una gran pérdida en la mayoría de las imágenes, y el resultado global es que el contraste (rango de intensidad) de la imagen se maximizará automáticamente. ¡Aquí se necesita un diagrama idealizado!__¿Ejemplo usando chinese chess? Aquí creamos un degradado de escala de grises y lo expandimos al rango completo de negro y blanco.
magick -size 150x100 gradient:gray70-gray30 gray_range.jpg
magick gray_range.jpg -normalize normalize_gray.jpg
| _Por razones prácticas relacionadas con las imprecisiones de color del JPEG (véaseDistorsión de color del JPEG para más detalles) y el ruido de las imágenes escaneadas, "[-normalize](https://imagemagick.org/command-line-options/#normalize)" no expande los colores más brillantes y oscuros exactos, sino un poco más allá de esos valores. Es decir, equivale a un "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" con un valor de '2%,99%' (véase abajo).
Esto significa que si los valores de color más alto y más bajo están muy juntos, "[-normalize](https://imagemagick.org/command-line-options/#normalize)" fallará, y no se realizará ninguna acción.
Si realmente quiere expandir los valores de color más brillante y más oscuro exactos hasta sus extremos, use "[-auto-level](https://imagemagick.org/command-line-options/#auto-level)" en su lugar._
---|---
Hasta la versión de IM 6.2.5-5, "[-normalize](https://imagemagick.org/command-line-options/#normalize)" funcionaba puramente como un operador de escala de grises. Es decir, cada uno de los canales rojo, verde, azul y alfa se expandía independientemente de los demás según el ajuste "[-channel](https://imagemagick.org/command-line-options/#channel)". A partir de la versión de IM 6.2.5-5, si solo se da el ajuste predeterminado "[+channel](https://imagemagick.org/command-line-options/#channel)", entonces "[-normalize](https://imagemagick.org/command-line-options/#normalize)" vinculará todos los canales de color y los normalizará todos en la misma medida. Esto garantiza que los colores de los píxeles dentro de la imagen no se desplacen. Sin embargo, también significa que puede que no obtenga un píxel de color blanco o negro puro. Por ejemplo, aquí añadimos algunos colores extra (un degradado de azul a azul marino) a nuestra imagen de prueba de normalización.
magick -size 100x100 gradient:gray70-gray30 \
-size 50x100 gradient:blue-navy +append color_range.jpg
magick color_range.jpg -normalize normalize.jpg
Como puede ver en el último ejemplo, para las imágenes en color "[-normalize](https://imagemagick.org/command-line-options/#normalize)" maximizó todos los canales juntos, de modo que un canal tiene un valor de cero y otro canal tiene un valor máximo. Es decir, no se generaron píxeles negros, ya que todos los colores azules añadidos ya contienen valores 'cero' en los canales 'rojo' y 'verde'. Por ello, los límites inferiores de la imagen no se expandieron. Si quiere el comportamiento antiguo de "[-normalize](https://imagemagick.org/command-line-options/#normalize)" (anterior a IM v6.2.5-5), tendrá que especificar cualquier ajuste "[-channel](https://imagemagick.org/command-line-options/#channel)" no predeterminado. Para imágenes que no contienen canal alfa (o mate), puede usar simplemente el ajuste de canal 'all'. |
magick color_range.jpg -channel all -normalize normalize_all.jpg
![[Salida de IM]](../static/img/color_mods/normalize_all.jpg)
Alternativamente, puede normalizar cada canal como una imagen separada usando el operador "[-separate](https://imagemagick.org/command-line-options/#separate)" (a partir de IM v6.2.9-2), y luego "[-combine](https://imagemagick.org/command-line-options/#combine)" para combinarlos de nuevo en una sola imagen. |
magick color_range.jpg -separate -normalize -combine normalize_sep.jpg
![[Salida de IM]](../static/img/color_mods/normalize_sep.jpg)
En estos dos últimos ejemplos, vemos que las áreas de escala de grises de la imagen se volvieron amarillas, ya que los canales 'rojo' y 'verde' se aclararon, mientras que el canal 'azul' solo se oscureció ligeramente. Esto nos lleva a un punto importante
Normalize y otros operadores de histograma son en realidad operadores de escala de grises,
se necesita precaución al usarlos con imágenes en color.
De hecho, "[-normalize](https://imagemagick.org/command-line-options/#normalize)" es solo un subconjunto del más general "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" con valores predeterminados de punto negro 2% y punto blanco=1%. Entonces, ¿qué es "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)"?
contrast-stretch
El operador "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" (añadido en IM v6.2.6) es similar a "[-normalize](https://imagemagick.org/command-line-options/#normalize)", salvo que permite al usuario especificar el número de píxeles que se recortarán o quemarán. Es decir, le proporciona cierto control sobre la selección del 'punto negro' y el 'punto blanco' que usará para el estiramiento del histograma. Así, el usuario especifica un recuento (o recuentos en porcentaje) de los grises más oscuros de la imagen que se convertirán en negro y el recuento de los grises más claros que se convertirán en blanco. Por ejemplo, esto reemplazará tanto el 15% superior como el inferior de los colores por sus extremos (blanco y negro), estirando apropiadamente el resto del 70% de los colores. El resultado final es intentar mejorar el contraste global de la imagen.
magick gray_range.jpg -contrast-stretch 15% stretch_gray.jpg
También puede ver fácilmente los efectos de 'quemado' y 'recorte' en la parte superior e inferior del degradado anterior, ya que esos colores grises se estiran mucho más allá de los límites del rango de color. Y aquí 'quemo' deliberadamente el 90% de los grises más oscuros, dejando solo el 10% de los píxeles más brillantes para estirarlos en un degradado lineal apretado en la parte superior de la imagen. |
magick gray_range.jpg -contrast-stretch 90%x0% stretch_black.jpg
![[Salida de IM]](../static/img/color_mods/stretch_black.jpg)
Esto puede ser bastante útil para encontrar los 'N' píxeles más brillantes de una imagen, ya que serán los únicos que no queden 'quemados' a un valor de cero. (Una manera mejor es usar "[-threshold-black](https://imagemagick.org/command-line-options/#threshold-black)") Un aspecto importante de "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" es el uso de cero para los recuentos de umbral del punto negro y el punto blanco. En este caso, "-contast-stretch 0" localizará los contenedores mínimo y máximo del histograma de la imagen. Dado que los recuentos comienzan realmente en estos contenedores, el resultado es simplemente estirar los contenedores mínimo y máximo hasta el negro completo y el blanco completo. Esto dará como resultado un estiramiento de contraste con una cantidad mínima o posiblemente nula de recorte, con todos los valores de esos 'contenedores' convirtiéndose en 0 y valores máximos.
Linear-Stretch
En muchos aspectos, "[-linear-stretch](https://imagemagick.org/command-line-options/#linear-stretch)" es muy similar al operador "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" anterior. Ambas funciones pueden tomar argumentos de punto negro y punto blanco, ya sea como recuentos en bruto o como porcentajes del número total de píxeles involucrados. Sin embargo, hay varias diferencias importantes. Una diferencia tiene que ver con cómo se calculan el punto negro y el punto blanco predeterminados. Con "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)". Si solo se proporciona un valor, el punto negro, entonces el punto blanco será el mismo valor. Así, "-contrast-stretch 1" equivale a "-contrast-stretch 1x1" y "-contrast-stretch 1%" equivale a "-contrast-stretch 1x1%"". Sin embargo, con "[-linear-stretch](https://imagemagick.org/command-line-options/#linear-stretch)", si solo se proporciona un valor, el punto negro, entonces el punto blanco será el valor complementario. Es decir, si el punto negro se especifica como un recuento en bruto, entonces el punto blanco será el total de píxeles de la imagen menos el recuento del punto negro. Del mismo modo, si el punto negro se especifica como un recuento en porcentaje, entonces el punto blanco será el 100% menos el recuento en porcentaje del punto negro. Así, "-linear-stretch 1%" equivaldrá a "-linear-stretch 1x99%". La segunda diferencia tiene que ver con dónde comienzan los recuentos. Considere un histograma con 256 contenedores (algunos 'contenedores' pueden tener recuentos de cero) que va del nivel de gris 0 al nivel de gris 255. En "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)", los recuentos comienzan en cero con los contenedores poblados más bajo (mín) y más alto (máx) de la imagen (que pueden estar o no en el contenedor 0 o el contenedor 255 del histograma). Así, un punto negro del 10% acumulará recuentos de todos los contenedores posteriores al contenedor mínimo hasta alcanzar el 10% y estirará el lado negro desde ese nivel de gris. Por ello, la cantidad quemada en el lado negro del histograma acabará siendo el 10% más lo que ya se encontraba en los 'contenedores' más oscuros anteriores. Lo mismo ocurre al contar desde el lado brillante del histograma. Con "[-linear-stretch](https://imagemagick.org/command-line-options/#linear-stretch)", el recuento comienza en los extremos del histograma, es decir, en el contenedor 0 y el contenedor 255. Así, la cantidad quemada en el lado oscuro será siempre el valor del punto negro y la cantidad de quemado en el lado brillante será siempre el valor del punto blanco. Como ejemplo, tomemos un degradado de 100 píxeles y observemos su histograma. |
magick -size 1x100 gradient: \
-depth 8 -format "%c" histogram:info:
Como era de esperar, cada contenedor está igualmente poblado con un solo píxel, produciendo un recuento de 1. (Para ver el listado completo, haga clic en la imagen de texto de salida de arriba). Ahora hagamos lo mismo después de usar "-contrast-stretch 10x10%"
magick -size 1x100 gradient: -contrast-stretch 10x10% \
-depth 8 -format "%c" histogram:info:
Y ahora "-linear-stretch 10x10%".
magick -size 1x100 gradient: -linear-stretch 10x10% \
-depth 8 -format "%c" histogram:info:
Así confirmamos que para "-contrast-stretch 10x10%" obtenemos 11 píxeles en cada extremo. Es decir, equivale al recuento de los contenedores de los extremos más el 10% de los píxeles de la imagen, que es igual a 10 píxeles. Así que 10+1=11 píxeles quemados. Por otra parte, en "-linear-stretch", los contenedores de los extremos acaban conteniendo solo 10 píxeles, o el 10% de la imagen. Una consecuencia de la diferencia antes mencionada es que "-contrast-stretch 0x0" puede cambiar la imagen, si los contenedores poblados más bajo o más alto no son los contenedores de los extremos en 0 y 255. En este caso, la imagen se estirará entre los niveles de gris correspondientes a esos contenedores. Por otra parte, "-linear-stretch 0x0" nunca cambiará la imagen. Por ejemplo, tomemos el degradado y comprimamos sus niveles de gris en un 10% en cada extremo. Es decir, subiremos el punto negro un 10% al nivel de gris 26 y bajaremos el punto blanco un 10% al nivel de gris 230.
magick -size 1x100 gradient: +level 10x90% \
-depth 8 -format "%c" histogram:info:
Ahora, apliquemos "-contrast-stretch 0x0" al degradado descontrastado anterior
magick -size 1x100 gradient: -level 10x90% -contrast-stretch 0x0 \
-depth 8 -format "%c" histogram:info:
Y ahora "-linear-stretch 0x0"
magick -size 1x100 gradient: -level 10x90% -linear-stretch 10x10% \
-depth 8 -format "%c" histogram:info:
Así vemos que la imagen original tenía un histograma que no abarcaba el rango dinámico completo de 0 a 255. Solo iba entre los niveles de gris 26 y 230. Pero tras aplicar "-contrast-stretch 0x0", se estiró al rango dinámico completo. Por otra parte, "-linear-stretch 0x0" no produjo ningún cambio en el histograma resultante. La tercera diferencia es que "-contrast-stretch" es sensible a los canales, mientras que "-linear-stretch" no lo es. Esto significa que con "-contrast-stretch" se pueden cambiar uno o más canales cualesquiera sin afectar a los demás. Así, si no se especifica ningún canal, el histograma global de todos los canales se usará para modificar todos los canales de la misma manera, de modo que no se produzcan desplazamientos de color. Sin embargo, si se especifica "-channel RGB", entonces cada canal se estirará por separado y el resultado dependerá de los contenedores de los extremos de cada canal. Si son diferentes, se producirá un desplazamiento de color entre los canales individuales de la imagen resultante. Con "-linear-stretch", todos los canales se procesarán de manera común, asegurando así que no se produzcan desplazamientos de color de los canales entre sí. Así que obtengamos un identify verboso y el histograma de una imagen real.
magick port.png -verbose -identify +verbose histogram:port_hist.gif
Vemos que ninguno de los canales de la imagen anterior abarca el rango dinámico completo. Observe también que cada uno de los canales abarca un rango de valores diferente y único. Ahora apliquemos "-contrast-stretch 1x1%" sin un ajuste "[-channel](https://imagemagick.org/command-line-options/#channel)".
magick port.png -contrast-stretch 1x1% \
-write histogram:port_cs1_hist.gif port_cs1.png
En el resultado anterior, la imagen se estira de forma consistente en todos los canales. Por ello, no hay desplazamientos de color entre canales. Ahora hagamos lo mismo, pero con "-channel RGB".
magick port.png -channel RGB -contrast-stretch 1x1% \
-write histogram:port_cs1rgb_hist.gif port_cs1rgb.png
En el resultado anterior, debido a que fijamos "-channel RGB", en lugar de usar el ajuste de canal predeterminado, la imagen se estira de manera diferente para cada canal. Esto provoca un desplazamiento de color entre canales. Ahora apliquemos "-linear-stretch" sin un ajuste "-channel".
magick port.png -linear-stretch 1x1% \
-write histogram:port_ls1_hist.gif \
port_ls1.png
En el resultado anterior, la imagen se estira de forma consistente en todos los canales. Así que no hay desplazamiento de color entre canales. Ahora hagamos lo mismo, pero con "-channel RGB".
magick port.png -channel RGB -linear-stretch 1x1% \
-write histogram:port_ls1rgb_hist.gif port_ls1rgb.png
En el resultado anterior con "-linear-stretch", la imagen se estira de forma consistente en todos los canales y "-channel RGB" se ignora. Por ello no hay desplazamiento de color entre canales y el resultado es idéntico al de arriba sin "-channel RGB".
Redistribución del histograma
La redistribución del histograma es una técnica no lineal que redistribuye los contenedores de un histograma para lograr una forma particular. Las dos formas más comunes son la uniforme (plana) y la gaussiana (en forma de campana), aunque también se han usado otros tipos de distribuciones como la hiperbólica y la de Rayleigh.
Equalize - Redistribución uniforme del histograma
En el caso de una distribución uniforme, los contenedores del histograma se desplazan, espacian y combinan de modo que, en promedio, el histograma tenga una altura plana o constante en todo el rango. Esto se llama ecualización del histograma. La función de IM "[-equalize](https://imagemagick.org/command-line-options/#equalize)" hace esto. Lamentablemente, opera sobre cada canal por separado, en lugar de aplicar la misma operación a todos los canales. Por ello, son posibles los desplazamientos de color cuando se aplica al espacio de color RGB. Aquí hay un ejemplo de ecualización del histograma usando la función de IM -equalize. Observe el desplazamiento del balance de color debido a la ecualización de cada canal de forma independiente.
magick zelda.png -write histogram:zelda_hist.gif \
-equalize -write histogram:zelda_equal_hist.gif \
zelda_equal.png
Puede que note que el histograma no parece muy uniforme. Pero si convertimos la imagen resultante a escala de grises y mostramos su histograma, su histograma parece un poco más uniforme en comparación con el histograma de escala de grises de la imagen original
magick zelda.png -colorspace gray histogram:zelda_ghist.gif
magick zelda_equal.png -colorspace gray \
histogram:zelda_equal_ghist.gif
La otra manera de abordar la redistribución de los contenedores es usando una tabla de búsqueda de transformación que se genera a partir de los histogramas acumulativos separados de cada canal y la curva de distribución integrada deseada. Si no se desea ningún desplazamiento de color entre canales, entonces se usa el histograma combinado de todos los canales de la imagen. Una aproximación es simplemente usar el histograma de la imagen tras convertirla a escala de grises. Fred Weinhaus ha desarrollado un script, llamado "redist" que hace precisamente eso. Redistribuye el histograma de una imagen en una distribución uniforme, aplicando el mismo cambio a todos los canales de color por igual.
redist -s uniform zelda.png zelda_uniform.png
magick zelda_uniform.png histogram:zelda_uniform_hist.gif
Observe cómo los resultados difieren del operador "[-equalize](https://imagemagick.org/command-line-options/#equalize)" integrado de IM. En concreto, todos los colores se conservan, sin el desplazamiento de color que vio anteriormente. Lo que hace el script es trabajar sobre el histograma de escala de grises, que luego aplica a todos los canales de color, de modo que todos los colores se mantienen juntos. Para comparar con los histogramas de "[-equalize](https://imagemagick.org/command-line-options/#equalize)" de IM, mostremos aquí también los resultados del histograma de escala de grises. Observe que el histograma redistribuido parece estar un poco más nivelado (plano, o uniforme) que el del equalize de IM.
magick zelda.png -colorspace gray histogram:zelda_ghist.gif
magick zelda_uniform.png -colorspace gray \
histogram:zelda_uniform_ghist.gif
FUTURO: ¡Añadir ejemplos de ecualización en otros espacios de color! Es decir, el canal de escala de grises en los espacios de color HSL, HSB y CMYK.
Redistribución gaussiana
Ecualizar un histograma no es la única manera de cambiar la distribución del histograma de una imagen. En realidad, normalmente no es muy útil, salvo en aplicaciones de visión por computadora. Aquí está la misma imagen, pero transformada para que su histograma tenga una distribución gaussiana (en forma de campana). Los valores usados aquí son una media de gris del 60%, con una caída sigma de 60 a cada lado de esa media.
redist -s gaussian 60,60,60 zelda.png \
zelda_gaussian.png
magick zelda_gaussian.png -colorspace gray \
histogram:zelda_gaussian_ghist.gif
A partir del histograma de escala de grises resultante, puede ver que la imagen se modifica de modo que sus colores siguen un tipo de distribución de curva de campana gaussiana. Para las fotos, esto produce un resultado de aspecto más 'natural'. La imagen no solo habrá sido optimizada en contraste, sino también ajustada en brillo de modo que la mayoría de los píxeles de la imagen tengan aproximadamente un 60% de brillo en escala de grises.
Metodología de la redistribución del histograma
Entonces, ¿cómo funciona este tipo de ajuste directo del histograma? Básicamente, calcula el histograma de la imagen actual y el de la distribución deseada. Luego determina cómo es necesario cambiar el valor de nivel de gris de cada 'contenedor' de modo que los recuentos de los contenedores sigan lo mejor posible la distribución deseada. Algunos contenedores pueden desplazarse hacia lo más oscuro, mientras que otros pueden desplazarse hacia lo más claro. En realidad, este es un proceso bastante complejo, así que recorrámoslo paso a paso.
Primero, necesitamos obtener los datos reales del histograma de ImageMagick, en lugar de una imagen gráfica del histograma. Tenga en cuenta que los datos provienen de todos los valores de color, combinados en una escala de grises. Esto se hizo para distribuir todos los canales juntos y ajustar el brillo global de la imagen para que siga la curva deseada.
magick zelda.png -colorspace gray \
-depth 8 -format "%c" histogram:info:- |\
tr -cs '0-9\012' ' ' |\
awk '# recopila los datos del histograma.
{ bin[$2] += $1; }
END { for ( i=0; i<256; i++ ) {
print bin[i]+0;
}
} ' > zelda_hist_data.txt
# obtiene el recuento máximo de cualquier 'contenedor' del histograma
max_count=`sort -n zelda_hist_data.txt | tail -n 1`
# convierte el histograma en un gráfico de perfil de los datos
echo "P2 256 1 $max_count" | cat - zelda_hist_data.txt |\
im_profile -s - zelda_hist_graph.gif
Para recopilar los datos tomo los metadatos de 'comment' de la imagen del histograma, que IM incluye justamente para este propósito. Los datos se limpian luego para dejar solo los números en bruto (usando un programa llamado "tr", abreviatura de 'translate'). Estos datos en bruto se pasan luego a otro programa de utilidad llamado "awk", que se usa para recopilar los recuentos reales del histograma de cada contenedor. Para poder ver los resultados, también proceso los recuentos del histograma en una imagen de degradado (mediante el formato de archivo de imagen NetPBM, escala de grises de texto PGM) y lo muestro como un gráfico de líneas usando el script "[im_profile](../static/img/scripts/im_profile)". Esencialmente, esta es solo una manera diferente de generar una imagen de histograma, aunque esta vez directamente desde un archivo de datos numéricos. Ahora que tenemos los datos del histograma en un archivo de texto, también necesitamos el histograma de la función con la que queremos que coincidan los datos redistribuidos. En este caso, es una distribución gaussiana con un valor medio de 153 (60% gris) y un ancho sigma de 60. Ambos valores están en términos del rango de 256 'contenedores' del histograma.
awk '# AWK para generar el gráfico de distribución gaussiana
BEGIN { mean = 153; sigma = 60;
fact = 1/(2*(sigma/256)^2);
expo = exp(1);
for ( i=0; i<256; i++ ) {
print int(65535*expo^(-(((i-mean)/256)^2)*fact));
}
}' /dev/null > gaussian_hist_data.txt
# convierte los datos gaussianos en un gráfico de perfil
echo "P2 256 1 65535" | cat - gaussian_hist_data.txt |\
im_profile -s -b - gaussian_hist_graph.gif
Los histogramas anteriores son interesantes y reflejan la distribución del histograma original de la imagen y el estado deseado del histograma. Pero para fines de conversión, esta forma de histograma, aunque buena para que la entendamos, no es muy útil para nuestros propósitos. En realidad, lo que de verdad necesitamos son los histogramas acumulativos. Estos histogramas son muy similares a un histograma normal, salvo que cada 'contenedor' del histograma es un recuento de su 'contenedor' más todos los 'contenedores' que vinieron antes, empezando en 0. Es decir, cada 'contenedor' es una 'acumulación' o recuento de todos los 'contenedores' más oscuros. En realidad, estos son más fáciles de generar directamente a partir de la imagen original. Así que repitamos el proceso, pero calculando y guardando los recuentos 'acumulativos'.
magick zelda.png -colorspace gray \
-depth 8 -format "%c" histogram:info:- |\
tr -cs '0-9\012' ' ' |\
awk '# Recopila el histograma acumulativo de una imagen
{ bin[$2] += $1; }
END { for ( i=0; i<256; i++ ) {
cum += bin[i];
print cum;
}
} ' > zelda_cumhist_data.txt
total_count=`tail -n 1 zelda_cumhist_data.txt`
echo "P2 256 1 $total_count" | cat - zelda_cumhist_data.txt |\
im_profile -s - zelda_cumhist_graph.gif
awk '# AWK para generar el gráfico acumulativo de distribución gaussiana
BEGIN { mean = 153; sigma = 60;
fact = 1/(2*(sigma/256)^2);
expo = exp(1);
for ( i=0; i<256; i++ ) {
gas[i] = expo^(-(((i-mean)/256)^2)*fact);
total += gas[i]
}
for ( i=0; i<256; i++ ) {
cum += gas[i];
print int(65535*cum/total);
}
}' /dev/null > gaussian_cumhist_data.txt
total_count=`tail -n 1 gaussian_cumhist_data.txt`
echo "P2 256 1 $total_count" | cat - gaussian_cumhist_data.txt |\
im_profile -s -b - gaussian_cumhist_graph.gif
![[Salida de IM]](../static/img/color_mods/zelda_cumhist_graph.gif)
Histograma acumulativo
de la imagen | ![[Salida de IM]](../static/img/color_mods/gaussian_cumhist_graph.gif)
Histograma acumulativo
gaussiano
---|---
Ahora lo que necesitamos hacer es convertir el histograma acumulativo de la imagen en el histograma acumulativo gaussiano. Para hacer esto, cada valor de gris de la imagen de entrada se usa para encontrar su valor acumulativo 'normalizado'. Luego este se mapea al mismo valor acumulativo en la distribución gaussiana y se encuentra su valor de gris correspondiente. Este diagrama debería aclarar el proceso de mapeo...
![[diagrama]](../static/img/img_diagrams/redist_working.jpg)
El siguiente comando realiza la búsqueda para cada valor de color de 8 bits posible, con el fin de generar una Tabla de Búsqueda de Color, o CLUT. Esta imagen especial puede usarse luego para mapear los valores de color de la imagen original a los nuevos valores necesarios para redistribuir el histograma de la imagen.
# Genera una CLUT para redistribuir el histograma
paste zelda_cumhist_data.txt gaussian_cumhist_data.txt |\
awk '# AWK para generar el gráfico de distribución gaussiana
{ bin[NR] = $1; gas[NR] = $2; }
END { k=0; # número de píxeles menores que este valor
print "P2 256 1 65535";
for ( j=0; j<256; j++ ) {
while ( k<255 &&
gas[k]/gas[255] <= bin[j]/bin[255] ) {
k++;
}
print 65535*k/255;
}
}' |\
magick pgm:- gaussian_clut.png
magick zelda.png gaussian_clut.png -clut zelda_redist.png
Como puede ver, convertir el histograma de una imagen para intentar que siga una función de distribución específica, como una curva de campana gaussiana, es un proceso bastante complejo y muy numérico. Aquí está todo en un único comando bastante largo y complejo...
magick zelda.png -colorspace gray \
-depth 8 -format "%c" histogram:info:- |\
tr -cs '0-9\012' ' ' |\
awk '# AWK para generar el gráfico de distribución gaussiana
{ # simplemente lee el histograma de la imagen en una tabla 'bin'
bin[$2] += $1;
}
END { # Genera el histograma gaussiano
mean = 153; sigma = 60;
fact = 1/(2*(sigma/256)^2);
expo = exp(1);
for ( i=0; i<256; i++ ) {
gas[i] = expo^(-(((i-mean)/256)^2)*fact);
}
# Convierte histogramas normales en histogramas acumulativos
for ( i=0; i<256; i++ ) {
gas[i] += gas[i-1];
bin[i] += bin[i-1];
}
# Genera el histograma redistribuido
k=0; # número de píxeles menores que este valor
print "P2 256 1 65535";
for ( j=0; j<256; j++ ) {
while ( k<255 &&
gas[k]/gas[255] <= bin[j]/bin[255] ) {
k++;
}
print 65535*k/255;
}
}' |\
magick zelda.png pgm:- -clut zelda_gaussian_redist.png
Solo unas palabras finales sobre la técnica anterior.
- El uso de "
awk" para hacer los cálculos y acelerar el script "[redist](http://www.fmwconcepts.com/imagemagick/redist/)" de Fred Weinhaus fue sugerido y aportado por Anthony Thyssen. - Para aplicar la técnica de redistribución anterior con el fin de generar una distribución 'uniforme' o 'ecualizada', el histograma de la función es simplemente una constante. Esto a su vez da como resultado una distribución integrada que es simplemente la fórmula
y = x, o sea, una simple línea recta diagonal. Aplicar la misma técnica de conversión conduce a una imagen CLUT que resulta ser idéntica al histograma acumulativo de la imagen de entrada. En otras palabras, para una ecualización del histograma, simplemente puede convertir el histograma acumulativo de la imagen en una CLUT y aplicarla a la imagen directamente. - La mayoría de los paquetes de procesamiento de imágenes, incluido ImageMagick en este momento, aplican las fórmulas de transformación directamente a los valores de la propia imagen, en lugar de generar una CLUT intermedia. Sin embargo, como los histogramas y, por tanto, los histogramas acumulativos tienen un tamaño limitado (típicamente 256 'contenedores'), eso puede conducir a errores graves, ya que los valores de color de la imagen pueden redondearse durante el proceso. Sin embargo, con ImageMagick, generamos una CLUT intermedia (que contiene esos mismos errores de redondeo) y luego convertimos los valores originales no redondeados de la imagen a través de la CLUT preparada usando una interpolación lineal de los valores. Como resultado de esta interpolación, los valores de color de la nueva imagen son más precisos, ya que no se han redondeado ni 'agrupado en contenedores' durante el procesamiento.
Con suerte, lo anterior acabará incorporándose a ImageMagick. Mientras tanto, el script "redist" de Fred Weinhaus está disponible para realizar la tarea. También puede interesarle el script "retinex" de Fred, que intenta realizar mejoras automáticas similares en las imágenes, en regiones localizadas de la imagen, en lugar de globalmente como hace esta técnica.
Ajustes de niveles caseros (DIY)
Ajustes matemáticos lineales de histograma
Las distintas formas básicas de Ajustes de niveles mostradas arriba ajustan linealmente los colores de la imagen. Estos cambios también pueden aplicarse de forma matemática. Por ejemplo, al multiplicar la imagen por un color específico, se establecen todas las áreas de blanco puro a ese color. Así que basta con leer la imagen, crear una imagen que contenga el color deseado y luego multiplicar la imagen original por ese color usando el "[-fx](https://imagemagick.org/command-line-options/#fx)" de forma libre de IM o el Operador DIY.
magick test.png -size 1x1 xc:Yellow \
-fx 'u*v.p{0,0}' fx_linear_white.png
Al hacer que "[-fx](https://imagemagick.org/command-line-options/#fx)" lea el color de una segunda imagen 'v', resulta fácil cambiar el color, sin necesidad de convertir los colores a valores RGB para usarlos en las operaciones matemáticas. Si se estuviera usando un paquete gráfico de procesamiento de imágenes elegante como "[Gimp](http://www.gimp.org/)" o "[Photoshop](http://www.adobe.com/products/photoshopfamily.html)", la operación anterior se habría aplicado a una imagen ajustando la 'curva' del gráfico del histograma de color de la imagen.
Por ejemplo, a la derecha hay un gráfico generado con "[gnuplot](http://www.gnuplot.info/)" (véase el script "[**im_histogram**](../static/img/scripts/im_histogram)") de la fórmula matemática que muestra lo que le ocurre a solo uno de los tres canales RGB. El color original (línea verde) se reasigna linealmente a un color más oscuro (línea roja). Teñir linealmente los colores negros también es bastante sencillo. Por ejemplo, para mapear linealmente 'black' a un color dorado como 'rgb(204,153,51)' (dejando 'white' como 'white') se necesitaría una fórmula matemática como...
result = 1-(1-color)*(1-intensity)
Esta fórmula niega los colores, multiplica la imagen por el color negado deseado y vuelve a negar la imagen. El resultado es el teñido del lado negro de la escala de grises, dejando el blanco sin cambios.
magick test.png -size 1x1 xc:'rgb(204,153,51)' \
-fx '1-(1-v.p{0,0})*(1-u)' fx_linear_black.png
Como referencia, arriba también se muestra un gráfico de histograma de "gnuplot" de la fórmula de reasignación. Con una fórmula algo más complicada se pueden reemplazar linealmente ambos extremos de la escala de grises, 'black' y 'white', con colores específicos.
magick test.png -size 1x2 gradient:gold-firebrick \
-fx 'v.p{0,0}*u+v.p{0,1}*(1-u)' fx_linear_color.png
El "-size 1x2 gradient:color1-color2" anterior solo se usa para generar una imagen de dos píxeles de color que la fórmula "[-fx](https://imagemagick.org/command-line-options/#fx)" pueda referenciar. El primer color reemplaza el blanco, mientras que el segundo reemplaza el negro, y todos los demás se interpolan entre el blanco y el negro. Como es típico de un operador de escala de grises, cada canal RGB se trata como un canal de escala de grises independiente, aunque la interpolación lineal es distinta para cada canal. Esto, por cierto, es exactamente equivalente al operador Ajustes de niveles por color "[+level-colors](https://imagemagick.org/command-line-options/#level-colors)". Sin embargo, a diferencia de "[+level-colors](https://imagemagick.org/command-line-options/#colors)", los colores a usar pueden provenir por supuesto de cualquier fuente de imagen, y no solo de los nombres de color proporcionados como argumento. Aun así, el uso directo de nombres de color también es posible. |
magick test.png -fx "yellow*u+green*(1-u)" fx_linear.png
Ajustes matemáticos no lineales de histograma
Si bien los ajustes de color lineales son importantes, y existen métodos más rápidos, hay muchas situaciones en las que un ajuste 'de nivel' lineal no es lo que se desea, y es ahí donde el Operador DIY "[-fx](https://imagemagick.org/command-line-options/#fx)" resulta más útil. Pues bien, una fórmula alternativa para el ajuste lineal es "-fx 'v.p{0,1}+(v.p{0,0}-v.p{0,1})*u'", que tiene la ventaja de que la 'u' puede reemplazarse por una única función aleatoria 'f(u)' para producir un cambio de color no lineal. Esto permite hacer cosas más interesantes. Por ejemplo, ¿qué pasaría si en el último ejemplo se quisiera empujar todos los colores hacia el lado 'black', haciendo que la imagen tenga un color más 'firebrick'?
magick test.png -size 1x2 gradient:gold-firebrick \
-fx 'v.p{0,1}+(v.p{0,0}-v.p{0,1})*u^4' fx_non-linear.png
En un ejemplo más práctico, Adelmo Gomes necesitaba un ajuste de color para un script automatizado de Recoloreado de mapas meteorológicos que estaba desarrollando. En este caso, quería teñir las partes de negro puro de la imagen con un azul de .25, pero dejar intacto el resto de la escala de grises, especialmente los grises blancos y de tonos medios de la imagen. Solo el color azul necesitaba ese ajuste, que entonces hacía a mano en un editor de imágenes. Por ejemplo, se podría usar una fórmula cuadrática como 'u^2' para teñir el extremo negro del histograma con un color azul de '.25'. Solo es necesario modificar el canal azul, así que el valor se insertó directamente en la fórmula.
magick test.png -channel B -fx '.25+(1-.25)*u^2' fx_quadratic.png
Sin embargo, aunque esto producía un resultado razonable, oscurece ligeramente los grises de tonos medios, generando un color amarillento enfermizo. Para evitarlo, se puede usar en su lugar una función 'exponencial', que da un mejor control del proceso de teñido.
magick test.png -channel B -fx '.3*exp(-u*4.9)+u' fx_expotential.png
De nuevo, el gráfico muestra cómo se modificó el canal azul para darle al negro un tinte azul oscuro distintivo. El segundo valor ('4.9') es la atenuación de vuelta hacia un gráfico lineal '+u'. Cuanto menor sea este valor, más lenta será la atenuación y más lineal se volverá el ajuste. Cuanto mayor sea el valor, más drástica será la 'atenuación'. El valor puede necesitar ajustarse para distintos valores de color, por lo que esta no es una buena fórmula general para el teñido genérico del color negro, pero es perfecta para teñir mapas meteorológicos. En general, si se puede expresar matemáticamente el ajuste de color deseado, se puede usar el operador "[-fx](https://imagemagick.org/command-line-options/#fx)" para lograr los resultados deseados.
Ajustes de 'curvas'
Normalmente, en un editor de fotos gráfico se presenta un gráfico de 'curvas' del histograma como el que he mostrado a la izquierda. El usuario puede entonces editar la 'curva' moviendo cuatro (o más) puntos de control, y la función de ajuste del histograma seguirá esos puntos. Los puntos de control generalmente especifican que el primer nivel de escala de grises se convierte, tras el ajuste, en el segundo nivel de escala de grises. Así que un punto como 0.0,0.2 significa básicamente que un gris al 0% (negro) debería convertirse, tras el ajuste, en un nivel de gris al 20%. Ahora bien, IM no permite especificar directamente 'puntos de control' para generar un ajuste de 'curva'; lo que necesita es la fórmula matemática de esa 'curva' generada. Por suerte para nosotros, hay programas que pueden generar esa fórmula de la curva a partir de los puntos de control, incluidos "[gnuplot](http://www.go.dlr.de/pdinfo_dv/gnuplot.html)", "[fudgit](http://www.go.dlr.de/pdinfo_dv/fudgit.html)", "mathematica" y "[matlab](http://www.mathworks.com/)", así como muchos otros paquetes de software matemático. El siguiente es un método que se puede usar para generar la fórmula a partir de cuatro puntos de control usando "gnuplot", que es un paquete adicional estándar que se puede instalar en la mayoría de las distribuciones de linux, así como en windows.
( echo "0.0 0.2"; echo "1.0 0.9"; \
echo "0.2 0.8"; echo "0.7 0.5"; ) > fx_control.txt
( echo 'f(x) = a*x**3 + b*x**2 + c*x + d'; \
echo 'fit f(x) "fx_control.txt" via a, b, c, d'; \
echo 'print a,"*u^3 + ",b,"*u^2 + ",c,"*u + ",d'; \
) | gnuplot 2>&1 | tail -1 > fx_funct.txt
| ![[Datos]](../static/img/color_mods/fx_control.txt.gif)
| _Tenga en cuenta que el número de parámetros ('a' a 'd' arriba) necesarios para el ajuste de la curva debe ser igual al número de puntos de control que se proporcionan. Por ello, si se quieren cinco puntos de control, hay que incluir otro término 'e' en la función.
Si la curva del histograma pasa por los puntos de control fijos 0,0 y 1,1, en realidad solo se necesitan dos parámetros, ya que 'd' será igual a '0' y 'c' será igual a '1-a-b'.
_
---|---
Una guía de uso más detallada de lo anterior, específicamente para usuarios de Windows, pero que también funciona para usuarios de linux, se ha publicado en StackOverflow: IM Curves using Gnuplot on Windows. Como puede verse en la imagen adicional generada por "gnuplot" arriba, la función generada se ajusta perfectamente a los puntos de control. Además, como generó una fórmula de estilo "-fx", puede usarse tal cual como argumento de IM. Por ejemplo... |
magick test.png -fx "`cat fx_funct.txt`" fx_funct_curve.png
![[Salida IM]](../static/img/color_mods/fx_funct_curve.png)
Para facilitar a los usuarios la conversión de puntos de control en una función de ajuste de histograma, he creado un script de shell llamado "[**im_fx_curves**](../static/img/scripts/im_fx_curves)" que llama a "gnuplot" y produce una ecuación polinómica de aspecto más agradable a partir de los puntos de control dados. Gabe Schaffer también proporcionó una versión en perl (usando un módulo de biblioteca "Math::Polynomial" descargado) llamada "[**im_fx_curves.pl**](../static/img/scripts/im_fx_curves.pl)" que hace lo mismo. Cualquiera de los dos scripts puede usarse. Por ejemplo, esta es una curva distinta con 5 puntos de control...
im_fx_curves 0,0.2 0.3,0.7 0.6,0.5 0.8,0.8 1,0.6 > fx_curve.txt
| | | ![[Gnuplot]](../static/img/color_mods/fx_curve.txt.gif)
Sin embargo, la función FX es muy lenta. Pero a partir de IM 6.4.8-9 ahora se pueden pasar directamente los coeficientes descubiertos de la expresión polinómica ajustada al Método de función polinómica. Se puede generar la lista de coeficientes separados por comas usando "[**im_fx_curves**](../static/img/scripts/im_fx_curves)" con una opción especial '-c'...
im_fx_curves -c 0,0.2 0.3,0.7 0.6,0.5 0.8,0.8 1,0.6 > coefficients.txt
| | | ![[Gnuplot]](../static/img/color_mods/coefficients.txt.gif)
Por ejemplo, apliquemos esas curvas a nuestra imagen de prueba... |
magick test.png -function Polynomial `cat coefficients.txt` test_curves.png
![[Salida IM]](../static/img/color_mods/test_curves.png)
Un ejemplo más práctico de este método se detalla en el ejemplo avanzado de Efectos "Aqua". Una forma alternativa de generar 'curvas' se examina en la discusión del Foro de IM Arbitrary tonal reproduction curves.
Coloreado de imágenes
Coloreado uniforme de imágenes
Normalmente, el coloreado de una imagen se logra mezclando la imagen con un color en cierta medida. Esto puede hacerse mediante las técnicas del Operador Evaluate o de Mezcla de imágenes, pero no son sencillas de usar. Por suerte, existe un método más simple para filtrar un color uniforme en una imagen mediante el operador de imagen "[-colorize](https://imagemagick.org/command-line-options/#colorize)". Este operador mezcla el color "[-fill](https://imagemagick.org/command-line-options/#fill)" actual en todas las imágenes de la secuencia de imágenes actual. El canal alfa de la imagen original se conserva, y solo se modifican los canales de color. Por ejemplo, para aclarar una imagen (en escala de grises o no) usamos "[-colorize](https://imagemagick.org/command-line-options/#colorize)" para mezclar cierta cantidad de blanco en la imagen, haciéndola más brillante sin saturarla por completo.
magick test.png -fill white -colorize 50% colorize_lighten.png
De forma similar, podemos usar un color de relleno 'black' para oscurecer una imagen.
magick test.png -fill black -colorize 50% colorize_darken.png
Para llevar ambos extremos de la imagen hacia el gris de los tonos medios, se usa un color de relleno gris específico. El color 'gray50' es el color exactamente central del espectro de color RGB.
magick test.png -fill gray50 -colorize 40% colorize_grayer.png
También se usa con frecuencia como un método de 'descontraste', como el que proporciona el Operador de ajuste de niveles inverso, aunque con menos control. El operador "[-colorize](https://imagemagick.org/command-line-options/#colorize)" también permite especificar porcentajes de disolución para cada uno de los tres canales de color por separado. Esto resulta útil para oscurecer (o aclarar) una imagen de forma lineal de una manera especial. |
Antes de IM v6.7.9, el operador "[-colorize](https://imagemagick.org/command-line-options/#colorize)" no modificaba el canal alfa en absoluto. A partir de esa versión, como puede verse arriba, ahora colorea de forma uniforme todos los píxeles, incluidos los píxeles totalmente transparentes. |
|---|---|
Un uso común del operador "[-colorize](https://imagemagick.org/command-line-options/#colorize)" es simplemente reemplazar todos los colores de una imagen existente (coloreando al '100%'), pero conservando la forma de transparencia (alfa) de la imagen, para producir una máscara coloreada. Sin embargo, a partir de IM v6.7.9 deberá proteger el canal alfa de este operador desactivándolo y volviendo a activar el canal alfa después. (Consulte Alpha On para más detalles). Por ejemplo... |
magick test.png -alpha off \
-fill blue -colorize 100% \
-alpha on colorize_shape.png
![[Salida IM]](../static/img/color_mods/colorize_shape.png)
Sin esta protección, colorize habría dejado el lienzo completamente en blanco con el color indicado... |
magick test.png -fill blue -colorize 100% colorize_blank.png
![[Salida IM]](../static/img/color_mods/colorize_blank.png)
Sin embargo, si existe la posibilidad de usar una versión de IM anterior a IM v6.7.9, recomiendo incluir en lo anterior una operación "-alpha opaque" o "-alpha off" para garantizar que la imagen resultante sea la imagen completamente en blanco que espera. Tenga en cuenta que puede dejar lienzos en blanco más rápido usando el operador Ajustes de niveles por color con un único color, en lugar de un rango de colores. Consulte también Lienzos en blanco.
Coloreado de tonos medios
Mientras que el operador Colorize aplica el color "[-fill](https://imagemagick.org/command-line-options/#fill)" para colorear linealmente todos los colores de una imagen, el operador "[-tint](https://imagemagick.org/command-line-options/#tint)" aplica el color "[-fill](https://imagemagick.org/command-line-options/#fill)" de tal forma que solo colorea los tonos medios de una imagen. El operador es un operador en escala de grises, y el color se modera o intensifica según el porcentaje indicado (de 0 a 200). Para limitar sus efectos, también se ajusta mediante una fórmula matemática de modo que no afecte al blanco ni al negro, sino que tenga el mayor efecto sobre los tonos medios de cada canal de color. Un "-tint 100" esencialmente colorea un gris perfecto de modo que adquiere la mitad de la intensidad del color de relleno. Un valor más bajo lo colorea hacia un color más oscuro, mientras que un valor más alto lo colorea hacia una coincidencia perfecta con ese color.
magick test.png -fill red -tint 40 tint_red.png
El color verde de la imagen de prueba no es un verde RGB verdadero, sino el 'green' de Scaled Vector Graphics, que solo tiene la mitad del brillo de un verde verdadero. Por ello también es un tono medio y, por tanto, se ve afectado por el operador "[-tint](https://imagemagick.org/command-line-options/#tint)", oscureciéndose, a diferencia de las manchas de color rojo y azul de la imagen de prueba. También puede colorear los componentes de color individuales usando una lista de porcentajes separados por comas. Por ejemplo "-tint 30,40,20,10". Sin embargo, esto puede ser complicado de usar y quizá requiera algo de experimentación para acertar. Es mejor especificar el color que desea para grises del 50% perfectos. | _
El operador "[-tint](https://imagemagick.org/command-line-options/#tint)" funciona tomando de algún modo el color y los porcentajes indicados y ajustando luego los colores individuales de la imagen según la intensidad del color "[-fill](https://imagemagick.org/command-line-options/#fill)", conforme a la fórmula siguiente. (vea el gráfico a la derecha)
_ f(x)=(1-(4.0*((x-0.5)*(x-0.5)))) _Una función cuadrática, cuyo resultado se usa como vector para el color existente en la imagen. Como puede ver, da una sustitución completa del color para un gris medio puro, sin ajuste alguno para el blanco ni para el negro.
O bien operadores de más bajo nivel que puede usar para hacer este tipo de cosas usted mismo; consulte el Operador FX, así como los Operadores Evaluate y Function.
_
---|---
El operador de coloreado es perfecto para ajustar los resultados de la salida de "[-shade](https://imagemagick.org/command-line-options/#shade)" (consulte Imágenes de realce con superposición de sombreado), como los ejemplos de Imágenes de viñetas 3D. También puede usar "[-tint](https://imagemagick.org/command-line-options/#tint)" para aclarar u oscurecer los tonos medios de una imagen. Esto es algo así como un 'ajuste de gamma' para imágenes, aunque no exactamente. Por ejemplo, usar un valor de tint mayor que 100 con un color 'white' aclarará los tonos medios.
magick test.png -fill white -tint 130 tint_lighter.png
Mientras que un valor menor que 100 oscurecerá los colores.
magick test.png -fill white -tint 70 tint_darker.png
| _Por el momento, un color gris de tono medio puro no se asignará al color "[-fill](https://imagemagick.org/command-line-options/#fill)".
El argumento de porcentaje no es un 'porcentaje de mezcla', sino más bien un 'porcentaje de brillo'. Por ejemplo, no funcionará en absoluto con un color de relleno 'black'.
No sé por qué se diseñó así ni cuál es la historia detrás de ello. No obstante, hace que el control exacto de los colores finales al colorear imágenes en escala de grises resulte muy incómodo.
Usar el Coloreado por composición de superposición que se muestra abajo proporcionará un coloreado de los grises de tono medio más exacto (aunque muy lineal, en lugar de parabólico).
Coloreado en tono sepia
Una técnica especial de recoloreado fotográfico, "[-sepia-tone](https://imagemagick.org/command-line-options/#sepia-tone)", consiste básicamente en convertir la imagen a escala de grises y colorear todos los tonos medios con un color marrón especial. |
magick rose: -sepia-tone 65% sepia-tone.jpg
![[Salida IM]](../static/img/color_mods/sepia-tone.jpg)
El argumento indicado es el 'punto medio' de la escala de grises que pasará a ser el más cercano al color sepia, que es similar al color 'Goldenrod'. El uso más común de esto es generar un Efecto duotono para producir fotos de 'aspecto antiguo' (consulte la entrada de Wikipedia sobre Tono sepia). Por ejemplo, aquí coloreo una imagen de rosa en escala de grises con contraste realzado, usando varios colores, para lograr efectos similares al tono sepia. El color que deba usar depende del efecto exacto que busque.
magick rose: -colorspace gray -sigmoidal-contrast 10,40% rose_grey.jpg
for color in goldenrod gold khaki wheat
do
magick rose_grey.jpg -fill $color -tint 100 sepia_$color.jpg
done
Personalmente, encuentro que mezclar o combinar una imagen en tono sepia con la original, para reducir su efecto, también puede producir un mejor efecto 'descolorido'. |
magick rose: \( +clone -sepia-tone 60% \) -evaluate-sequence mean sepia-tone_blended.jpg
![[Salida IM]](../static/img/color_mods/sepia-tone_blended.jpg)
Consulte también Tablas de búsqueda de color Hald para conocer un método con el que guardar variaciones de cambio de color mucho más complejas, como el último ejemplo anterior.
Efecto duotono
Un 'duotono' es un método de impresión en el que se mezcla la escala de grises de una imagen (tinta negra) con algún otro color para producir un mejor resultado, con un presupuesto o equipo de impresión limitado. Por ejemplo, la razón por la que todas las fotos antiguas que se ven hoy tienen un aspecto en tono sepia es que las tintas sepia sobrevivieron y no se deterioraron ni se descoloraron con el tiempo. Otros formatos de imagen 'en blanco y negro' se descoloraron hasta quedar inservibles. Consulte el Operador de tono sepia anterior. Otra técnica de duotono conocida como 'Cyanotype' (más comúnmente conocida como 'blue-prints' o cianotipos) se generalizó como método para hacer copias a gran escala de los planos originales de arquitectos en blanco y negro. Recuerde que esta técnica se usaba mucho antes de la invención de los láseres y, a partir de ellos, de la fotocopia (y Xerox). Para más información, consulte la entrada de Wikipedia sobre Duotone, también Fake duotones vs Real duotones. Sin embargo, el Operador Tint anterior produce un facsímil razonable del efecto duotono, tal como lo hizo con el efecto similar al tono sepia anterior.
magick rose: -colorspace gray -sigmoidal-contrast 10,40% rose_grey.jpg
for color in blue darkcyan goldenrod firebrick
do
magick rose_grey.jpg -fill $color -tint 100 duotone_$color.jpg
done
Tenga en cuenta que, por lo general, elegí una versión más oscura del color 'duotono', pero también puede ajustar esto usando el argumento del Operador Tint. El brillo y el contraste también pueden ajustarse usando los argumentos del Operador de contraste sigmoidal. Otra forma más rigurosa de generar un duotono a partir de tres colores (los colores de punto negro, punto medio y punto blanco) es usar una Tabla de búsqueda de color (vea más abajo). Aquí tiene solo un ejemplo rápido en el que creo un duotono muy inusual usando los colores 'Black', 'Chocolate' y 'LemonChiffon'. Y sí, el color del punto negro normalmente se deja en negro, razón por la cual suele llamarse duo -tono.
magick -size 1x1 xc:Black xc:Chocolate xc:LemonChiffon \
+append duotone_clut.gif
magick -size 20x256 gradient: -rotate 90 duotone_clut.gif \
-interpolate Bicubic -clut duotone_gradient.gif
magick rose_grey.jpg duotone_clut.gif \
-interpolate Bicubic -clut rose_duotone.jpg
La ventaja de lo anterior es un control exacto del color del punto medio (a diferencia de Tint, que no es exacto). También puede usar directamente los tres colores que desee, igual que en el ejemplo anterior, o usar un degradado ampliado de los colores para un control más fino de los colores entre los tres (o más) puntos de control. La técnica también le ofrece una forma muy compacta de almacenar el efecto duotono concreto, para su uso repetido y futuro. Consulte también las Tablas de búsqueda de color Hald para un método más complejo de guardar cambios de color que van más allá de colorear imágenes en escala de grises.
Coloreado, hágalo usted mismo
Uno de los mayores problemas de "[-tint](https://imagemagick.org/command-line-options/#tint)" es que es un operador en escala de grises (o vectorial). Es decir, maneja cada uno de los canales rojo, verde y azul de forma completamente independiente entre sí. Esto, a su vez, significa que un color primario y secundario como 'blue' o 'yellow' no se ven afectados por "[-tint](https://imagemagick.org/command-line-options/#tint)", aunque sí lo estén todos los niveles de gris. Sin embargo, gracias a diversas transformaciones matemáticas de canal como el Operador FX y los más rápidos Operadores Evaluate y Function, puede generar sus propias superposiciones de color para modificar la imagen. Es decir, colorear la imagen de forma similar a como lo hace el Operador Colorize. Por ejemplo, aquí convierto el nivel de brillo en escala de grises de una imagen en una superposición semitransparente del color concreto deseado. |
magick test.png \( +clone -colorspace gray \
-function polynomial -4,4,0 -background Gold -alpha shape \) \
-composite tint_diy_compose.png
![[Salida IM]](../static/img/color_mods/tint_diy_compose.png)
Advertencia: esto no conserva correctamente la transparencia de la imagen, pero funcionará bien con imágenes totalmente opacas. Tenga en cuenta que, a diferencia de tint, puede usarse cualquier color, incluido 'black', ya que el color no se trata como una suma vectorial, sino como una composición alfa. El resultado no es del todo igual al que obtendría con un tint normal.
Superposición de coloreado
Los métodos especiales de Composición alfa '[Overlay](compose.html#overlay)' y '[Hardlight](compose.html#hardlight)' se diseñaron en realidad pensando en el coloreado de color (y de patrones). Estos métodos de composición también reemplazan los grises de tono medio dejando intactas las luces blancas y negras de la imagen. Por ejemplo, aquí genero rápidamente una imagen de superposición coloreada y la compongo para colorear la imagen original. |
magick test.png \( +clone -alpha off -fill gold -colorize 100% \) \
-compose overlay -composite tint_overlay.png
![[Salida IM]](../static/img/color_mods/tint_overlay.png)
Como puede ver, la composición alfa no conserva ninguna transparencia de la imagen original, lo que exige usar una segunda operación de composición alfa para solucionar este problema. |
magick test.png \
\( +clone -alpha off -fill gold -colorize 100% \
+clone +swap -compose overlay -composite \) \
-compose SrcIn -composite tint_overlay_fixed.png
![[Salida IM]](../static/img/color_mods/tint_overlay_fixed.png)
Usar '[Overlay](compose.html#overlay)' es una forma de coloreado mucho más lineal que la función cuadrática usada arriba y, al igual que "[-tint](https://imagemagick.org/command-line-options/#tint)", se aplica a cada canal de la imagen por separado, de modo que los colores primarios y secundarios también permanecen sin cambios. Además, este método de composición alfa no ofrece ningún control de ajuste, por lo que si desea controlar el nivel de coloreado, deberá ajustar la transparencia de la imagen de superposición antes de aplicar el coloreado. Por supuesto, a diferencia de los otros métodos de coloreado que he mostrado hasta ahora, no se limita a colorear con un simple color, sino que puede aplicar un coloreado usando una imagen o un patrón de mosaico. |
magick test.png \
\( -size 150x100 tile:tile_disks.jpg \
+clone +swap -compose overlay -composite \) \
-compose SrcIn -composite tint_overlay_pattern.png
![[Salida IM]](../static/img/color_mods/tint_overlay_pattern.png)
Sin embargo, esto se aleja del alcance del manejo básico del color, así que dejaré el coloreado de imágenes aquí. | _El método de composición alfa '[HardLight](compose.html#hardlight)' producirá los mismos resultados que '[Overlay](compose.html#overlay)', pero con las imágenes de origen y destino intercambiadas.
Esto podría haberse usado en lugar de "+swap" en los últimos ejemplos._
---|---
Modificadores globales de color
Modular brillo, saturación y matiz
El operador "[-modulate](https://imagemagick.org/command-line-options/#modulate)" es especial porque modifica una imagen en el espacio de color especial HSL (matiz-saturación-luminosidad) espacio de color. Convierte cada píxel de color a este espacio de color, lo modifica y lo convierte de nuevo a su espacio de color original. Toma tres valores (aunque los valores posteriores son opcionales) como porcentaje, de modo que 100 no produce ningún cambio en la imagen. Por ejemplo.. |
magick rose: -modulate 100,100,100 mod_noop.gif
![[Salida IM]](../static/img/color_mods/mod_noop.gif)
El primer valor, brightness (brillo), es un multiplicador del brillo general de la imagen.
magick rose: -modulate 0 mod_bright_0.gif
magick rose: -modulate 50 mod_bright_50.gif
magick rose: -modulate 80 mod_bright_80.gif
magick rose: -modulate 100 mod_bright_100.gif
magick rose: -modulate 150 mod_bright_150.gif
magick rose: -modulate 200 mod_bright_200.gif
Tenga en cuenta que, aunque un argumento de brillo de '0' produce una imagen negra pura, no se puede producir una imagen blanca pura usando este operador por sí solo. El segundo valor, saturation (saturación), también es un multiplicador que ajusta la cantidad total de color presente en la imagen.
magick rose: -modulate 100,0 mod_sat_0.gif
magick rose: -modulate 100,20 mod_sat_20.gif
magick rose: -modulate 100,70 mod_sat_70.gif
magick rose: -modulate 100,100 mod_sat_100.gif
magick rose: -modulate 100,150 mod_sat_150.gif
magick rose: -modulate 100,200 mod_sat_200.gif
Una saturación de '0' produce una imagen en escala de grises, como también se mostró en Convertir color a escala de grises más arriba. Sin embargo, ese gris mezcla los tres canales de color por igual, tal como lo define el espacio de color HSL, por lo que no produce una verdadera escala de grises de 'intensidad'. En esencia, los valores pequeños producen colores más 'pastel', mientras que los valores mayores que '100' producen imágenes más coloridas y de aspecto caricaturesco. Tenga en cuenta que, como brightness y saturation son multiplicadores porcentuales, sería necesario multiplicar por un número muy grande para llevar casi todos los valores de color de la imagen cerca del máximo. Es decir, necesitaría usar un factor de brightness cercano al millón para volver blancos todos los colores excepto el negro puro.
Modulación del matiz
El valor final, Hue (matiz), es en realidad mucho más útil. Rota los colores de la imagen de manera cíclica. Para lograrlo, el valor de Hue indicado produce una 'suma modular' en lugar de una multiplicación. Sin embargo, tenga cuidado: el matiz se rota mediante un porcentaje y no mediante un ángulo. Esto puede parecer extraño, pero "[-modulate](https://imagemagick.org/command-line-options/#modulate)" siempre ha sido así. Las fórmulas de conversión entre el ángulo y el argumento de modulate son...
_hue_angle_ = ( _modulate_arg - 100_ ) * 180/100
_modulate_arg_ = ( _hue_angle * 100/180_ ) + 100
Eso significa que '100' (para los tres argumentos) no produce ningún cambio. Mientras que un valor de '0' o '200' negará efectivamente los colores de la imagen (pero no la intensidad). Por ejemplo...
magick rose: -modulate 100,100,0 mod_hue_0.gif
magick rose: -modulate 100,100,33.3 mod_hue_33.gif
magick rose: -modulate 100,100,66.6 mod_hue_66.gif
magick rose: -modulate 100,100,100 mod_hue_100.gif
magick rose: -modulate 100,100,133.3 mod_hue_133.gif
magick rose: -modulate 100,100,166.6 mod_hue_166.gif
magick rose: -modulate 100,100,200 mod_hue_200.gif
0
(rojo <-> cian) |
33.3
(rojo -> azul) |
66.6 |
100%
no-op |
133.3 |
166.6
(rojo -> verde) |
200
(igual que 0)
---|---|---|---|---|---|---
Como puede ver, un valor de '33.3' produce una rotación negativa, o en sentido antihorario, de todos los colores en aproximadamente 60 grados, mapeando efectivamente el rojo al azul, el azul al verde y el verde al rojo. Usar valores de '0' o '200' produce una negación completa de 180 grados de los colores, sin negar el brillo de la imagen. Tenga en cuenta que los matices son cíclicos, por lo que usar un valor de '300' producirá una rotación de color de 360 grados y no resultará en ningún cambio en la imagen. Para ver ejemplos del uso de la 'Modulación del matiz' para modificar colores en imágenes, consulte Enmascaramiento con clave de croma y Chinchetas en un mapa.
Estos tipos de operaciones y más también pueden aplicarse mediante técnicas avanzadas de espacio de color, como las usadas en el operador Recolor Matrix (más abajo), pero para una 'modulación' básica de una imagen, este operador simplifica mucho las cosas. Para el intercambio de colores primarios, el operador Recolor Matrix, o el intercambio de canales (consulte operadores Separate/Combine), es probablemente una técnica más precisa. Aunque es mucho menos versátil. Consulte también Tablas de búsqueda de color Hald para conocer un método con el que puede guardar variaciones de cambio de color, especialmente cambios de matiz, para reutilizarlas más adelante.
Modulate DIY
Si realmente lo desea, puede hacerlo usted mismo ("Do It Yourself"). Básicamente, convierte la imagen al espacio de color apropiado, modifica los valores y la convierte de nuevo. Recuerde que en el espacio de color HSL, el canal verde contiene el valor de saturación y el canal azul contiene el valor de luminancia. Por ejemplo, aquí está el equivalente a un "-modulate 80,120" (oscurecer ligeramente, aumentar la saturación de color), usando el espacio de color HSL predeterminado...
magick rose: -colorspace HSL \
-channel B -evaluate multiply 0.80 \
-channel G -evaluate multiply 1.20 \
+channel -colorspace sRGB modulate_channel.png
Por supuesto, si modifica el matiz (canal rojo) usando este método, deberá asegurarse de que el valor final 'envuelva' (un módulo), en lugar de simplemente recortar el valor en el máximo o el mínimo (ambos corresponden al matiz 'rojo'). Por ello, probablemente sea más fácil usar directamente el operador Modulate para las modificaciones de matiz.
Modular en otros espacios de color
El mayor problema de "[-modulate](https://imagemagick.org/command-line-options/#modulate)" se da al manejar imágenes que contienen muchos colores 'casi blancos'. Como hace su trabajo en el espacio de color HSL, los colores que no son blanco puro se vuelven más 'saturados' a medida que se reduce el brillo. Puede verlo en la hoja blanca de la imagen rose de arriba, que muestra muchos artefactos de color con un oscurecimiento del 50%. Esto es especialmente un problema al tratar con formatos de imagen JPEG, ya que tiende a generar colores no blancos puros (en realidad, todos los colores suelen estar ligeramente desviados en JPEG) debido a su algoritmo de compresión con pérdida. Por ejemplo...
magick wedding_party_sm.jpg -modulate 85 modulate_off-white.png
El problema aquí es que en HSL todos los colores casi blancos quedaban comprimidos en una pequeña área de 'punto blanco' del espacio de color empleado (un doble cono). Cuando luego se reduce el brillo, los colores casi blancos se expanden al expandirse el cono de color, lo que hace que el color casi blanco genere un conjunto de colores casi blancos más colorido (saturado). Es decir, las pequeñas variaciones de color se exageran. La solución a esto es hacer el "[-modulate](https://imagemagick.org/command-line-options/#modulate)" en el espacio de color HSB, en lugar del espacio de color HSL. | _La 'B' de HSB significa Brightness (brillo), pero también se conoce comúnmente como HSV, donde la 'V' significa Value (valor). Son el mismo espacio de color, pero 'V' es un término confuso, ya que un valor normalmente significa 'un número almacenado'.
También existe un espacio de color HSI (que usa la 'I' de Intensity, intensidad), pero es poco común y no es necesario debido a la incorporación del espacio de color cíclico HCL (donde 'L' significa Luminance, luminancia) (véase más abajo).
_
---|---
En el espacio de color HSB, el 'blanco' no es un único punto, sino un gran 'disco', por lo que los casi blancos no están 'cerca' unos de otros. De este modo, cuando se reduce el brillo, los casi blancos se contraen por igual, reduciendo cualquier ligera variación de color en lugar de expandirla. Así, los blancos simplemente se vuelven grises, y no más coloridos. Para modular la imagen en el espacio de color HSB, puede usar la técnica DIY (véase más arriba) en ese espacio de color. O, con IM v6.5.3-7 y posteriores, puede definir un control operativo de 'modulate:colorspace' con uno de los espacios de color 'Hue'. |
magick wedding_party_sm.jpg \
-define modulate:colorspace=HSB -modulate 85 \
modulate_HSB.png
![[Salida IM]](../static/img/color_mods/modulate_HSB.png)
Otros espacios de color 'Hue' son HWB y HCL (véase la siguiente sección). Por supuesto, si redimensionó la imagen a este tamaño tan pequeño, una solución aún mejor es NO guardar la imagen en JPEG, que fue la causa de los valores casi blancos. Mejor todavía, no guarde la imagen en absoluto hasta que haya terminado, de modo que pueda mantener todos los valores de color con la mejor configuración de calidad en memoria. La razón por la que el espacio de color HSB no se usa de forma predeterminada para modulate es que, si aclara una imagen en este espacio de color, los colores se vuelven más saturados e intensos, en lugar de que la imagen se vuelva más brillante y blanca. Aquí, por ejemplo, hay un aclarado al 150% de la imagen 'rose' en el espacio de color HSL predeterminado y en un espacio de color HSB especificado, a modo de comparación.
magick rose: -modulate 150 mod_bright_HSL.gif
magick rose: -define modulate:colorspace=HSB \
-modulate 150 mod_bright_HSB.gif
| _Antes de IM v6.4.0-10, el operador "[-modulate](https://imagemagick.org/command-line-options/#modulate)" en realidad usaba el espacio de color HSB en lugar del espacio de color HSL. Esto se cambió debido a un informe de error de un usuario sobre la situación descrita arriba.
La cuestión es que, para algunas imágenes, está condenado si usa HSL, y para otras imágenes está condenado si usa el espacio de color HSB. ¡Todo depende de lo que esté intentando hacer!
Modular en LCHab y otros espacios de color
La modulación del matiz (en el espacio de color HSL o HSB) se considera en realidad bastante tosca. Estos espacios de color no tienen en cuenta una intensidad más realista de los colores. Por ello, rotar entre los matices 'azul' y 'amarillo' también generará desplazamientos de brillo muy grandes. Consulte Wikipedia: Desventajas del espacio de color HSL.Una alternativa es realizar una rotación que preserve la luminancia, como se describe en Grafica Obscura en el artículo "Matrix Operations". Esto es complejo, ya que las modificaciones de color se realizan como parte de la operación, como una única operación matricial calculada que es diferente según cuánta rotación se requiera.A partir de IM v6.8.4-7, el operador Modulate también puede manejar los espacios de color especiales 'LCHab ' y 'LCHuv ', que son las formas cilíndricas (matiz-croma) de los respectivos espacios de color 'Luv ' y 'Lab '. Consulte Wikipedia, espacio de color LUV cilíndrico, o LCHuv y The HCL Colorspace para más información. |
Los canales equivalentes de los espacios de color 'LCHab ' y 'LCHuv ' están invertidos respecto a los de los espacios de color 'HCL ' y 'HCB '. Es decir, el equivalente de la intensidad 'en escala de grises' está en el primer canal ('rojo') y el matiz está en el tercer canal ('azul') de la imagen. |
|---|---|
Por ejemplo, hacemos algunas rotaciones de matiz para la rose roja usando el espacio de color 'LCHab '. Compárelas con el conjunto anterior del espacio de color 'HSL ' de arriba. |
for i in 0 25 50 75 100 125 150 175; do
magick rose: -define modulate:colorspace=LCHab \
-modulate 100,100,$i mod_lch_$i.gif
done
0% & 200% |
25%
(rojo->azul) |
50% |
75% |
100%
no-op |
125% |
150% |
175%
---|---|---|---|---|---|---|---
Tenga en cuenta que los matices se distribuyen de forma diferente a la de los espacios de color de matiz más tradicionales. Pero, lo que es más importante, se preserva la intensidad de la imagen original. Debido a esto, nunca pasará de un color primario/secundario puro a otro color primario/secundario puro, ya que ninguno de ellos tiene la misma intensidad. Sin embargo, la progresión de los colores a lo largo de los matices fluye de forma más suave, con 'picos' menos pronunciados en los colores primarios y secundarios. Aquí hay una comparación de una simple rotación de matiz de rojo a azul para 'LCHab' frente al espacio de color 'HSL' normal (usando los porcentajes de rotación apropiados).
Original | |
LCHab
25% |
HSL/HSB
33.3%
---|---|---|---
Observe cómo el azul no es ni de lejos tan oscuro, sino un tono que se ajusta mejor al tono de la imagen original. Para más información sobre los matices del espacio de color HCL, consulte los ejemplos de La rueda de colores LCH. | _Antes de IM v6.8.4-7 habría usado el espacio de color 'HCL ' (introducido en IM v6.7.9-1). Este espacio de color es exactamente igual que 'LCHuv ' pero con el orden de los canales invertido (el matiz se almacena en el canal rojo de la imagen; era simplemente la forma en que se define ese espacio de color). Esto significaba que también tenía que intercambiar los distintos canales para que el operador Modulate funcionara correctamente.
Los espacios de color 'LCHab ' y 'LCHuv ' ordenan los canales de la misma manera que 'HSL ', para permitir que modulate funcione correctamente y directamente sobre el espacio de color sin requerir un reordenamiento de canales.
_
---|---
| _Tenga en cuenta que, para colores muy oscuros, 'LCHuv ' puede generar valores de color con discontinuidades. Sin embargo, esto no debería ocurrir con imágenes reales, solo con imágenes generadas directamente en el espacio cilíndrico.
Operador Color Matrix
El operador "[-color-matrix](https://imagemagick.org/command-line-options/#color-matrix)" recolorea imágenes usando una técnica matricial. Es decir, se le proporciona una matriz de valores que representa cómo mezclar linealmente los distintos valores de los canales de color de una imagen para producir nuevos valores de color. El uso típico es proporcionar al operador 9 valores, que forman tres funciones (filas) o tres multiplicadores (columnas). Así, los tres primeros números son la fórmula de color del canal 'rojo'. Los tres siguientes para el 'verde', y así sucesivamente. Por ejemplo... |
magick rose: -color-matrix ' 1 0 0
0 1 0
0 0 1 ' matrix_noop.png
![[Salida IM]](../static/img/color_mods/matrix_noop.png)
Equivale a aplicar las ecuaciones...
red' |
= 1 * red + 0 * green + 0 * blue |
|---|---|
green' |
= 0 * red + 1 * green + 0 * blue |
blue' |
= 0 * red + 0 * green + 1 * blue |
En este caso particular, no se realiza ningún cambio en la imagen. La matriz forma un arreglo especial, conocido como 'identity matrix' (matriz identidad). Al mezclar las filas, puede usarla para intercambiar los distintos canales. Por ejemplo, aquí intercambio los valores de los canales rojo y azul. |
magick rose: -color-matrix ' 0 0 1
0 1 0
1 0 0 ' matrix_red_blue_swap.png
![[Salida IM]](../static/img/color_mods/matrix_red_blue_swap.png)
O simplemente copiar el canal rojo a los otros dos canales, para extraer o separar el 'canal rojo' (consulte también Separar imágenes de canal)... |
magick rose: -color-matrix ' 1 0 0
1 0 0
1 0 0 ' matrix_red_channel.png
![[Salida IM]](../static/img/color_mods/matrix_red_channel.png)
o convertir la imagen a escala de grises usando una proporción de gris 2/5/3 (consulte Convertir color a escala de grises)... |
magick rose: -color-matrix ' .2 .5 .3
.2 .5 .3
.2 .5 .3 ' matrix_grayscale.png
Puede usar una matriz más grande, de hasta un conjunto de 6 filas y columnas. Estas corresponden a los canales: 'Red', 'Green', 'Blue', 'Black' (si está definido), 'Alpha' (si está definido) y una constante. Tenga en cuenta que los canales 'Black' y 'Alpha' deben proporcionarse igualmente si la matriz tiene ese tamaño, aunque el valor en sí pueda no estar presente o no usarse. La última columna constante es simplemente una suma (o resta, si es negativa) a la fórmula. La 6.ª fila (si se proporciona) simplemente se ignora y no se usa. De forma predeterminada, la definición de la 'matriz' sigue la misma estructura que un núcleo de morfología/convolución definido por el usuario y se trata como un núcleo 'cuadrado' si no se especifica una geometría de tamaño. El desplazamiento del núcleo no se usa actualmente. El 'arreglo de valores' indicado se superpone entonces sobre una '6x6 identity matrix' (matriz identidad de 6x6) más grande (una diagonal de unos) antes de aplicarse a la imagen. Este manejo interno significa que en realidad puede simplificar el valor de la matriz con solo unas pocas filas de números, en lugar de todas ellas. Esto es especialmente útil cuando necesita incluir la 'constante' en los cálculos de color, o solo desea modificar un canal. Por ejemplo, invertir (negar) la imagen. |
magick rose: -color-matrix '6x3: -1 0 0 0 0 1
0 -1 0 0 0 1
0 0 -1 0 0 1' matrix_negate.png
![[Salida IM]](../static/img/color_mods/matrix_negate.png)
Establecer todos los valores del canal rojo al máximo (usando la 'constante')... |
magick rose: -color-matrix '6x1: 0,0,0,0,0,1' matrix_red_max.png
![[Salida IM]](../static/img/color_mods/matrix_red_max.png)
Debido a la superposición sobre la matriz identidad, ninguno de los demás valores de canal se ve afectado, aunque internamente se recalculan igualmente. | Antes de IM v6.6.1-0, "[-color-matrix](https://imagemagick.org/command-line-options/#color-matrix)" se llamaba "-recolor.
---|---
Ejemplos de Color Matrix
Color sepia, o al menos una forma lineal de esa operación |
magick rose: -color-matrix ' 0.393 0.769 0.189
0.349 0.686 0.168
0.272 0.534 0.131 ' matrix_sepia.png
![[Salida IM]](../static/img/color_mods/matrix_sepia.png)
Colores vívidos, con una técnica llamada Digital Velvia... |
magick rose: -color-matrix ' 1.2 -0.1 -0.1
-0.1 1.2 -0.1
-0.1 -0.1 1.2 ' matrix_vivid.png
![[Salida IM]](../static/img/color_mods/matrix_vivid.png)
Esta matriz aclara cada canal de color mientras resta los colores de los demás canales, haciendo que los colores sean más vívidos en la imagen RGB. Esto no es exactamente lo mismo que usar Modulate para aumentar la saturación de color de una imagen en un 20%, pero es similar a ello. Color Polaroid... |
magick rose: -color-matrix \
'6x3: 1.438 -0.122 -0.016 0 0 -0.03
-0.062 1.378 -0.016 0 0 0.05
-0.062 -0.122 1.483 0 0 -0.02 ' matrix_polaroid.png
![[Salida IM]](../static/img/color_mods/matrix_polaroid.png)
Futuro: rotaciones de matiz usando una matriz de color...
Como se describe en la página web de Grafica Obscura.
Para más información sobre el uso de una matriz de color, consulte...
- Color Matrix Filter Adobe Flash Tutorial
- Color Transformations and the Color Matrix
- ColorMatrix Unleased
- Grafica Obscura - Matrix Operations for Image Processing
- SWF Color Matrix Filter (para rotación de matiz con preservación de la luminancia)
Sin embargo, tenga cuidado: la mayoría de estas implementaciones usan una forma diagonalmente transpuesta de la matriz, en la que las columnas forman la ecuación en lugar de las filas. O bien involucran menos canales (un número menor de filas/columnas).
Coloreado por solarización
"[-solarize](https://imagemagick.org/command-line-options/#solarize)" una imagen consiste básicamente en 'quemar' los colores más brillantes hasta el negro. Cuanto más brillante es el color, más oscuro es el color solarizado. Esto ocurre en fotografía cuando la película química se sobreexpone. |
magick rose: -solarize 90% solarize.jpg
![[Salida IM]](../static/img/color_mods/solarize.jpg)
Básicamente, todo lo que esté por encima del nivel de escala de grises indicado se niega. Así que, si da un argumento de '0%', básicamente tiene una versión pobre del operador Negate. Por ejemplo, aquí hay un "[-solarize](https://imagemagick.org/command-line-options/#solarize)" simulado usando una fórmula matemática "[-fx](https://imagemagick.org/command-line-options/#fx)". |
magick rose: -fx '.9>u ? u : 1-u' solarize_fx.jpg
![[Salida IM]](../static/img/color_mods/solarize_fx.jpg)
Este operador es particularmente adecuado para extraer los grises de tonos medios de las imágenes. Por ejemplo, aquí uso una operación de contraste sigmoidal muy fuerte para producir una especie de umbral 'difuso' en el 70% de gris. Luego solarizo el resultado para generar un pico difuso en lugar de un umbral difuso. Un ajuste de nivel final lleva entonces el pico al máximo brillo para generar un efecto de 'filamento'.
magick -size 10x300 gradient: -rotate 90 \
-sigmoidal-contrast 50x70% fuzzy_thres.png
magick fuzzy_thres.png -solarize 50% fuzzy_spike.png
magick fuzzy_spike.png -level 0,50% filament.png
NOTA AL MARGEN: Las imágenes anteriores que muestran gráficos de 'perfil' del degradado se generaron usando "[im_profile](../static/img/scripts/im_profile)" del directorio de Scripts de los IM Examples. Observe cómo todo lo que es blanco se vuelve negro, mientras que los grises de tonos medios alrededor del pico central se preservan. La difuminación y la ubicación del pico están determinadas por el operador "[-sigmoidal-contrast](https://imagemagick.org/command-line-options/#sigmoidal-contrast)". Lo llamo 'filamento' porque, normalmente, el resultado se parece notablemente a filamentos eléctricos incandescentes o a descargas de rayos. Para ver otro ejemplo de este efecto, consulte Random Flux. Esta extracción de los grises de tonos medios también se aprovecha en las técnicas para generar contornos de bordes a partir de formas de mapa de bits y para la multiplicación de dos degradados sesgados. Otro uso novedoso de esta operación es determinar si una imagen es básicamente un boceto o dibujo en blanco y negro puro (como el de un libro), en lugar de una imagen en escala de grises sombreada o en color. Consulte Determinar si una imagen es: blanco y negro puro, o escala de grises
Recoloreo de imágenes con tablas de consulta
Aunque se pueden recolorear imágenes usando los diversos ajustes de color de histograma mostrados arriba, existe otra técnica para recolorear imágenes, simplemente 'consultando' los valores modificados a partir de un degradado de colores preparado de antemano, o "tablas de consulta de color" (Color LUT, o CLUT). Hay dos tipos de Color LUT: las LUT simples unidimensionales o 'por canal' y las LUT de color 3D. Una LUT de canal tiene tres tablas de consulta independientes: una para cada uno de los canales R, G y B. Cada entrada de la LUT de canal mapea un valor de canal de entrada a un valor de canal de salida. El canal rojo de la imagen de salida solo se ve afectado por el valor rojo original de la imagen de entrada. Una LUT de color 3D, en cambio, permite reemplazar el color completo como una función del color de entrada completo. Es decir, el valor de salida del canal rojo puede depender de cualquiera o de todos los valores de entrada rojo, verde y azul. Esto a veces se denomina diafonía de canal.
Tablas de consulta de color (canal)
Un requisito común de una herramienta de procesamiento de imágenes es la capacidad de reemplazar todo el rango de colores a partir de una tabla de colores preparada de antemano. Esto permite convertir imágenes de un conjunto de colores (generalmente escala de grises) en un conjunto de colores completamente distinto, con solo consultar su color de reemplazo en una imagen especial. Por supuesto, se necesita una imagen de 'tabla de consulta' de la que leer los colores de reemplazo. Para estos primeros ejemplos, opté por usar un degradado vertical de colores para la LUT, de modo que el generador "[gradient:](canvas.html#gradient)" de IM pueda usarse para simplificar la generación de la 'tabla de consulta de color'. Bueno, basta de teoría. Probémoslo recoloreando una sencilla imagen de plasma en escala de grises, reemplazando la escala de grises por un degradado de colores de azul oscuro a blanco hueso.
magick -size 100x100 plasma:fractal -virtual-pixel edge -blur 0x5 \
-shade 140x45 -normalize \
-size 1x100 xc:black -size 9x100 gradient: \
+append gray_image.jpg
magick -size 10x100 gradient:navy-snow gradient_ice-sea.png
magick gray_image.jpg gradient_ice-sea.png -clut gray_recolored.jpg
El operador "[-clut](https://imagemagick.org/command-line-options/#clut)" toma dos imágenes. La primera es la imagen en la que se reemplazan los valores de color; la segunda es una imagen de degradado que es una sola fila o una sola columna. |
El operador "[-clut](https://imagemagick.org/command-line-options/#clut)" se añadió en IM v6.3.5-8. |
|---|---|
Si su IM es demasiado antiguo para entender el operador "[-clut](https://imagemagick.org/command-line-options/#clut)" o si quiere hacer algo fuera de lo común, como una tabla de consulta de color bidimensional, puede crear la suya propia usando el operador DIY general, FX. Por ejemplo, este es un comando lento pero equivalente al anterior. |
magick gray_image.jpg gradient_ice-sea.png \
-fx 'v.p{0,u*v.h}' gray_recolored_fx.jpg
![[Salida de IM]](../static/img/color_mods/gray_recolored_fx.jpg)
El problema es que, incluso para un proceso sencillo como el anterior, el operador "[-fx](https://imagemagick.org/command-line-options/#fx)" es muy lento y debe diseñarse específicamente para una LUT de fila o de columna. Pero funciona. La LUT no tiene por qué ser muy grande. Por ejemplo, aquí usamos una LUT muy pequeña, con un número muy limitado de colores.
magick -size 1x6 gradient:navy-snow gradient_levels.png
magick gray_image.jpg gradient_levels.png -clut gray_levels.jpg
Amplié la imagen de degradado para mostrarla arriba en la página web, de lo contrario sería demasiado pequeña para verse correctamente. La LUT en realidad solo tiene 6 píxeles de tamaño. Sin embargo, si observa el resultado, verá que el operador de consulta de color suaviza esos 6 colores hasta formar un degradado uniforme. Lo que ocurre es que IM realiza una consulta interpolada de la imagen de la LUT. Es decir, en lugar de elegir simplemente el color encontrado, realiza un promedio ponderado de todos los colores cercanos para representar mejor la LUT. En este caso particular, usó el ajuste '[Bilinear](misc.html#bilinear)' predeterminado, que simplemente une cada píxel coloreado mediante segmentos de línea recta. Diferentes ajustes de "[-interpolate](https://imagemagick.org/command-line-options/#interpolate)" generan distintos niveles de suavizado de los colores al usar una LUT de color muy pequeña. Aquí, por ejemplo, muestro varios tipos de suavizado interpolado de los colores de la LUT.
magick gray_image.jpg gradient_levels.png \
-interpolate Integer -clut gray_levels_integer.jpg
magick gray_image.jpg gradient_levels.png \
-interpolate NearestNeighbor -clut gray_levels_nearest.jpg
magick gray_image.jpg gradient_levels.png \
-interpolate Average -clut gray_levels_average.jpg
magick gray_image.jpg gradient_levels.png \
-interpolate Blend -clut gray_levels_blend.jpg
magick gray_image.jpg gradient_levels.png \
-interpolate BiLinear -clut gray_levels_bilinear.jpg
magick gray_image.jpg gradient_levels.png \
-interpolate Catrom -clut gray_levels_catrom.jpg
magick gray_image.jpg gradient_levels.png \
-interpolate Spline -clut gray_levels_spline.jpg
![[Salida de IM]](../static/img/color_mods/gray_levels_integer.jpg)
Integer | ![[Salida de IM]](../static/img/color_mods/gray_levels_nearest.jpg)
Nearest | ![[Salida de IM]](../static/img/color_mods/gray_levels_average.jpg)
Average | ![[Salida de IM]](../static/img/color_mods/gray_levels_blend.jpg)
Blend | ![[Salida de IM]](../static/img/color_mods/gray_levels_bilinear.jpg)
BiLinear | ![[Salida de IM]](../static/img/color_mods/gray_levels_catrom.jpg)
Catrom | ![[Salida de IM]](../static/img/color_mods/gray_levels_spline.jpg)
Spline
---|---|---|---|---|---|---
Los ajustes '[Integer](misc.html#integer)' y '[Nearest](misc.html#nearest)' son especiales porque no suavizan los colores en absoluto. Es decir, no se añadirán nuevos 'colores mezclados', solo se usarán los valores de color exactos presentes para colorear una imagen en escala de grises. Sin embargo, observe cómo difiere la consulta de los colores entre ambos. Es una diferencia sutil, pero puede ser muy importante. El ajuste '[Average](misc.html#average)', por su parte, también genera bandas de color, pero usando solo una mezcla de los colores, lo que da como resultado un color menos que el tamaño de la imagen de la tabla de consulta de color. '[Blend](misc.html#blend)', en cambio, mezcla '[Average](misc.html#average)' y '[Nearest](misc.html#nearest)' para añadir más píxeles. Este tipo de 'bandeado' de color (o artefactos de bloque) es en realidad bastante común en los mapas geográficos y los gráficos de temperatura, ya que ofrece una mejor representación de la forma exacta del mapa. Los bordes de límite nítidos se conocen como isolíneas. Añadir un ligero desenfoque de un píxel a la imagen final puede mejorar el aspecto de esos bordes, haciéndolos parecer un poco más suaves, sin destruir el bandeado de color. El ajuste '[BiLinear](misc.html#bilinear)' también genera bandeado, pero solo en forma de cambios de degradado nítidos, cuando los colores cambian bruscamente (no en este ejemplo). En cambio, '[Catrom](misc.html#catrom)' suaviza los cambios de color. Por último, '[Spline](misc.html#spline)' desenfoca los colores y puede no generar ninguno de los colores presentes en la CLUT dada. Para evitar problemas de interpolación, o para definir mejor los degradados de color, lo mejor es usar una LUT mucho más larga. Lo ideal es que cubra todo el rango de valores de intensidad posibles. Para ImageMagick Q16 (compilado con calidad de 16 bits), eso requiere una LUT con una altura de 65536 píxeles. Pero la interpolación de píxeles permite usar una imagen de degradado de LUT más razonable, de 500 píxeles, adecuada para la mayoría de las tareas de recoloreo de imágenes. Tenga en cuenta que la LUT de degradado vertical usada en los ejemplos anteriores se ve al revés para nuestros ojos, ya que el índice negro o '0' está en la parte superior de la imagen. Normalmente, los humanos preferimos ver degradados con el nivel de negro en la parte inferior (gracias a nuestro pasado evolutivo). Si prefiere guardar la imagen de degradado con la orientación 'correcta', puede aplicar "[-flip](https://imagemagick.org/command-line-options/#flip)" a la imagen al leerla. Por ejemplo, probemos una LUT más compleja, volteando el degradado vertical antes de usarlo sobre la imagen.
magick -size 1x33 gradient:wheat-brown gradient:Brown-LawnGreen \
gradient:DodgerBlue-Navy -append gradient_planet.png
magick gray_image.jpg \
\( gradient_planet.png -flip \) -clut gray_planet.jpg
Como puede ver, para un degradado vertical tiene mucho sentido voltearlo antes de usarlo. Para más ejemplos de generación de degradados, consulte Degradados de color. También podría interesarle una forma de teselar imágenes en escala de grises usando una imagen para cada nivel de gris, lo que puede producir imágenes tipo 'mapa' aún mejores. Consulte Tramado con patrones.
Conversión de función a Color LUT
Estas "imágenes de tabla de consulta" (o LUT) preparadas de antemano también pueden usarse para aumentar enormemente la velocidad de operaciones "[-fx](https://imagemagick.org/command-line-options/#fx)" muy complejas y, por tanto, lentas; así, en lugar de que IM interprete la cadena funcional 3 o 4 veces por píxel, puede realizar una consulta mucho más rápida del color de reemplazo. El procedimiento para hacer esto es bastante sencillo: o bien aplicar la función a un degradado lineal sin modificar, o bien reemplazar la 'u' de la función por el valor '(i/w)' o '(j/h)' para calcular el valor de reemplazo en función de su posición. Por ejemplo, en el ejemplo avanzado de efectos 'Aqua', usé una función "[-fx](https://imagemagick.org/command-line-options/#fx)" compleja para ajustar la salida en escala de grises del operador Shade". Además, como este ajuste de escala de grises también se superpone sobre una forma 'DodgerBlue', no hay razón por la que los resultados de ambos operadores no puedan combinarse en una única tabla de consulta de degradado. Es decir, generamos una LUT a partir de la fórmula "[-fx](https://imagemagick.org/command-line-options/#fx)" y de la superposición de color. Además, para estos ejemplos decidí generar una sola fila de píxeles en lugar de una columna como hice antes.
magick -size 1x512 gradient: -rotate 90 -alpha off \
-fx '3.5u^3 - 5.05u^2 + 2.05u + 0.3' \
-size 512x1 xc:DodgerBlue -compose Overlay -composite \
aqua_gradient.png
| El polinomio "[-fx](https://imagemagick.org/command-line-options/#fx)" anterior ahora puede generarse de forma más directa y rápida usando una función polinómica. Por ejemplo
_"[-function](https://imagemagick.org/command-line-options/#function) Polynomial 3.5,-5.05,2.05,0.3"_
---|---
Esta LUT pregenerada ahora puede aplicarse a la forma sombreada mucho más rápidamente, con el coste mínimo de almacenar una imagen muy pequeña.
magick -font Candice -pointsize 72 -background None label:A \
-trim +repage aqua_mask.png
magick aqua_mask.png -alpha Extract -blur 0x6 -shade 120x21 \
-alpha On -normalize aqua_shade.png
magick aqua_shade.png aqua_gradient.png -clut aqua_font.png
![[Salida de IM]](../static/img/color_mods/aqua_font.png)
ADVERTENCIA: lo anterior está incompleto (los bordes no se han oscurecido)
Como puede ver, el resultado es muy eficaz y, una vez generado un degradado de LUT apropiado, puede reutilizar el mismo degradado una y otra vez, tantas veces como quiera.
Manejo de CLUT y transparencia
El operador "[-clut](https://imagemagick.org/command-line-options/#clut)" está controlado por el ajuste "[-channel](https://imagemagick.org/command-line-options/#channel)", pero en realidad solo reemplaza los valores de canal individuales dentro de la imagen. Eso significa que, normalmente, cada canal individual de la imagen de origen se usa para 'consultar' el valor de reemplazo solo de ese canal en la tabla de consulta de color. Esto incluye el canal alfa, lo cual suele ser muy inconveniente y difícil de aplicar. Típicamente, el operador "[-clut](https://imagemagick.org/command-line-options/#clut)" se usa o bien para colorear una imagen de origen en escala de grises (consulte los ejemplos anteriores), O BIEN para realizar un ajuste de histograma de una imagen en color usando una CLUT (tabla de consulta de color) en escala de grises. En otras palabras, por lo general una de las imágenes suele estar en escala de grises. A partir de IM v6.4.9-8, si un ajuste "[-channel](https://imagemagick.org/command-line-options/#channel)" especifica que se desea reemplazar/ajustar el canal alfa de una imagen (está presente una 'A'), y o bien la imagen de 'origen' o bien la imagen 'CLUT' no tiene un canal alfa definido, entonces IM asumirá que esa imagen está en escala de grises y actuará en consecuencia. Por ejemplo, aquí genero un sencillo triángulo desenfocado, como una imagen en escala de grises. Luego puedo colorearlo usando una tabla de consulta de color que incluye transparencia. Esta vez no volteé la imagen CLUT, así que el reemplazo negro estará arriba y el reemplazo blanco abajo.
magick -size 100x100 xc: -draw 'polygon 50,10 10,80 90,80' \
-blur 0x10 blurred_shape.jpg
magick -size 1x5 xc:none \
-draw 'fill red point 0,2' \
-draw 'fill yellow rectangle 0,0 0,1' gradient_border.png
magick blurred_shape.jpg -alpha off gradient_border.png \
-channel RGBA -interpolate integer -clut clut_shape.png
Recuerde que lo anterior solo funcionará como se espera si la imagen en escala de grises no tiene canal alfa (desactivado mediante "[-alpha](https://imagemagick.org/command-line-options/#alpha) off" o "[-alpha off](https://imagemagick.org/command-line-options/#matte)") y se especifica que también se quieren consultar los valores del canal alfa (usando "[-channel](https://imagemagick.org/command-line-options/#channel) RGBA"). Y aquí está el otro caso especial, en el que tenemos una imagen con transparencia (y canal alfa) que debe ajustarse usando un degradado de ajuste de histograma en escala de grises (sin canal alfa habilitado).
magick -size 100x100 xc:none -draw 'polygon 50,10 10,80 90,80' \
tile_disks.jpg -compose In -composite shape_triangle.gif
magick shape_triangle.gif -channel A -blur 0x10 +channel shape_blurred.png
magick -size 1x50 gradient: xc:black -append -flip \
-sigmoidal-contrast 6x0% feather_histogram.jpg
magick shape_blurred.png \( feather_histogram.jpg -alpha off \) \
-channel A -clut shape_feathered.png
Lo anterior es un problema típico de suavizado de bordes (feathering) de imagen. El halo 'negro' de la imagen intermedia se debe a que la operación "[-blur](https://imagemagick.org/command-line-options/#blur)" hace visibles las áreas totalmente transparentes que rodean el triángulo. Como lo totalmente transparente tiene un color indefinido, IM usa el negro de forma predeterminada. La propia imagen CLUT se diseñó para garantizar que cualquier píxel con menos del 50 % de transparencia se vuelva totalmente transparente, haciendo de hecho que las partes previamente totalmente transparentes de la imagen vuelvan a ser transparentes. Para este ejemplo, exagero el 'desenfoque' inicial y luego sobrecorrijo el ajuste del canal alfa. El resultado es un redondeo severo de los vértices del triángulo. Para un suavizado de bordes de imagen normal se usarían típicamente valores mucho más pequeños tanto para "[-blur](https://imagemagick.org/command-line-options/#blur)" como para el ajuste de alfa "[-sigmoidal-contrast](https://imagemagick.org/command-line-options/#sigmoidal-contrast)". Fred Weinhaus ha implementado una técnica de suavizado de bordes por desenfoque en su script "feather", para facilitar su uso.
Tablas de consulta de color 3D Hald
A partir de IM v6.5.3-4 ahora también puede usar una tabla de consulta de color 3D completa, que puede emplearse para reemplazar directamente todos los colores de varias imágenes. Es decir, en lugar de consultar solo el valor de cada canal de color como una entidad separada (como en la CLUT anterior), se usa el color completo para consultar el nuevo color. No obstante, las tablas de color 3D suelen requerir formatos de archivo especiales para almacenar correctamente la matriz 3D de valores de color. Sin embargo, usando una disposición especial de los valores de color, la tabla 3D puede almacenarse en una imagen 2D conocida como Hald Color LUT. Esta es simplemente una imagen normal y, como tal, puede usarse CUALQUIER buen formato de archivo de imagen para guardar una Hald 3D Color LUT. Para más detalles y ejemplos de imágenes HALD, consulte el sitio web oficial Hald Images, Clut Technology. Para generar una tabla de color 3D Hald, use el generador de imágenes 'HALD:{_level_}'. Por ejemplo, aquí hay una pequeña que he ampliado para que pueda ver los píxeles individuales...
magick hald:3 hald_3.png
La tabla contiene un cubo de color con un lado de '{_level_}2' colores, es decir, 9 colores. El cubo de color completo contiene '9 × 9 × 9' colores, lo que da un total de 729 colores, que se almacenan en una imagen de la raíz cuadrada de ese número, es decir, 27x27 píxeles. Los colores se almacenan de modo que los primeros 9 colores (en la esquina superior izquierda) forman un degradado que va de 'pure-black' a 'pure-red'. Cada noveno color forma entonces un degradado en 'verde', y cada octogésimo primer color formará un degradado de 'azul'. El último color, en la esquina inferior derecha, es 'pure-white'. Puede pensar en la imagen como una matriz 1D de píxeles aún más simple que se referencia como un cubo de color 3D, si eso le ayuda a imaginarlo. Ahora bien, esta es solo una pequeña imagen HALD CLUT. Más típicamente usaría al menos una Hald de level 8 (la predeterminada), que contendrá un cubo de color con 64 colores por lado, es decir, 64^3 = 262144 colores, y producirá una imagen de 512x512 píxeles de tamaño, que se guarda en una imagen PNG de aproximadamente 10 Kbytes. Esto no son todos los colores de 8 bits, pero es bastante bueno. Para una imagen HALD con cada color de 8 bits, necesitaría una versión de level 16, que produce una imagen de 4096x4096. Lo cual demuestra que incluso las imágenes normales de cámara digital generalmente no pueden contener todos los colores posibles de 8 bits. Sin embargo, puede usarse una imagen Hald más pequeña, ya que IM interpolará los 8 colores vecinos de la Hald para calcular el color final del reemplazo de consulta. Simplemente no será una representación tan buena como una versión más grande. No se recomiendan imágenes Hald mayores de 8, y requerirían imágenes muy grandes, de al menos 16 bits por profundidad de valor para contenerla. Ahora bien, estas imágenes hald generadas son las imágenes CLUT 'identidad' o 'no-op'. Es decir, son los valores de color normales que forman el cubo de color 3D y, como tales, no producirán ningún cambio en la imagen. Por ejemplo, apliquemos una imagen Hald 'no-op' usando el operador "[-hald-clut](https://imagemagick.org/command-line-options/#hald-clut)"...
magick rose: hald_3.png -hald-clut rose_hald_noop.png
Esta imagen es exactamente igual a la original, y la imagen Hald no contenía cambios. Sin embargo, modificando la imagen Hald, ya sea a mano o usando una modificación de color, puede sustituir los colores originales por los colores modificados. Por ejemplo, aquí creo un esquema de color de tono sepia mezclado...
magick hald_3.png \( +clone -sepia-tone 60% \) -evaluate-sequence mean hald_sepia.png
magick rose.png hald_sepia.png -hald-clut rose_hald_sepia.png
Por supuesto, si puede aplicar una modificación de color específica a una imagen Hald, también puede aplicarla directamente a la imagen real. Pero ahora puede guardar sus modificaciones de color para reutilizarlas, y luego aplicarlas tantas veces como quiera. Eso significa que puede dedicar su esfuerzo a la hald y guardarla para el futuro. También puede enviar, o descargar imágenes Hald CLUT, para otras personas e incluso otras aplicaciones. Incluso podría editar directamente los colores de una Hald usando un editor de imágenes como "Gimp" o "Photoshop", o, si se guarda en una imagen de texto de píxeles enumerados, ¡usar un editor de texto plano! Todo esto es especialmente cierto en el caso de modificaciones de color muy complejas. Por favor, envíeme por correo cualquier imagen Hald CLUT que haya encontrado interesante o útil, ¡y la pondré aquí como ejemplo. Se le acreditará, también aquí!
Limitaciones de la Hald CLUT
A diferencia de la consulta de degradado unidimensional más simple usando el operador CLUT, puede usar una Hald CLUT para rotar colores. Por ejemplo, intercambiar los colores rojo y azul. Es un método CLUT mucho más versátil. Sin embargo, no es tan bueno para cosas más simples como colorear una imagen en escala de grises o realizar un ajuste de histograma de valores de color. También puede reemplazar colores por valores transparentes o semitransparentes, guardando dichos colores de reemplazo en la imagen Hald CLUT. No obstante, esta consulta de reemplazo es únicamente por color. No puede usarla para reemplazar colores transparentes de maneras específicas. ¡Al fin y al cabo, no es un hipercubo de consulta de color 4D!
Reemplazo de color usando Hald CLUT
Ahora bien, como se usa el valor de color completo para consultar el reemplazo de color, también podría usar esto como un método para reemplazar directamente todos los colores de una imagen por algún otro color. Sin embargo, como IM realiza actualmente una consulta interpolada lineal de la Hald, necesitará establecer el color de reemplazo en las 8 celdas de color vecinas del cubo de color 3D.
En construcción
Esto necesita más trabajo y podría requerir un ajuste de consulta Hald de 'nearest-neighbour' (digamos usando -interpolate), en lugar de una consulta interpolada lineal 3D, para funcionar mejor en el reemplazo de color específico. Además, alguna forma sencilla de localizar colores específicos en una Hald (nearest-neighbour, o los 8 vecinos) facilitaría mucho esto. Si tiene ideas, sugerencias o, mejor aún, pequeños ejemplos, contribuya enviándomelos por correo, a mí o a los foros de discusión de IM Otra idea es que, si tiene dos imágenes, la original y la convertida, entonces debería ser posible rellenar una imagen Hald CLUT a partir de la comparación de ambas imágenes. Una vez rellenados los colores inmediatos, el resto del cubo de color debería poder derivarse al menos aproximadamente ajustando una curva a los colores presentes. Es decir, crear una superficie de color 4-D a partir de los cambios de color descubiertos. Una vez completada, puede aplicar la Hald CLUT a cualquier otra imagen para realizar la misma transformación de color (en cualquier dirección) en cualquier otra imagen.
Reemplazo completo del mapa de colores
FUTURO: Reemplazar todos los colores de un mapa de colores por los colores de otro mapa de colores. Se agradecen sugerencias sobre la mejor forma de hacer esto, o programadores que implementen alguna función de mapa de colores de imagen. Un método podría ser usar las ideas presentadas en Tramado con símbolos. La mejor solución conocida (aunque difícilmente ideal) la proporciona actualmente Fred Weinhaus en su script "[mapcolors](http://www.fmwconcepts.com/imagemagick/mapcolors/index.php)". Este script esencialmente mapea cada color de uno en uno, enmascarando los píxeles implicados de una imagen hacia una nueva imagen inicialmente en blanco. Otra idea es mapear de algún modo un reemplazo de color tridimensional en una tabla de color HALD. Esto no solo mapeará los colores especificados, sino que también remapeará los colores intermedios entre los colores especificados de una manera lógica. Se busca generador de HALD.
En construcción
Más opciones de color aún por examinar en detalle...
-contrast
-brightness-contrast
¿Ciclado de color?
-cycle desplaza el mapa de colores (¿¿¿para animaciones de fractales???)
¿¿¿Puntos de color de cromaticidad???
–white-point x,y
–red-primary x,y
–green-primary x,y
–blue-primary x,y
Umbrales (tras la negación)
En concreto -white-threshold y -black-threshold
![[IM Output]](../static/img/color_mods/gray_colorspace.png)
![[IM Output]](../static/img/color_mods/gray_intensity.png)
| ![[IM Output]](../static/img/color_mods/test_negate.png)
![[IM Output]](../static/img/color_mods/rose_negate.gif)
![[IM Output]](../static/img/color_mods/negate_rgba.png)
![[IM Output]](../static/img/color_mods/negate_green.png)
![[IM Output]](../static/img/color_mods/negate_restore.png)
| ![[IM Output]](../static/img/color_mods/test_level.png)
![[IM Output]](../static/img/color_mods/rose_level.gif)
![[IM Output]](../static/img/color_mods/rose_level_light.gif)
![[IM Output]](../static/img/color_mods/rose_level_dark.gif)
![[IM Output]](../static/img/color_mods/rose_decontrast.gif)
![[IM Output]](../static/img/color_mods/rose_level_neg.gif)
![[IM Output]](../static/img/color_mods/rose_level_thres.gif)
| ![[IM Output]](../static/img/color_mods/test_level_plus.png)
![[IM Output]](../static/img/color_mods/rose_level_plus.gif)
![[IM Output]](../static/img/color_mods/test_level_undo.png)
![[IM Output]](../static/img/color_mods/test_level_const.png)
![[IM Output]](../static/img/color_mods/rose_level_gamma_light.gif)
![[IM Output]](../static/img/color_mods/rose_level_gamma_dark.gif)
![[IM Output]](../static/img/color_mods/test_blue_tint.png)
![[IM Output]](../static/img/color_mods/levelc_grn-gold.png)
![[IM Output]](../static/img/color_mods/levelc_dodger.png)
![[IM Output]](../static/img/color_mods/levelc_gold.png)
![[IM Output]](../static/img/color_mods/levelc_lime.png)
![[IM Output]](../static/img/color_mods/levelc_red.png)
![[IM Output]](../static/img/color_mods/levelc_navy.png)
![[IM Output]](../static/img/color_mods/levelc_darkgreen.png)
![[IM Output]](../static/img/color_mods/levelc_firebrick.png)
![[IM Output]](../static/img/images/cow.gif)
![[IM Output]](../static/img/color_mods/cow_red.gif)
![[IM Output]](../static/img/color_mods/levelc_faded.gif)
![[IM Output]](../static/img/color_mods/levelc_fire.gif)
![[IM Output]](../static/img/color_mods/levelc_tan.gif)
![[IM Output]](../static/img/color_mods/sigmoidal.png)
![[Salida de IM]](../static/img/img_photos/chinese_chess.jpg)
![[Salida de IM]](../static/img/color_mods/chinese_contrast.png)
![[Salida de IM]](../static/img/color_mods/chinese_chess_hist.gif)
![[Salida de IM]](../static/img/color_mods/chinese_contrast_hist.gif)
![[Salida de IM]](../static/img/color_mods/gray_range.jpg)
![[Salida de IM]](../static/img/color_mods/normalize_gray.jpg)
![[Salida de IM]](../static/img/color_mods/color_range.jpg)
![[Salida de IM]](../static/img/color_mods/normalize.jpg)
![[Salida de IM]](../static/img/color_mods/stretch_gray.jpg)
![[Texto de IM]](../static/img/color_mods/grad_hist_mod.txt.gif)
![[Texto de IM]](../static/img/color_mods/grad_cs_hist_mod.txt.gif)
![[Texto de IM]](../static/img/color_mods/grad_ls_hist_mod.txt.gif)
![[Texto de IM]](../static/img/color_mods/grad_lv_hist_mod.txt.gif)
![[Texto de IM]](../static/img/color_mods/grad_cs0_hist_mod.txt.gif)
![[Texto de IM]](../static/img/color_mods/grad_ls0_hist_mod.txt.gif)
![[Texto de IM]](../static/img/color_mods/info_port_mod.txt.gif)
![[Salida de IM]](../static/img/img_photos/port.png)
![[Salida de IM]](../static/img/color_mods/port_hist.gif)
![[Salida de IM]](../static/img/color_mods/port_cs1.png)
![[Salida de IM]](../static/img/color_mods/port_cs1_hist.gif)
![[Salida de IM]](../static/img/color_mods/port_cs1rgb.png)
![[Salida de IM]](../static/img/color_mods/port_cs1rgb_hist.gif)
![[Salida de IM]](../static/img/color_mods/port_ls1.png)
![[Salida de IM]](../static/img/color_mods/port_ls1_hist.gif)
![[Salida de IM]](../static/img/color_mods/port_ls1rgb.png)
![[Salida de IM]](../static/img/color_mods/port_ls1rgb_hist.gif)
![[Salida de IM]](../static/img/img_photos/zelda.png)
![[Salida de IM]](../static/img/color_mods/zelda_equal.png)
![[Salida de IM]](../static/img/color_mods/zelda_hist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_equal_hist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_ghist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_equal_ghist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_uniform.png)
![[Salida de IM]](../static/img/color_mods/zelda_uniform_hist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_uniform_ghist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_gaussian.png)
![[Salida de IM]](../static/img/color_mods/zelda_gaussian_ghist.gif)
![[Salida de IM]](../static/img/color_mods/zelda_hist_graph.gif)
![[Salida de IM]](../static/img/color_mods/gaussian_hist_graph.gif)
![[Salida de IM]](../static/img/color_mods/zelda_redist.png)
![[Salida de IM]](../static/img/color_mods/zelda_redist_graph.gif)
![[Salida de IM]](../static/img/color_mods/zelda_gaussian_redist.png)
![[Salida IM]](../static/img/color_mods/fx_linear_white.png)
![[Salida IM]](../static/img/color_mods/fx_linear_black_plot.gif)
![[Salida IM]](../static/img/color_mods/fx_linear_black.png)
![[Salida IM]](../static/img/color_mods/fx_linear_color_plot.gif)
![[Salida IM]](../static/img/color_mods/fx_linear_color.png)
![[Salida IM]](../static/img/color_mods/fx_linear.png)
![[Salida IM]](../static/img/color_mods/fx_non-linear_plot.gif)
![[Salida IM]](../static/img/color_mods/fx_non-linear.png)
![[Salida IM]](../static/img/color_mods/fx_quadratic_plot.gif)
![[Salida IM]](../static/img/color_mods/fx_quadratic.png)
![[Salida IM]](../static/img/color_mods/fx_expotential_plot.gif)
![[Salida IM]](../static/img/color_mods/fx_expotential.png)
![[Gnuplot]](../static/img/color_mods/fx_funct_plot.gif)
![[Gnuplot]](../static/img/color_mods/fx_funct.txt.gif)
![[Salida IM]](../static/img/color_mods/colorize_lighten.png)
![[Salida IM]](../static/img/color_mods/colorize_darken.png)
![[Salida IM]](../static/img/color_mods/colorize_grayer.png)
![[Salida IM]](../static/img/color_mods/tint_red.png)
![[Salida IM]](../static/img/color_mods/tint_lighter.png)
![[Salida IM]](../static/img/color_mods/tint_darker.png)
![[Salida IM]](../static/img/color_mods/rose_grey.jpg)
![[Salida IM]](../static/img/color_mods/sepia_goldenrod.jpg)
![[Salida IM]](../static/img/color_mods/sepia_gold.jpg)
![[Salida IM]](../static/img/color_mods/sepia_khaki.jpg)
![[Salida IM]](../static/img/color_mods/sepia_wheat.jpg)
![[Salida IM]](../static/img/color_mods/duotone_blue.jpg)
![[Salida IM]](../static/img/color_mods/duotone_darkcyan.jpg)
![[Salida IM]](../static/img/color_mods/duotone_goldenrod.jpg)
![[Salida IM]](../static/img/color_mods/duotone_firebrick.jpg)
![[Salida IM]](../static/img/color_mods/duotone_clut.gif)
![[Salida IM]](../static/img/color_mods/duotone_gradient.gif)
![[Salida IM]](../static/img/color_mods/rose_duotone.jpg)
![[Salida IM]](../static/img/color_mods/mod_bright_0.gif)
![[Salida IM]](../static/img/color_mods/mod_bright_50.gif)
![[Salida IM]](../static/img/color_mods/mod_bright_80.gif)
![[Salida IM]](../static/img/color_mods/mod_bright_100.gif)
![[Salida IM]](../static/img/color_mods/mod_bright_150.gif)
![[Salida IM]](../static/img/color_mods/mod_bright_200.gif)
![[Salida IM]](../static/img/color_mods/mod_sat_0.gif)
![[Salida IM]](../static/img/color_mods/mod_sat_20.gif)
![[Salida IM]](../static/img/color_mods/mod_sat_70.gif)
![[Salida IM]](../static/img/color_mods/mod_sat_100.gif)
![[Salida IM]](../static/img/color_mods/mod_sat_150.gif)
![[Salida IM]](../static/img/color_mods/mod_sat_200.gif)
![[Salida IM]](../static/img/color_mods/modulate_channel.png)
![[Salida IM]](../static/img/img_photos/wedding_party_sm.jpg)
![[Salida IM]](../static/img/color_mods/modulate_off-white.png)
![[Salida IM]](../static/img/color_mods/mod_bright_HSL.gif)
![[Salida IM]](../static/img/color_mods/mod_bright_HSB.gif)
![[Salida IM]](../static/img/color_mods/matrix_grayscale.png)
![[Salida IM]](../static/img/color_mods/fuzzy_thres_pf.gif)
![[Salida IM]](../static/img/color_mods/fuzzy_spike_pf.gif)
![[Salida IM]](../static/img/color_mods/filament_pf.gif)
![[Salida de IM]](../static/img/color_mods/gray_image.jpg)
![[Salida de IM]](../static/img/color_mods/gradient_ice-sea.png)
![[Salida de IM]](../static/img/color_mods/gray_recolored.jpg)
![[Salida de IM]](../static/img/color_mods/gradient_levels_mag.png)
![[Salida de IM]](../static/img/color_mods/gray_levels.jpg)
![[Salida de IM]](../static/img/color_mods/gradient_planet.png)
![[Salida de IM]](../static/img/color_mods/gray_planet.jpg)
![[Salida de IM]](../static/img/color_mods/aqua_gradient.png)
![[Salida de IM]](../static/img/color_mods/blurred_shape.jpg)
![[Salida de IM]](../static/img/color_mods/gradient_border.png)
![[Salida de IM]](../static/img/color_mods/clut_shape.png)
![[Salida de IM]](../static/img/color_mods/shape_triangle.gif)
![[Salida de IM]](../static/img/color_mods/shape_blurred.png)
![[Salida de IM]](../static/img/color_mods/feather_histogram.jpg)
![[Salida de IM]](../static/img/color_mods/shape_feathered.png)
![[Salida de IM]](../static/img/color_mods/hald_3_lg.png)
![[Salida de IM]](../static/img/color_mods/hald_3.png)
![[Salida de IM]](../static/img/color_mods/rose_hald_noop.png)
![[Salida de IM]](../static/img/color_mods/hald_sepia.png)
![[Salida de IM]](../static/img/color_mods/rose_hald_sepia.png)