Московский государственный университет имени М.В.Ломоносова
Опубликован: 23.04.2007 | Доступ: свободный | Студентов: 3309 / 462 | Оценка: 4.18 / 3.71 | Длительность: 17:54:00
ISBN: 978-5-9556-0098-7
Специальности: Программист
Лекция 7:

Дискретизация. Антиалиасинг. Геометрические преобразования растровых изображений

Подход Веймана

Вейманом был предложен подход [50], основанный на кодах Ротштейна (см. [46], рис. 7.18). Код Ротштейна - это бинарный код длины p, который кодирует приблизительно равномерное распределение q единиц в p разрядов. Как было показано в "Алгоритмы растеризации отрезков, окружностей и эллипсов" , это эквивалентно кодированию смещений при растеризации отрезка. Данный подход позволяет осуществлять такие преобразования, как скос и масштабирование с коэффициентами, заданными рациональными числами. С помощью комбинации этих преобразований можно представить произвольное аффинное преобразование (см. ниже).

Код Ротштейна.

Рис. 7.18. Код Ротштейна.

Рассмотрим задачу масштабирования по горизонтали из изображения шириной q пикселей в изображение шириной p пикселей, p > q (т.е. коэффициент масштабирования равен p/q ). Для начала строится код Ротштейна (например, алгоритмом Брезенхема ( "Алгоритмы растеризации отрезков, окружностей и эллипсов" )). Наиболее просто скопировать q исходных колонок в те колонки, которые помечены кодом 1. Но это приведет к пробелам в тех столбцах, где значение кода равно 0. Поэтому данное распределение по колонкам применяется к циклическим перестановкам кода Ротштейна; при этом происходит суммирование в каждой колонке, а затем результат усредняется (делится на q, т.к. всего было p циклических перестановок и каждая колонка была закрашена q раз).

Для случая сжатия (когда p < q ) строится код длины q, и теперь уже, наоборот, 1 -цы соответствуют выбору тех исходных столбцов, которые копируются в результирующие p. Аналогично, с целью устранения алиасинга, результат усредняется по всем циклическим перестановкам кода (деление снова на q, т.к. прибавка к каждой колонке происходит при каждой перестановке).

// q - исходная ширина, p - ширина результата (p > q)
// I0 - исходное изображение (q x n)
// I1 - результирующее изображение (p x n)

I1 = 0; // установим все пиксели в I1 равными 0
code = ComputeCode( p, q ); // код длины p

// по всем циклическим перестановкам
foreach( perm in 1...p )
{
      code = CyclicShift( code );
      srcI = 0;

      foreach( dstI in 1...p )
            if( code[dstI] == 1 )
            {
                  foreach( J in 1...p )
                        I1(dstI,J) += I0(srcI,J);
                  srcI++;
            }
}
// усредняем
foreach( pixel in I1 )
      I1(pixel) = I1(pixel) / q;
Листинг 7.3. Алгоритм Веймана для растяжения по горизонтали

Для вертикального скоса с коэффициентом p/q < 1 применяется модификация, где 1 в коде указывает на то, что текущий столбец следует сдвинуть вверх на 1 пиксель (см. рис. 7.19). Так же, как и для растяжения, с целью фильтрации результат усредняется по циклическим перестановкам кода.

Алгоритм Веймана для вертикального скоса.

Рис. 7.19. Алгоритм Веймана для вертикального скоса.