Алгоритм поворота картинки

Lika25

Кто-нибудь знает хороший сабж? На sources.ru я нашел кое-что, оч. простой алгоритм, но потери информации оч. много (напр. при повороте на 5гр. CW, а потом 5гр. CCW появляется много зубчиков, хотя картинка почти не должна меняться). Вот в фотошопе - другое дело, но разработчики мне не скажут формулу преобразования . Инета Кири пока нет, посмотреть негде, может подскажет кто?

Ktitiss

imagemagick.org Очень хорошо крутят.

Lika25

Такой вопрос (у меня Кирин инет, его сейчас и нет): там прямо алгоритмы есть или сорсцы даже какие (т.е. надеяться мне или нет)? Мне лучше и то и другое!

Ktitiss

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

ocean

ну, например, можно рассмотреть картинку не как массив точек, а как массив квадратиков
соответственно, при повороте учитывать пересечения между ними и вычислять цвет

feo1978

Возможно "зубчики" просто сглаживаются на конечном этапе преобразования...(antialiasing).
В том же фотошопе если начертить жирную линию без опции сглаживания, то увидишь те же самые "зубчики"

ocean

по сути, антиалиасинг - это и есть операция "над квадратиками"
для линии яркость точки зависит от площади пересечения линии с пикселом
и происходит такая операция в процессе рисования, а не потом
сглаживание после построения картинки имеет более низкое качество
так как не связано с природой изображённых объектов

Sander

А такой алгоритм не покатит:
пусть исходная катинка это массив **d
1. Определяешь размеры картинки после поворота.
2. Обходишь все пиксели.
Рассматриваешь пиксель (i,j)
Поворачиваешь его в исходное изображение // знаешь как поворачивать?
Получаешь дробные координаты (x,y)
Вычисляешь цвет --- какую-нибудь сглаживающую формулу можно взять, ну например
color=( d[ floor(xfloor(y) ]*(1-x+floor(x+d[floor(x)+1,floor(y)]*(x-floor(x ) * (1-y+floor(y +
( d[ floor(xfloor(y)+1 ]*(1-x+floor(x+d[floor(x)+1,floor(y)+1]*(x-floor(x ) * (y-floor(y ;
Присваеваим цвет
PS
конечно алгоритм тупой, но работать вроде должен, простой в написании,
портить ни чего особенно не будет, только сглаживать картинку чуток при нескольких поворотах
PS 2
все это , мое ИМХО, я не спец в машграфе и т.п. так что может быть и лажу где-нибудь написал какую-нибудь

Lika25

Ага, спасибо за алгоритм и (выше) за антилиазинг (или как там его). В общем, я почти до него сам додумался, только вот не стал писать на языке и проверять "хорошесть" (правильная проверка и оценка - тоже дело не из простых). Вот решил узнать о имеющихся разработках, чтобы не изобретать круглое колесо заново. Так что, когда инет будет, посмотрю ту ГНУсную библиотеку и напишу здесь свое мнение (кому интересно). Однако, все же, если есть люди-профессионалы (никого не хочу обидеть) в деле с обработкой растра, напишите здесь. Основная проблема в том, что хочу повернуть черно-белое изображение с минимальными потерями, поэтому колдовство с Grayscale или даже Color, к сожалению, не подходит. Фотошоп, все-таки, хорошо справляется с задачей (при Monochrome) - значит алгоритм есть!

feo1978

Основная проблема в том, что хочу повернуть черно-белое изображение с минимальными потерями, поэтому колдовство с Grayscale или даже Color, к сожалению
Немного не понял, что значит не помогает с Color ? В случае чернобелого изображения, цвет пикселя определяется RGB(c,c,c) ; где с от 0-255.
т.е. если нужно "усреднить" пиксели с C1 = 255 и C2 = 0 получим (C1+C2)/2 = 127 , т.е. конечный RBG(127,127,127)...

Lika25

Черно-белое - не серое! Т. е. Monochrome - не Grayscale. Тогда цвет опр. как 0 (black) или RGB(255,255,255) (white).

Lika25

И такое же на выходе! Так что 127 не подходит!

feo1978

хм, а как тогда получиться сделать сглаживание ? если у тебя в палитре всего 2 цвета ..(white&black)...тут уже врятли что-то поможет..можно конечно попробовать сначала представить его как Grayscale повернуть а потом преобразовать в Monochrome, т.е. все где цвета>127 считать их White остальные Black, но думаю тут все равно не получиться то чего хотелось бы..

ocean

Алгоритм:
1) тупо увеличиваем картинку в несколько раз (например, в 15 чтобы каждый пиксел стал квадратиком
2) поворачиваем
3) уменьшаем. в каждом квадрате берём цвет, которого больше (при увеличении в нечётное число раз проблемы выбора не будет)

Lika25

Неплохой алгоритм все-таки есть. Вот что делает фотошоп.
исходник:
+ 5 CW:
+ 5 CCW:
Появились искажения, но незначительные (по сравнению с тем, что я видел на алгоритме с исходников.ру). Кстати, мне кажется, большие квадраты помогут настолько же, как и анти... (длинное слово главное - как определять во вновь уменьшенном, какой цвет белый и какой черный. Только затраты по памяти больше. А ЧБ был выбран именно из-за этого.

feo1978

Кстати есть еще один прием, когда из 2-х цветов можно сделать видимость третьего - например распологать рядом пиксель черный и белый , выглядеть данный стык будет примерно как серый...называется помоему этот метод как Dithering
p.s. cобственно по этому принципу и смешиваются цвета R,G,B на экране ЭЛТ. Два соседних пикселя конечно уже будет немного заметно, но суть примерно та же.

Lika25

Да, дизеринг - это хорошая идея, но, к сожалению, не могу его использовать, т.к. теряется связность областей. Мне просто важно как можно меньше потерять информации, а не сделать картинку приятнее для глаза. Однако, большое спасибо за идеи!

sirp

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

valy


А транзитивность при этом будет сохраняться?
т.е. +5+5-10 == 0 ?

Lika25

Доказать так на вскидку не могу, но считаю, что такое преобразование не возможно (кроме определенных углов, кратных Pi/2). Что-то интуитивно мощности не сравнимы... Хотя я могу ошибаться. Еще довод: наверное, тогда фотошоп использовал такой метод, но есть потери. Кстати, он монохром поворачивать на произвольный угол отказался, пришлось менять режим на серый, поворачивать и снова менять режим на монохромный.
2 yuriy: про транзитивность я не понял вопроса...

ocean

> Только затраты по памяти больше. А ЧБ был выбран именно из-за этого.
Увеличение можно делать виртуально, без дополнительных затрат памяти:
для каждого пиксела цикл, в котором он обходит квадратик и вычисляет цвет.

Lika25

Ок. Надо будет попробовать. Может оно и действительно хорошо повернет. Если получится - дам знать.
Оставить комментарий
Имя или ник:
Комментарий: