Pull to refresh

Эксперимент с голографическим кодированием и декодированием информации

Algorithms *
Захотелось мне как-то сделать кодирование информации основываясь на голографическом принципе. Захотелось не просто так, а для проверки кое-каких своих идей и теорий. Теории не подтвердились, идеи не реализовались. Но поскольку подобного алгоритма я «с наскока» не нашёл и пришлось придумывать его самому, основываясь на учебниках по физике, то решил поделиться им на хабре. Алгоритм, кстати, довольно простой.

Итак, приступим.
Как делается голограмма. В общем случае, луч света от когерентного источника света тем или иным образом делится на две части, одна из которых попадает напрямую на фотопластинку, а другая часть тоже попадает на фотопластинку, но после отражения от объекта, голограмму которого мы желаем получить. В результате, на фотопластинке фиксируется картина интерференции света напрямую пришедшего из источника, и света отражённого от объекта.
Суть голографии в том, что в картине интерференции закодирована не только яркость той или иной точки объекта, но и расстояние до этой точки. Так получается потому что на фотопластинку приходят световые волны в разных фазах (а фаза зависит от расстояния до точки объекта), эти волны складываются в соответствии со своими фазами, за счёт чего собственно говоря и образуется картина интерференции.

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

У голограмы есть интересные свойства.
Например, восстановить полное изображение объекта можно по любому кусочку голографического снимка (с ухудшением качества изображения).
Можно на одну фотопластинку записать изображения нескольких объектов, воспользовавшись источниками света с разной длиной волны. И восстановить изображение каждого объекта в отдельности осветив фотопластинку светом с той же длиной волны, который был использован для записи нужного объекта.

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

Почему эта идея не реализовалась?
Во-первых — звук не картинка, картинку мы видим сразу полностью, и автоматически выделяем знакомые детали. А звук слушаем последовательно, и любая зашумлённость сильно ухудшает восприятие. Тем более, что при голографическом кодировании зашумлённость появляется в виде накладывающихся на исходный звук свистов, шипений и т.п.
Во-вторых сразу не учёл сложность алгоритма. Сложность алгоритма оценивается как O(n^2). Т.е. для кодирования (и декодирования) файла размером в 1 мегабайт требуется триллион (миллион миллионов) итераций, а при каждой итерации надо ещё и производить вычисления… Для примера, WAV-файл размером 10 килобайт (2-3 секунды звука) у меня кодировался около минуты (10 000 * 10 000 итераций = 100 млн. итераций). И ускорить алгоритм никак не получится. А для кодирования файла в 10 раз большего размера потребуется в 100 раз больше времени.
И в третьих — для получения нормального голографического изображения требуется что бы объект был контрастным. А какая контрастность в звуковом файле? Почти случайный набор чисел.

Но вернёмся к самому алгоритму, и его рабочей демонстрации.
Кодирование и декодирование осуществляется одним и тем же алгоритмом, но при декодировании изменяется пара коэффициентов.
Тестовый алгоритм обработки изображения был реализован на PHP, потому что «так быстрее» (для экспериментов с WAV-файлом использовался язык C).

Исходно: матрица яркости пикселей исходного изображения (для кодирования или декодирования потребуется 2500*2500 = около 6 миллионов итераций, в моём случае — несколько секунд работы PHP)
$data0[50][50];

На выходе: матрица яркости пикселей «на фотопластинке»
$data1[50][50];

$W=0.1; //длина волны источника света

//вычислим яркость каждой точки искомого изображения
for($x1=0;$x1<50;$x1++)
for($y1=0;$y1<50;$y1++) {

//опорный свет - считаем, что источник света излучает свет с силой достаточной для освещения
каждого пикселя с силой 256 единиц, но половину света мы отправили на объект, а половину света направили на фотопластинку (128 единиц).
$px=128.0; //эта часть света уже достигла фотопластинки, минуя объект (д.б. =0 при декодировании)

//яркость каждой точки искомого изображения - равна сумме света пришедшего ОТО ВСЕХ точек исходного изображения
for($x0=0;$x0<50;$x0++)
for($y0=0;$y0<50;$y0++) {

//расстояние от точки (x0;y0) до точки (x1;y1) считаем что везде z=1, плоская голограмма
$D=sqrt(1+($x0-$x1)*($x0-$x1)+($y0-$y1)*($y0-$y1));

// Фаза волны достигшей этой точки
$Phase=$D/$W;

//доля света от очередной точки объекта (по поводу коэффициента 0.3 - будет написано далее)
$obj_light=($data[$x0][$y0])*0.3;

//суммируем свет от очередной точки (в соответствии с фазой световой волны пришедшей от этой точки)
$px+=$obj_light*cos($Phase);

}
//волна оставляет пятно в любом случае, плюс она в этой точке или минус.
$px=abs($px);

//на выходе имеем - интенсивность света в точке (x1;y1)
data1[$x1][$y1]=$px;
}


Коэффициент в этой строке $obj_light=($data[$x0][$y0])*0.3; подбирается. Хотя можно для него и формулу вывести, правда отдельно для случая кодирования и случая декодирования.

Декодирование осуществляется этим же алгоритмом, только $px=128.0; изменяется на $px=0.0; (в данном случае, изображение восстанавливается только из отражённого света)

Ну и результаты работы.
Исходное изображение
image



Записанная голограмма и восстановленное по ней изображение
image image



Затёртая на 1/3 запись голограммы и восстановленное по ней изображение
image image



Затёртая более чем на 2/3 запись голограммы и восстановленное по ней изображение
image image



Для случая трёх точек и длины волны светового излучения W=1 пример есть тут.

Есть две причины сильных шумов:
  1. В эксперименте яркости точек округляются до целых в диапазоне 0..255. Часть информации теряется в отбрасываемых дробных частях, да и диапазон, конечно маловат.
  2. Малая площадь голограммы, всего лишь 50 на 50 точек. Это намного меньше квадратного миллиметра настоящей голограммы. В реальности для получения голограммы используют фотоматериалы с разрешающей способностью 5000 линий/мм.


Если нужна будет трёхмерность голограммы, то это не усложнит алгоритм, т.к. достаточно будет изменить формулу подсчёта расстояния D (сейчас голограмма плоская, координата Z всегда =1)

Вот такой вот эксперимент.
Tags:
Hubs:
Total votes 62: ↑61 and ↓1 +60
Views 9.1K
Comments 48
Comments Comments 48

Posts