// функция поворота точки на угол alpha
void rotate(float &x, float &y, float alpha)
{
float nx = x * cos(alpha) - y * sin(alpha);
float ny = x * sin(alpha) + y * cos(alpha);
x = nx;
y = ny;
}
// функция репроекции снимка
void reproject(Mat *SrcImg, Mat *DstImg, REPROJECTION *Reprojection, INTERNALS *NewInternals)
{
if (!SrcImg->empty())
{
CvSize sz = SrcImg->size(); // получаем размер исходного изображения
Mat mx, my;
mx.create(sz, CV_32FC1); // создаем массивы горизонтальных и вертикальных координат на исходном изображении
my.create(sz, CV_32FC1);
for (int j = 0; j < sz.height; j++) // для каждой строки
{
for (int i = 0; i < sz.width; i++) // для каждого столбца
{
// тело цикла - преобразование координат выходного снимка в координаты на входном
float x = (i-NewInternals->cx) / NewInternals->fx;
float y = (j-NewInternals->cy) / NewInternals->fy;
float z = 1;
rotate(y, z, -Reprojection->ax * PI / 180); // производим повороты
rotate(x, z, -Reprojection->ay * PI / 180);
rotate(x, y, -Reprojection->az * PI / 180);
mx.at<float>(j, i) = Reprojection->internals.fx*x/z+Reprojection->internals.cx;
my.at<float>(j, i) = Reprojection->internals.fy*y/z+Reprojection->internals.cy;
}
}
// функция opencv преобразования снимка с субпиксельной точностью
remap(*SrcImg, *DstImg, mx, my, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0) );
mx.release();
my.release();
}
}
...
// исходные данные
REPROJECTION reproj[] =
{
{
{ 2117, 2328, 4589, 4589 }, // положение оптической оси 2117, 2328; фокусное - 4589
0, -12.52636814, 3.29980469 // углы поворота вокруг осей
},
{
{ 2117, 2368, 4623, 4623 }, // положение оптической оси 2117, 2368; фокусное - 4623
5.609776, 5.01366234, 1.30566382 // углы поворота вокруг осей
}
}; // положения оптических осей сдвинуты на одно и то же значение (4 по горизонтали, 2 по вертикали) относительно центрального креста для обоих снимков. впрочем, если не сдвигать, разница всё равно невелика, просто так чуть лучше
INTERNALS internals[DA_COUNT] =
{
{ sz.width/2-1000, sz.height/2, fx1, fy1 },
{ sz.width/2+300, sz.height/2, fx1, fy1 }
};
// вызов собственно репроекции
reproject(&img[DA_LEFT], &rimg[DA_LEFT], &reproj[DA_LEFT], &internals[DA_LEFT]);
reproject(&img[DA_RIGHT], &rimg[DA_RIGHT], &reproj[DA_RIGHT], &internals[DA_RIGHT]); Отредактировано: CodeGrinder - 25.04.2012 00:21:42
http://www.avanturist.org/forum/topic/682/offset/22000