J'ai des images sRGB avec des dominantes de couleur. Pour le supprimer manuellement, j'utilise généralement les Réglages de niveau de Photoshop. Photoshop propose également des outils pour cela: Contraste automatique ou encore mieux Tonalité automatique qui prend également en compte les ombres, les tons moyens et les tons clairs.
Si je supprime la distribution manuellement, j'ajuste chacun des canaux RVB individuellement afin que les pixels les plus sombres soient réglés sur le noir pur et les plus clairs sur le blanc pur, puis je redistribue toutes les autres valeurs (en étalant l'histogramme). C'est une approche simple mais qui donne de bons résultats pour mes images.
Dans mon application node.js , j'utilise sharp pour le traitement d'image qui utilise libvips comme moteur de traitement. J'ai essayé de supprimer la distribution avec .normalize ()
mais cette commande fonctionne sur tous les canaux ensemble et non individuellement pour chacun des canaux RVB. Donc ça ne marche pas pour moi.
J'ai également posé cette question sur la page du projet pointu. J'ai testé la suggestion de lovell pour l'essayer avec hist_local
mais les résultats ne sont pas utilisables pour moi.
J'aimerais maintenant savoir comment cela pourrait être fait en utilisant les libvips natifs. J'ai joué avec l'interface graphique nip2 et différentes commandes, mais je n'ai pas pu comprendre comment cela pourrait être réalisé:
Merci pour chaque indice!
Ajout Voici un exemple avec des images de Photoshop pour montrer ce que je veux.
L'image source est une image d'une image d'un négatif de film. Image avant le traitement
Étape 1 Inverser l'image Image après inversion
Étape 2 à l'aide de la tonalité automatique dans Photoshop (fonctionne de la même manière que ma description ci-dessus concernant la suppression manuelle de la dominante de couleur) Image après la tonalité automatique
Cette dernière photo me convient.
3 Réponses :
nip2 a un élément de menu pour cela.
Chargez votre image et marquez-y une région contenant la zone que vous aimeriez être neutre. Cela peut être n'importe quelle légèreté, il n'a pas besoin d'être blanc.
De retour dans la fenêtre principale, cliquez sur Toolkits / Tasks / Capture / White balance. Vous devriez voir quelque chose comme:
Vous pouvez faire glisser et redimensionner votre région pour changer le point neutre. Utilisez le sélecteur de couleur pour définir la signification du blanc. Vous pouvez créer d'autres blancs avec (par exemple) Couleur / Nouveau / Couleur de CCT et les lier ensemble.
Vous pouvez maintenant faire glisser la région pour ajuster les pixels à partir desquels définir le neutre et faire glisser le curseur CCT pour régler la température.
Il peut être ennuyeux de trouver des éléments dans le menu de la boîte à outils. Il y a un truc pour rechercher des toolkits: dans la fenêtre principale, cliquez sur View / Toolkit browser. Vous pouvez saisir quelque chose comme "blanc" et il affichera les entrées de boîte à outils associées.
Salut jcupitt merci beaucoup pour cette explication détaillée! Je l'ai essayé mais je n'obtiens pas les mêmes résultats qu'avec mes actions Photoshop. J'ai ajouté plus de détails et aussi des images montrant mes étapes dans PS dans ma première question.
Étape 1 "Invert" fonctionne très bien avec sharp ou libvips. Mais je ne sais pas comment atteindre Step2. Je peux choisir les valeurs min et max pour chaque canal RVB (en utilisant les statistiques) mais je ne sais pas comment utiliser ces valeurs pour étaler l'histogramme de chaque canal sur toute la plage (0 ... 255).
Votre exemple PS semble simplement étirer les trois canaux indépendamment. Pour ce faire dans nip2, divisez les bandes, mettez-les à l'échelle, puis rejoignez-les. Je vais faire une autre réponse.
Je viens d'essayer vos suggestions en utilisant: Image-> Band-> Extract pour chaque canal, puis Image-> Levels-> Scale 0 ... 255 et enfin Image-> Join-> Bandwise Join. Cela donne un bon résultat avec une dominante bleu clair mais celle du PS est meilleure car la dominante bleue est plus claire. Je soupçonne que PS coupe quelques-unes des valeurs les plus basses et les plus élevées de l'histogramme. Est-il possible de définir de telles limites dans libvips?
Oui, je pense que PS ignore quelques pour cent de pixels à chaque extrémité lors du calcul de l'étirement. Vous pouvez faire la même chose dans nip2 en recherchant l'histogramme cumulatif normalisé, en établissant un seuil et en trouvant l'index.
Désolé, j'ai essayé de mettre en œuvre vos suggestions, mais je ne sais pas comment. Comment puis-je obtenir un histogramme cumulatif normalisé (intégrer?) Et effectuer le seuillage, trouver l'index et construire l'image finale? Désolé de vous déranger encore!
Voici une autre réponse, mais en utilisant pyvips et en répondant aux commentaires précédents. Je ne voulais pas supprimer la première réponse car cela me paraissait toujours utile.
Cette version trouve l'histogramme de l'image, recherche des seuils qui sélectionneront 0,5% et 99,5% des pixels dans chaque bande d'image, puis remet l'image à l'échelle pour que ces valeurs de pixel deviennent 0 et 255.
$ ./autolevel.py ~/pics/before.jpg x.jpg
Il semble donner des résultats à peu près similaires au bouton PS. Si je lance:
import sys import pyvips # trim off this percentage of pixels from the top and bottom trim_percent = 0.5 def percent(hist, percentage): """From a histogram, find the threshold above which lie @percentage of pixels.""" # normalised cumulative histogram norm = hist.hist_cum().hist_norm() # column and row profile over percentage c, r = (norm > norm.width * percentage / 100).profile() return r.avg() image = pyvips.Image.new_from_file(sys.argv[1]) # photographic negative image = image.invert() # find image histogram, split to set of separate bands bands = image.hist_find().bandsplit() # for each band, the low and high thresholds low = [percent(band, trim_percent) for band in bands] high = [percent(band, 100 - trim_percent) for band in bands] # rescale image scale = [255.0 / (h - l) for h, l in zip(high, low)] image = (image - low) * scale image.write_to_file(sys.argv[2])
Je vois:
p >
Merci pour cela! Maintenant, comprenez mieux. J'ai également trouvé une solution possible mais sans libvips qui, je pense, est plus simple à implémenter dans node.js. Parce que pour autant que je sache, sharp ne prend pas en charge certaines des commandes nécessaires à votre solution. Je poste une nouvelle réponse avec ma solution.
En attendant, j'ai trouvé l ' algorithme d'équilibre des couleurs le plus simple a> qui décrit exactement le problème des dominantes de couleurs et vous pouvez également y trouver un code source C.
C'est exactement la même solution que celle décrite par John dans sa deuxième réponse, mais comme un petit morceau de c-code.
J'essaye maintenant de l'utiliser comme addon C / C ++ avec N-API sous node.js.