Название: [РЕШЕНО] Как применить матрицу поворота к изображению?
Отправлено: Hrundel от Май 14, 2013, 20:38
Всем привет!
Будьте добры объясните как применять матрицу поворота к массиву. Массив, конечно, одномерный:
rgbQuad* bmp[];
где размер width*hight;
Как считать поворот пикселей для такого массива? Желательно без потерь!
Всем спасибо!
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Igors от Май 15, 2013, 08:11
Массив, конечно, одномерный:
rgbQuad* bmp[];
Это двумерный :) Проще всего создать QImage (можно и не копируя исходный массив) и использовать его удобные методы для поворота
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Disa от Май 15, 2013, 09:41
Если вдруг нужно написать самому, то что-то в духе (воспринимайте это как псевдокод навеянный С++ и Qt, сам код не проверял): C++ (Qt) void RotateImage(const int angle, const rgbQuad & bmp[][], const int widget, const int height, rgbQuad * outRGB[]) { double rad = 180.0f * angle / 3.141592f; // или M_PI double rotateMat[2][2] = {cos(rad), -sin(rad), sin(rad), cos(rad)} // или QMatrix2x2, но думаю и так ясно; // вычисление размеров результирующего изображения (координаты 3х углов) int x1 = height * rotateMat[1][0]; // sin(rad) int y1 = height * rotateMat[0][0]; // cos(rad) int x2 = width * rotateMat[0][0] + height * rotateMat[1][0]; int y2 = height * rotateMat[1][1] + width * rotateMat[0][1]; int x3 = width * rotateMat[1][1]; int y3 = width * rotateMat[0][1]; int minX = min(0, min(x1, min(x2, x3))); int minY = min(0, min(y1, min(y2, y3))); int maxX = max(0, max(x1, max(x2 ,x3))); int maxY = max(0, max(y1, max(y2, y3))); int newWidth = maxX - minX; int newHeight = maxY - minY; // нужно чтоб размеры outRGB стали newWidth x newHeight и чем-то залить // что-то типа resize(outRGB, newWidth, newHeight), fill(outRGB, Qt::gray); // применяем матрицу поворота for(int y = 0; y < height; ++y) { for(int x = 0; x < height; ++x) { int tx = x * rotateMat[0][0] + y * rotateMat[0][1]; int ty = x * rotateMat[1][0] + y * rotateMat[1][1]; outRGB[tx][ty] = bmp[x][y]; } } }
Т.е. вектор итогового положение точки - это матрица поворота, умноженная слева на исходное (ну как всегда при трансформации) + предварительное вычисление нового размера. Поправьте если где ошибся!
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Hrundel от Май 15, 2013, 09:54
Привет Игорь, да нет, я массив написал одномерным. Просто умножил строки на высоту и по полученному результату создал динамически одномерный массив. По заданию, профессор хочет, чтобы мы считали сами через матрицу. Ну я кажется уже понял как надо сделать. 1. Определиться с центром изображения и взять его для основания координат вращения. 2. Проходя циклом по каждой точке формировать из ее координат вектор. 3. Умножать вектор на матрицу поворота void RotateImage (int angle) { double rad = 180*angle/3.1415; double rmtrx[2][2] = { {qcos(rad),(-1)*qsin(rad)}, {qsin(rad),qcos(rad} };
for (int x=0; x< ... ; x++) { newx = (altx)*rmtrx[0][0] + (alty)*rmtrx[0][1] + offsetX; newy = (altx)*rmtrx[1][0] + (alty)*rmtrx[1][1] + offsetY; }
}
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Hrundel от Май 15, 2013, 09:55
Disa, Спасибо!
Я тоже к такому решению пришел. :D
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Igors от Май 15, 2013, 11:53
C++ (Qt) // вычисление размеров результирующего изображения (координаты 3х углов) int x1 = height * rotateMat[1][0]; // sin(rad) int y1 = height * rotateMat[0][0]; // cos(rad) int x2 = width * rotateMat[0][0] + height * rotateMat[1][0]; int y2 = height * rotateMat[1][1] + width * rotateMat[0][1]; int x3 = width * rotateMat[1][1]; int y3 = width * rotateMat[0][1];
В использовании своей структуры матрицы нет ничего плохого, но метод/ф-цию transform (или оператор *) надо писать. А то получается "дамское программирование" :) C++ (Qt) // применяем матрицу поворота for(int y = 0; y < height; ++y) { for(int x = 0; x < height; ++x) { int tx = x * rotateMat[0][0] + y * rotateMat[0][1]; int ty = x * rotateMat[1][0] + y * rotateMat[1][1]; outRGB[tx][ty] = bmp[x][y]; } } }
Так некоторые пиксели останутся незаполненными (за счет округления int). Надо наоборот, бежать по выходному имеджу и, применяя обратную матрицу, подставлять пыксели исходного имеджа. Причем не 1 (будет рванина) а неск с осреднением По заданию, профессор хочет, чтобы мы считали сами через матрицу.
Респект Вашему профессору, правильно, хорошо учит
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Disa от Май 15, 2013, 15:09
Так некоторые пиксели останутся незаполненными (за счет округления int) Спасибо за поправку, с ходу это не бросается в глаза.
Название: Re: Как применить матрицу поворота к изображению?
Отправлено: Hrundel от Май 15, 2013, 15:15
Всем спасибо! Удачи!
|