четверг, 27 декабря 2012 г.

How to make anaglyph (stereo, 3D) image with standard camera

If you do not have special equipment you still can create pretty good anaglyph images with standard camera.

What do we need for it?

1) Make two shots with little parallax. Try not to make large offset. For example if you make photo of a tree then offset must be about 6-10 сm.

2) You need special anaglyph glasses red-blue glasses.



3) Make following steps to get final image:

- Apply screen blenging operation (wiki) to the left and right images. Left must be blended with cyan color (0x00FFFF) and right with red color (0xFF0000).



- Having two changed images for left and right eyes blend them with multiply operation (wiki).



Make sure you adjusted images in such way, that objects on the photos matches with each other.

- Finally you get result. Put on glasses and enjoy!

Трехмерная модель скважины

Эту программу я начал писать еще два года назад как курсовую работу, она так и осталась недоделанная.

Недавно потребовалось довести проект до ума, в результате чего более половины исходников было переписано и добавлены новые возможности.

Программа достает из базы данных данные инклинометрии и любое количество кривых каверномера (профилемера).

Для расчета изменения направления ствола скважины использованы преобразования координат при помощи матриц поворота.

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

В результате получаем такие картинки:







Построение изолиний поверхности

Решение задачи не претендует на абюсолютную правильность реализации и не явлеяется самым лучшим и оптимальным. Предложенный алгоритм – попытка решения поставленной проблемы.

Задача.

Поверхность – двумерный массив размером nx на ny точек, в каждой из которых содержится Z отметка высоты. Пусть, поверхность хранится в массиве вида:

  1. std::vector<double> surf;

К элементу с номером i, j можно обратиться следующим образом: surf[j*nx + i];

Задача состоит в трассировке линий, принадлежащих этой поверхности, состоящих из точек с одинаковыми Z-отметками.

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

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

Поэтому для трассировки изолиний необходимо разбить существующие прямоугольники на треугольники следующим образом:



Подготовка.

Трассировка изолиний выполняется с заданным шагом dz в интервале изменения высот поверхности. Далее приведено описание построения изолинии для одной величины Z.

Первым этапом является проверка всех существующих граней на пересечение с заданной величиной Z.

Каждую грань легко задать одним узлом и направлением. Всего существует три направления: горизонтальное, вертикальное, диагональное. Поэтому, для хранения отмеченных граней понадобится массив такого же размера, как и масив поверхности nx на ny. Каждая ячейка массива будет хранить unsigned char число, являющееся битовым полем. В битовом поле закодированны три направления: 001 – горизонтальное, 010 – вертикальное, 100 – диагональное. Если ячейка массива содержит 0 – значит из этого узла не выходит ни одного ребра, пересекающегося с заданной величиной Z.




  1. std::vector<unsigned char> edges; // bit
  2. // так можно отметить вертикальную грань
  3. if ((z1 < curz) && (z >= curz))
  4. edges[y * nx + x] |= 2;


Итак, в цикле перебираем все точки поверхности и заносим информацию об отмеченных ребрах с специальный массив.



Трассировка.

Для того что бы трассировать линии удобно применить такой контейнер как очередь (FILO – First In Last Out). На каждом шаге цикла из очереди будет доставаться одна грань, рассчитываться координаты точки пересечения этой грани с плоскостью Z = Z0, анализироваться треугольник, которому принадлежит грань и добавляться новые грани в конец очереди.

Элементы хранимые в очереди – грани треугольников – отрезки соединяющие две соседние точки в массиве поверхности. Грань может быть представлена такой структурой данных:

  1. struct Edge
  2. {
  3. int knot1;
  4. int knot2;
  5. };



Каждый узел поверхности однозначно определяется целым числом, значение которого можно вычислить как j*nx+i, где i и j – координаты узла в массиве.
Так как каждая грань принадлежит двум треугольникам, удобно задавать ее координатами начала и конца. Это позволяет определить направление вектора-грани, что дает информацию о треугольнике, к которому принадлежит грань. Будем считать что все треугольники обходятся против часовой стрелки, и что бы узнать третью координату треугольника, достаточно обойти его против часовой стрелки по направлению вектора-грани.

Первый этап

Для начала надо найти хотя бы одну отмеченную грань. Последовательно перебираем массив, где хранятся метки граней и ищем значение не равное 0. Это означает, что из данный узел является началом хотя бы одной грани (горизонтальной, вертикальной, диагональной), пересекающей поверхность Z = Z0;

После того как узел найден, проверяем какая грань, выходящая из него, отмечена и добавляем эту грань в очередь. Причем добавляется прямое и инвертированное направление грани: (knot1, knot2) и (knot2, knot1). Это позволяет начать трассировку линий в двух направлениях.

Втоой этап.

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

а) Достаем грань из очереди и находим третью вершину, вместе с которой она образует треугольник. Третью вершину легко найти зная координаты вершин грани (knot1, knot2).
б) Проверяем две оставшиеся грани реугольника, если какая-либо грань пересекает плоскоссть Z = Z0 (проверяем массив с отмечеными гранями), добавляем ее в очередь.
в) Считаем точные координаты точки пересечения исходной грани треугольника с горизонтальной плоскостью. Это просто сделать, зная значения высот узлов грани Z1, Z2. и координаты точек (x1, y1) (x2, y2)
г) Добавляем полученную координату к текущей изолинии. Убираем метку этой грани из массива отмеченных граней и удяляем грань из очереди.

Повторяем цикл, пока очередь не исчерпается.











Стоит заметить, что самая первая грань в очереди добавляется два раза, в прямом и инвертированном направлении. Это необходимо для того, что бы начать построение изолинии сразу в двух направлениях. Если изолиния замкнутая, к таком способу можно не прибегать, но если изолиния разомкнутая и заканчивается на границах, требуется отследить ее в обе стороны, пока изолиния не дойдет до границы.. Для того что бы знать, в начало или в конец изолинии добавлять новую точку, можно хранить вместе с каждой отмеченной гранью переменную int direction, которая может принимать значения +1 или -1.

  1. struct Edge
  2. {

  3. int knot1;

  4. int knot2;

  5. int direction;
  6. };
Я использовал слово “грань”, которое в общем случае обозначает поверхность объемного многогранница для удобства, т.к. словосочетание “сторона треугольника” кажется мне не ёмким

Получение национальной визы в Германию


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

При подаче документов на национальную визу нужны следующие документы:

1. Заявление на получение национальной визы (можно найти на сайте посольства) с наклеенными фотографиями
2. Заявление в соответствии с параграфом 55 Закона о пребывании (обычно прилагается к основному заявлению)
3. Приглашение от университета
4. Подтверждение финансовой обеспеченности.

Про четвертый пункт подробнее. В случае, если вы получили стипендию (к примеру DAAD), то нужно предоставить документы о получении стипендии. Иначе, необходимо открыть блокированный счет (Sperrkonto) в немецком банке (к примеру Deutschebank) и предоставить выписку оттуда. Я такой счет открыть не смог, поэтому взял выписку с российского банка, со своего счета в евро, перевел на немецкий и заверил у нотариуса. Кроме того, я написал обязательство у нотариуса открыть блокированный счет сразу по приезду в Германию.

Могут быть полезными (но не обязательными) следующие документы:

5. Мотивационное письмо.
6. Сертификат о сдаче экзамена по немецкому (английскому, т.к. я буду учиться на английском)
7. Копии дипломов, заверенные и переведенные на немецкий язык.


Примерно через 4-6 недель позвонят из посольства и сообщат результат. Такой долгий срок рассмотрения связан с тем, что документы отправляют в Германию.

Надеюсь кому-то помог. И да, требования могут меняться, я могу ошибиться. Так что не гарантирую абсолютную правильность всего вышесказанного.