реклама на сайте
подробности

 
 
> Поворот картинки (транспонирование матрицы), Как сделать через перестановки?
RHnd
сообщение May 18 2007, 17:33
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 518
Регистрация: 12-04-07
Из: Санкт-Петербург
Пользователь №: 26 997



Не совсем уверен, что правильно выбрал подфорум, но, надеюсь, мне помогут.
Задача ставиться так - в памяти лежит картинка NxM, ее нужно повернуть против часовой стрелки на 90 градусов. Так как картинка большая, а памяти мало, то просто переписать ее в новый блок памяти нельзя. Мне кажетя, что должен быть какой-то алгоритм перестановки элементов картинки, решающий задачу, но найтк его как-то не удается.

Пример:
По сути, задача сводится к транспонированию матрицы. Есть матрица 4x3, из нее получается 3x4:
Код
1 2 3                       3 6 9 C
4 5 6           =>          2 5 8 B
7 8 9                       1 4 7 A
A B C

В линейном виде (как в памяти лежит):
Было: Picture[12] = 1 2 3 4 5 6 7 8 9 A B C
Стало: NewPictute[12] = 3 6 9 С 2 5 8 B 1 4 7 A

А вот каким алгоритмом можно переставить элементы Picture так чтобы получился NewPicture для произвольных N и M, я не знаю. sad.gif Подскажите, пожалуйста!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SasaTheProgramme...
сообщение May 20 2007, 18:53
Сообщение #2


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Вот придумался алгоритм - очень не быстрый и требующий немножко памяти (всё-таки). Требуется буфер на одну строку. Допустим, исходный массив был M по горизонтали и N по вертикали. Нужен буфер на N позиций. Проходим по массиву. выклёвывая в буфер каждый M-тый элемент начиная с нулевого, т.е. перемещаем в буфер первый столбец. Теперь уплотняем массив (ой сколько пересылок!!! M вызовов memcpy!) с учётом скопированных элементов. Получившееся рассматриваем как массив (M-1)*N и свободный (!) хвост длины N. Переписываем буфер в хвост и повторяем всё сначала...

Сообщение отредактировал SasaTheProgrammer - May 20 2007, 18:56
Go to the top of the page
 
+Quote Post
RHnd
сообщение May 21 2007, 14:41
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 518
Регистрация: 12-04-07
Из: Санкт-Петербург
Пользователь №: 26 997



Цитата(SasaTheProgrammer @ May 20 2007, 22:53) *
Вот придумался алгоритм - очень не быстрый и требующий немножко памяти (всё-таки). Требуется буфер на одну строку. Допустим, исходный массив был M по горизонтали и N по вертикали. Нужен буфер на N позиций. Проходим по массиву. выклёвывая в буфер каждый M-тый элемент начиная с нулевого, т.е. перемещаем в буфер первый столбец. Теперь уплотняем массив (ой сколько пересылок!!! M вызовов memcpy!) с учётом скопированных элементов. Получившееся рассматриваем как массив (M-1)*N и свободный (!) хвост длины N. Переписываем буфер в хвост и повторяем всё сначала...

учитывая, что время нам не критично, то это действительно пока-что лучший алгоритм.
PS: Сегодня согласовывал память. Возможно, выделится место под дополнительный кадр. smile.gif
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 25 2007, 09:52
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(RHnd @ May 21 2007, 18:41) *
учитывая, что время нам не критично, то это действительно пока-что лучший алгоритм.
PS: Сегодня согласовывал память. Возможно, выделится место под дополнительный кадр. smile.gif


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

Считайте, что у вас матрица в одномерном массиве (так и есть - память линейная smile.gif ). Транспонирование матрицы - это перестановка элементов линейного массива в этой линейной памяти. Любая перестановка элементов упорядоченного множества распадается на набор циклических перестановок. Для квадратной матрицы это - попарные перестановки, для приямоугольной - более длинные циклы. Если элемент матрицы размера MxN имел индекс (i,j), его смещение в исходном массиве было M*i+j, и он переходит в элемент N*j+i. Пусть в этой ячейке располагается элемент (k,m). Имеем уравнение:

M*k+m = N*j+i

откуда

k = floor( (N*j+i) / M )
m = mod( N*j+i, M )

Далее мы переносим уже этот элемент в ячейку с индексом N*k+m и так далее, пока цикл не завершается. Можно бойтись вообще без дополнительной памяти - на каждом шаге переставлять элементы с началом цикла.

Ну и осталось правильно вычислить набор начальных элементов циклов и немного соптимизировать процесс вычисления индексов smile.gif


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
Oldring
сообщение May 26 2007, 09:28
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(Oldring @ May 25 2007, 13:52) *
Ну и осталось правильно вычислить набор начальных элементов циклов и немного соптимизировать процесс вычисления индексов smile.gif


По поводу оптимизации вычисления индексов.

Из уравнений

a = M*i+j
b = N*j+i

следует, что

b = N*a mod N*M-1

Если N*M является степенью двойки, или степенью двойки + 1 - то на поцессоре с быстрым умножением итерация становится тривиальной.


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- RHnd   Поворот картинки (транспонирование матрицы)   May 18 2007, 17:33
- - blackfin   Цитата(RHnd @ May 18 2007, 21:33) По сути...   May 18 2007, 18:03
|- - RHnd   Цитата(blackfin @ May 18 2007, 22:03) Ско...   May 18 2007, 20:05
|- - SasaTheProgrammer   Цитата(RHnd @ May 18 2007, 22:05) А не по...   May 19 2007, 23:09
- - Doka   Цитата(RHnd @ May 18 2007, 21:33) В линей...   May 18 2007, 18:35
- - SasaTheProgrammer   Цитата(RHnd @ May 18 2007, 19:33) Не совс...   May 18 2007, 18:41
|- - Doka   Цитата(SasaTheProgrammer @ May 18 2007, 22...   May 18 2007, 19:10
- - anton   1. В дсп камнях часто присутствует двумерное дма. ...   May 19 2007, 10:25
|- - RHnd   Цитата(anton @ May 19 2007, 14:25) 1. В д...   May 19 2007, 10:57
- - gfdsa   Алгоритм циклической перестановки для поворота кар...   May 20 2007, 16:10
|- - shasik   Не знаю на сколько еще актуально... Посмотрите кн...   May 25 2007, 08:59
- - SasaTheProgrammer   Вот какое-то решение из ФИДО (извините ребята, я с...   Jun 21 2007, 01:05


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 12th August 2025 - 12:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016