Алгоритм для вращения изображения 90 градусов на месте? (Никакая дополнительная память)

Во встроенном приложении C у меня есть большое изображение, которое я хотел бы повернуть на 90 градусов. В настоящее время я использую известный простой алгоритм, чтобы сделать это. Однако этот алгоритм требует, чтобы я сделал другую копию изображения. Я хотел бы постараться не выделять память для копии, я скорее поверну ее оперативный. Так как изображение не является квадратным, это хитро. Кто-либо знает о подходящем алгоритме?

Отредактированный для добавления разъяснения, потому что люди спрашивают:

Я храню изображение в обычном формате:

// Images are 16 bpp
struct Image {
    int width;
    int height;
    uint16_t * data;
};

uint16_t getPixel(Image *img, int x, int y)
{
    return img->data[y * img->width + x];
}

Я надеюсь переместить содержание data массив вокруг, затем подкачайте по width и height членские переменные. Таким образом, если я запущу с изображения на 9x20 пикселей, затем поверну его, то я закончу с изображением на 20x9 пикселей. Это изменяет шаг изображения, которое усложняет алгоритм много.

38
задан user9876 3 June 2010 в 18:06
поделиться

4 ответа

Это может помочь: In-place matrix transposition.

(Возможно, вам также придется сделать некоторое зеркальное отражение после транспонирования, как упоминает rlbond).

29
ответ дан 27 November 2019 в 03:44
поделиться

Если вы читаете изображение из памяти в «неправильном порядке», это по сути то же самое, что вращать его. Это может или не может подходить для того, что вы делаете, но вот:

image[y][x] /* assuming this is the original orientation */
image[x][original_width - y] /* rotated 90 degrees ccw */
image[original_height - x][y] /* 90 degrees cw */
image[original_height - y][original_width - x] /* 180 degrees */
22
ответ дан 27 November 2019 в 03:44
поделиться

Это может быть слишком расплывчатым и не тем, что вы ищете, но я все равно опубликую.

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

Итак, вы должны либо пройти через каждый столбец пикселей (0-> columns / 2) и поменять местами их (так что вам нужна только временная память для 1 пикселя, а не всего изображения), либо прокручивать строки для горизонтального переворачивания .. Имеет ли это смысл? Если нет, разработаю / напишу код ..

1
ответ дан 27 November 2019 в 03:44
поделиться

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

uint16_t getPixel90(Image *img, int x, int y) 
{
    return img->data[(img->height - x) * img->width + y];
}

Где входные параметры x и y поменялись размерностью с исходной

6
ответ дан 27 November 2019 в 03:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: