IgorTPH's blog

By IgorTPH, 15 years ago, In Russian
Я не силен в компьтерной графике. Насколько я понимаю, есть огромное количество людей, которые ей занимаются, потому что тема эта очень интересная. Поэтому я могу быть неточен в терминах и могу говорить о проблемах, которые уже давно решены, и если это так, то вы поправьте меня)

Как часть дипломной работы, передо мной встала задача трансформации изображения. Есть картинка и мы применяем к ее системе координат некоторое геометрическое преобразование (например, поворачиваем ее на определенный угол, но на самом деле у меня там делается перспективное преобразование). Вопрос в том, как расчитать цвет каждого пикселя нового изображения (всетчался термин resampling). Я поизучал, как этот вопрос решается в оупенсорсной библиотеке libpano.

Насколько я понял, стандартная техника такова. Мы перебираем пиксели результируеющего изображения и применяем к их координатам обратное преобразование. Смотрим, на какой пиксель исходного изображения указывает обратное преобразование. Его-то цвет мы и должны взять. Проблема в том, что если написать этот алгоритм именно в таком виде, получится изображение, в котором будут резкие переходы между цветами соседних пикселей (так называемый алиасинг). Существует, видимо, большое количество методов антиалиасинга. Те, которые я видел (в том же libpano) основываются на том, что мы начинам сглаживать картинку, рассматривая не только один пиксель исходного изображения, но и еще некоторые соседние с ним. Например, можно рассмотреть несколько пикселей вряд и взять их взвешенную сумму, или пропустить через них сплайн с нужной нам гладкостью. В подробности я особо не вникал.

Я решил реализовать "прямой" метод. Пиксели на самом деле квадратные (или прямоугольные, это не так важно). У квадрата есть четыре угла и при преобразовании они переходят в четыре точки в новой системе координат. Предположим, что пиксель достаточно мал, чтобы стороны квадрата остались отрезками прямых даже при преобразовании (ну или преобразование сохраняет прямые прямыми, как например поворот). Тогда цвет пикселя результирующего изображения можно вычислить, посмотрев, какие четырехугольники преобразованных пикселей имеют с ним общую площадь. По каждой цветовой компоненте RGB берем компоненту нашего пикселя, как взвешенную сумму компонент пикселей, пересекающих данный. В качестве веса выступает общая площадь квадрата и четырехугольника.

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

Итого: прямой метод может быть работает медленнее (надо сравнивать эффективность методов антиалиасинга), но зато не требует обратного преобразования и мне он нравится тем, что он делает все "честно", по-спортивному ;)
  • Vote: I like it
  • 0
  • Vote: I do not like it