Reconstruct a missing RGB channel
Python 3 + scikit-image
Simply sets the color of the missing channel to the average of the other two.
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)
And the restored images:
Lua, Love2D
Just sets the missing channel to the smaller of the two remaining channels.
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"))
Takes a filename as an argument on the command line.
Bonus
I tried setting the missing channel to 255-(a+b), clamping the value. As to "fill in the gap". The results are useless but glorious.
And with 255-(a+b)/2