Суммирование цветных графиков


9

В некоторых случаях, часто в физике, вы должны суммировать графики. Ваша задача - написать на выбранном вами языке программу или функцию, которая принимает несколько графиков в виде изображений, вычисляет все возможные суммы и выводит результат.

диаграммы

Графики - это изображения, которые содержат белый ( rgb(255, 255, 255)) фон с небелым пикселем в каждом столбце. Примеры:

примерный график примерный график примерный график

Значения скрипта представлены в виде позиций Y цветных пикселей. Значение в определенной координате X равно позиции Y самого верхнего цветного пикселя в этом столбце, с координатами, начинающимися с 0 слева внизу. По эстетическим причинам под этими пикселями могут быть или не быть дополнительные цветные пиксели.

задача

Ваша задача - написать на выбранном вами языке программу или функцию, которая принимает несколько графиков в виде изображений, вычисляет все возможные 2^n - 1суммы и выводит результат.

Сумма графиков - это график, где значение каждого столбца равно сумме значений соответствующего столбца в каждом из входных графиков.

Графики будут представлены в нескольких цветах. Полученное изображение должно содержать все возможные суммы графиков, как и другие графики, включая исходные графики, но исключая нулевую сумму.

Цвет каждой суммы определяется средним значением цветов включенных графиков, например, графиков цветов, rgb(255, 0, 255)и rgb(0, 255, 255)будет rgb(128, 128, 255)отображать график (также может быть округлен в меньшую сторону).

Полученное изображение должно быть настолько высоким, насколько это необходимо для размещения всех графиков. Это означает, что вам, возможно, придется выводить изображение больше, чем любой из входов.

Порядок, в котором результирующие графики рисуются на результирующем изображении, не имеет значения, т.е. если графики результатов перекрываются, вы можете выбрать, какой из них находится сверху, но это должен быть один из графиков, а не комбинация их цветов.

Можно предположить, что входные изображения имеют одинаковую ширину, что все столбцы изображений имеют по меньшей мере один небелой пиксель и что высота изображений (включая выходные данные) ниже 4096 пикселей.

пример

Вход A:

пример графика

Вход B:

пример графика б

Пример вывода:

пример графика суммы

(В случае, если кому-то это интересно, я скопировал данные для них из фондовых графиков случайных компаний. Это был первый способ получить реалистичные данные в формате CSV.)

правила

  • Вы можете выбрать любой формат входного файла растрового изображения.
  • Вы можете выбрать любой формат выходного файла растрового изображения, который не должен совпадать с входным.
  • Вы можете использовать библиотеки обработки изображений, однако любые функции для выполнения этой задачи напрямую запрещены.
  • Применяются стандартные лазейки .
  • Это , поэтому выигрывает самый короткий код в байтах.

Скрипт генератора графа

Вот скрипт Python 2, который генерирует графики. Входные данные даны в строках, с тремя первыми строками в качестве цвета RGB, а остальные в качестве данных, оканчивающимися EOF

import PIL.Image as image
import sys

if len(sys.argv) < 2:
    sys.stderr.write("Usage: graphgen.py <outfile> [infile]")
    exit(1)
outfile = sys.argv[1]
if len(sys.argv) > 2:
    try:
        stream = open(sys.argv[2], "r")
        data = stream.read()
        stream.close()
    except IOError as err:
        if err.errno == 2:
            sys.stderr.write("File \"{0}\" not found".format(sys.argv[2]))
        else:
            sys.stderr.write("IO error {0}: {1}".format(err.errno, err.strerror))
        exit(1)
else:
    data = sys.stdin.read()

try:
    items = map(int, data.strip().split("\n"))
    red, green, blue = items[:3]
    items = items[3:]
    highest = max(items)
except (ValueError, TypeError, IndexError):
    sys.stderr.write("Invalid value(s) in input")

img = image.new("RGB", (len(items), highest + 1), (255, 255, 255))

prev = items[0]
img.putpixel((0, highest - items[0]), (red, green, blue))
for x, item in enumerate(items[1:]):
    img.putpixel((x + 1, highest - item), (red, green, blue))
    if item < prev:
        for i in range(item + 1, prev):
            img.putpixel((x, highest - i), (red, green, blue))
    else:
        for i in range(prev + 1, item):
            img.putpixel((x + 1, highest - i), (red, green, blue))
    prev = item

img.save(outfile, "png")

@ MartinBüttner В настоящее время я делаю один для двух графиков. Я делаю это вручную (пока нет ссылок), поэтому я не знаю, хватит ли у меня терпения на 3. Кроме того, три, которые я дал, не могут быть суммированы, поскольку они имеют разную ширину.
PurkkaKoodari

Так что, если есть nвходные графики, будут ли 2^n - 1строки в выходном изображении?
Питер Тейлор

@PeterTaylor Да.
PurkkaKoodari

Я так понимаю, вывод не должен содержать вертикальные линии? Только самый верхний пиксель в каждом столбце?
Мартин Эндер

@ MartinBüttner Это правильно, так как эти данные все еще могут быть проанализированы как график, как определено в первом разделе.
PurkkaKoodari

Ответы:


3

MATLAB, 405

Звоните через: f('http://i.stack.imgur.com/ffCzR.png','http://i.stack.imgur.com/zHldg.png')

function f(varargin)
for k=1:nargin
i=im2double(imread(varargin{k}))
V(k,:)=size(i,1)-cellfun(@(V)find(any(V~=1,3),1),num2cell(i,[1,3]))
C(k,:)=i(find(any(i(:,1,:)~=1,3),1),1,:)
end
s=2^nargin-1
G=dec2bin(1:s)-'0'
C=bsxfun(@rdivide,G*C,sum(G,2))
V=G*V
m=max(V(:))
r=ones(m+1,size(V,2))
g=r
b=r
for i=1:s
M=bsxfun(@eq,(m:-1:0).',V(i,:))
r(M)=C(i,1)
g(M)=C(i,2)
b(M)=C(i,3)
end
imwrite(cat(3,r,g,b),'S.png')

4

Python, 422

Звонок из командной строки python plotsum im1.png im2.png im3.png

import sys
from numpy import*
from scipy import misc as m
R=m.imread
r=range
a=array
N=sys.args[1:]
L=len(N)
P=[map(argmin,R(n,1).T)for n in N]               #converts image to list of heights, counting from the top
C=a([R(N[i])[P[i][0],0,:]for i in r(L)])         #finds and stores the colour
P=a([len(R(N[i]))-a(P[i])for i in r(L)])         #flips the numbers, measures actual heights from bottom
w=len(P[0])
h=max(sum(P,0))+1                                    #compute dimensions
G=ones((h,w,3))*255                                  #and make a white grid
for i in r(1,2**L):
 z=where(a(list(bin(i)[2:].zfill(L)))=='1');y=sum(P[z],0)    #sum the graphs
 for x in r(w):G[y[x],x,:]=average(C[z],0)                   #average the colours
m.imsave('S.png',G[::-1])                            #flip image vertically and save

Пример вывода
введите описание изображения здесь
Другой пример
введите описание изображения здесь

Это было сложно, высокоуровневые операции с массивами и использование массивов в качестве индексов здесь очень помогают. Я не ожидаю увидеть решения под 1000 байтов, за исключением Mathematica и Matlab

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.