Reconstruire un canal RVB manquant

11

Regardez ces photos de scènes naturelles, avec l'un des canaux RVB retiré:

une forêt idyllique sans rouge

Source (en rouge): https://en.wikipedia.org/wiki/File:Altja_j%C3%B5gi_Lahemaal.jpg

une côte antarctique sans vert

Source (en vert): https://commons.wikimedia.org/wiki/File:2007_mather-lake_hg.jpg

un renard roux sans bleu

Source (en bleu): https://commons.wikimedia.org/wiki/File:Fox_01.jpg

Même sans l'un des canaux, vous pouvez probablement déterminer les couleurs de certaines choses, ou au moins avoir une bonne idée si la reconstruction du canal manquant est exacte.

Par exemple, voici la première image avec un canal rouge ajouté en arrière qui est juste un bruit aléatoire:

photo 1 avec bruit ajouté

Cette image n'est clairement pas une reconstruction précise du canal rouge. En effet, les photos de la nature n'utilisent généralement pas l'intégralité du spectre RVB, mais uniquement un sous-ensemble de "couleurs d'apparence naturelle". De plus, les nuances de rouge suivront certains gradients en corrélation avec les autres.


Votre tâche consiste à créer un programme qui prendra une photo dont un canal a été supprimé et tentera d'approximer l'image originale aussi près que possible en reconstruisant ce qu'il pense être le canal manquant.

Votre programme sera évalué en fonction de la correspondance entre le canal manquant et le canal de l'image d'origine, en comptant le pourcentage de pixels dont les valeurs de ce canal se situent à ± 15 (inclus) de la valeur réelle dans l'image d'origine (où les valeurs de 0 à 255 comme dans un canal de couleur 8 bits standard).

Les cas de test sur lesquels votre programme sera noté peuvent être trouvés ici (fichier zip de 9,04 Mo, 6 images). Actuellement, il ne contient que les trois images d'exemple ci-dessus et leurs originaux, mais j'en ajouterai quelques autres plus tard pour faire la suite complète une fois que je les aurai faites.

Chaque image est réduite et rognée à 1024 x 768, donc elles auront le même poids dans votre score. Le programme qui peut prédire le plus de pixels dans la tolérance donnée gagne.

Joe Z.
la source
1
Pourriez-vous écrire un programme de notation, par exemple en Python?
orlp
J'y reviendrai demain. En ce moment, je dois aller me coucher.
Joe Z.
Y a-t-il une limite à l'exécution du programme?
Lause
@Lause La limite est votre patience pour que le programme produise réellement une sortie.
Joe Z.

Réponses:

17

Python 3 + scikit-image

Définit simplement la couleur du canal manquant à la moyenne des deux autres.

import sys
from skimage import io, color

im = io.imread(sys.argv[1])
h, w, c = im.shape

removed_channel_options = {0, 1, 2}
for y in range(h):
    for x in range(w):
        if len(removed_channel_options) == 1: break
        removed_channel_options -= {i for i, c in enumerate(im[y][x]) if c > 0}
removed_channel = removed_channel_options.pop()

for y in range(h):
    for x in range(w):
        p = [float(c) / 255 for c in im[y][x][:3]]
        p = [sum(p)/2 if i == removed_channel else p[i]
             for i in range(3)]
        im[y][x] = [int(c*255) for c in p] + [255]*(c == 4)

io.imsave(sys.argv[2], im)

Et les images restaurées:

forêt Renard glacé

orlp
la source
3
moyenne des deux autres - apparemment beaucoup plus précis (subjectivement) que je ne l'aurais deviné. +1.
Digital Trauma
2
Ils rappellent les daguerréotypes teintés à la main d'autrefois. Très agréable. +1
6

Lua, Love2D

Définit simplement le canal manquant sur le plus petit des deux canaux restants.

local inp = love.image.newImageData(arg[2])

local channels = {1, 2, 3}
local removed = nil
local removed_options = {true,true,true}

inp:mapPixel(function(x,y,r,g,b)
    local o = {r,g,b}
    for k,v in pairs(o) do
        if v > 0 then
            removed_options[k] = false
        end
    end
    return r,g,b
end)

for k,v in pairs(removed_options) do
    if v then
        removed = k
        break
    end
end
inp:mapPixel(function(x,y,r,g,b)
    local o = {r,g,b}
    o[removed] = math.min(o[removed%3+1], o[(removed+1)%3 + 1])
    return unpack(o)
end)

inp:encode('png', IMAGE:gsub("%.png", "2.png"))

Prend un nom de fichier comme argument sur la ligne de commande.

Forêt Renard Neige

Prime

J'ai essayé de régler le canal manquant sur 255- (a + b), en fixant la valeur. Quant à "combler le vide". Les résultats sont inutiles mais glorieux.

Forrest Red Teal Renard Jaune Bleu Snow Purple Green

Et avec 255- (a + b) / 2

Forêt rouge cyan ennuyeux Fox Yellow Blue Boring Snow Purple Green Boring

ATaco
la source
Les images semblent encore plus réalistes que l'autre réponse. Bon travail! Par curiosité, que se passe-t-il si vous faites 255- (a + b) / 2 à la place (pas besoin de serrage)?
ETHproductions
Les résultats sont une version moins saturée de ceux publiés ci-dessus. Je vais les ajouter à la réponse pour les rires.
ATaco
J'ai, en fait, gloussé. Je vous remercie.
Gabriel Benamy