Rekonstruieren Sie einen fehlenden RGB-Kanal


11

Schauen Sie sich diese Fotos von natürlichen Szenen an, aus denen einer der RGB-Kanäle herausgenommen wurde:

Ein idyllischer Wald ohne Rot

Quelle (mit rot): https://en.wikipedia.org/wiki/File:Altja_j%C3%B5gi_Lahemaal.jpg

ein antarktisches Ufer ohne Grün

Quelle (mit grün): https://commons.wikimedia.org/wiki/File:2007_mather-lake_hg.jpg

ein roter Fuchs ohne Blau

Quelle (mit Blau): https://commons.wikimedia.org/wiki/File:Fox_01.jpg

Auch ohne einen der Kanäle können Sie wahrscheinlich erkennen, welche Farben bestimmte Dinge haben sollen, oder zumindest eine gute Idee haben, ob eine Rekonstruktion des fehlenden Kanals korrekt ist.

Hier ist zum Beispiel das erste Bild mit einem roten Kanal, der nur zufälliges Rauschen ist:

Foto 1 mit Rauschen hinzugefügt

Dieses Bild ist eindeutig keine genaue Rekonstruktion des roten Kanals. Dies liegt daran, dass Naturfotos im Allgemeinen nicht das gesamte RGB-Spektrum verwenden, sondern nur eine Teilmenge der "natürlich aussehenden Farben". Außerdem folgen die Rottöne bestimmten Verläufen, die mit den anderen korrelieren.


Ihre Aufgabe ist es, ein Programm zu erstellen, das ein Foto aufnimmt, bei dem ein Kanal entfernt wurde, und zu versuchen, das Originalbild so genau wie möglich zu approximieren, indem Sie den fehlenden Kanal rekonstruieren.

Ihr Programm wird danach bewertet, wie genau der fehlende Kanal mit dem Kanal des Originalbilds übereinstimmt, indem der Prozentsatz der Pixel gezählt wird, deren Werte dieses Kanals innerhalb von ± 15 (einschließlich) des tatsächlichen Werts im Originalbild liegen (wobei die Werte Bereich von 0 bis 255 wie bei einem Standard-8-Bit-Farbkanal).

Die Testfälle, für die Ihr Programm bewertet wird, finden Sie hier (9,04 MB Zip-Datei, 6 Bilder). Derzeit enthält es nur die drei obigen Beispielbilder und ihre Originale, aber ich werde später noch einige hinzufügen, um die vollständige Suite zu erstellen, sobald ich sie erstellt habe.

Jedes Bild wird verkleinert und auf 1024 x 768 zugeschnitten, sodass es in Ihrer Partitur das gleiche Gewicht hat. Das Programm, das die meisten Pixel innerhalb der angegebenen Toleranz vorhersagen kann, gewinnt.


1
Könnten Sie ein Scoring-Programm schreiben, z. B. in Python?
Orlp

Ich werde morgen darauf zurückkommen. Im Moment muss ich ins Bett gehen.
Joe Z.

Gibt es eine Laufzeitbeschränkung für das Programm?
Pause

@Lause Die Grenze ist Ihre Geduld, damit das Programm tatsächlich eine Ausgabe erzeugt.
Joe Z.

Antworten:


17

Python 3 + Scikit-Bild

Setzt einfach die Farbe des fehlenden Kanals auf den Durchschnitt der beiden anderen.

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)

Und die restaurierten Bilder:

Wald Fuchs eisig


3
Durchschnitt der beiden anderen - anscheinend viel genauer (subjektiv) als ich gedacht hätte. +1.
Digitales Trauma

2
Sie erinnern an handgetönte Daguerreotypien von vor langer Zeit. Sehr schön. +1

6

Lua, Love2D

Setzt einfach den fehlenden Kanal auf den kleineren der beiden verbleibenden Kanäle.

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

Nimmt einen Dateinamen als Argument in der Befehlszeile.

Wald Fuchs Schnee

Bonus

Ich habe versucht, den fehlenden Kanal auf 255- (a + b) einzustellen und den Wert zu klemmen. Um "die Lücke zu füllen". Die Ergebnisse sind nutzlos, aber herrlich.

Forrest Red Teal Fox Yellow Blue Schnee Lila Grün

Und mit 255- (a + b) / 2

Waldrot Cyan langweilig Fox Yellow Blue Boring Schnee Lila Grün Langweilig


Die Bilder sehen noch realistischer aus als die andere Antwort. Gut gemacht! Was passiert aus Neugier, wenn Sie stattdessen 255- (a + b) / 2 machen (keine Klemmung erforderlich)?
ETHproductions

Die Ergebnisse sind weniger gesättigt als die oben genannten. Ich werde sie der Antwort für das Kichern hinzufügen.
ATaco

Ich habe tatsächlich gekichert. Vielen Dank.
Gabriel Benamy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.