Были или нет американцы на Луне?
13,259,699 109,685
 

  CodeGrinder ( Слушатель )
05 сен 2009 18:33:03

Тред №143533

новая дискуссия Дискуссия  95

Ну что, кому был нужен перевод в сферическую(равноугольную) проекцию? Смотрите исходный код в конце.
Я взял два снимка: AS11-39-5750HR и AS11-39-5751HR и перевёл их в сферическую проекцию, параметры - фокусное расстояние 61,2 мм, 10 мм кадра - это 450 точек.
AS11-39-5750HR_Sphere.jpg
AS11-39-5751HR_Sphere.jpg
Затем совместил их в редакторе:


Так как у нас сферическая проекция, то совершенно непонятно как два камня ближе к горизонту по которым проводилось совмещение сохранили угловое расстояние но один из них стал значительно крупнее. Я так понимаю, что вариантов два: либо фокусное расстояние указано неправильно (но я пробовал и 81, 2 мм - камни уехали нафиг друг от друга), либо сдвиг фотографа, поворот не катит, т.к. проекция сферическая. Но для такого эффекта надо либо сдвиг конкретный (а фотографируя от окна сильно не подвигаешься, либо чтобы сами объекты съёмки были очень маленькие).

// фокусное расстояние datacamera
float gFocusLength = 61.2f;
// точек на 10 мм кадра
float gPixelsPer10mm = 450;
// подпрограмма перевода в сферичекую проекцию.
HBITMAP processBitmap(HBITMAP SrcBmp)
{
if (NULL != SrcBmp)
{
DIBSECTION ds;
if (sizeof(ds) == GetObject(SrcBmp, sizeof(ds), &ds)
&& 24 == ds.dsBm.bmBitsPixel)
{
int width = ds.dsBm.bmWidth; // ширина исходной картинки
int height = ds.dsBm.bmHeight; // высота исходной картинки
PBYTE pBits = (PBYTE)ds.dsBm.bmBits; // содержимое исходной картинки
double ax = atan(5.0*width/gPixelsPer10mm/gFocusLength); // угол половины кадра по горизонтали
double ax_1 = atan(10.0/gPixelsPer10mm/gFocusLength); // угол одной точки в центре по горизонтали
int cx = int(2*ax/ax_1); // размер нового изображения по горизонтали
double ay = atan(5.0*height/gPixelsPer10mm/gFocusLength); // угол половины кадра по вертикали
double ay_1 = atan(10.0/gPixelsPer10mm/gFocusLength);  // угол одной точки в центре по вертикали
int cy = int(2*ay/ay_1); // размер нового изображения по вертикали
BITMAPINFOHEADER bmih = // описываем картинку
{
sizeof(bmih),
cx,
cy,
1,
24,
BI_RGB,
0, 0, 0, 0, 0
};
PBYTE pNewBits = NULL; // и создаём (след. строка)
HBITMAP hbmr = CreateDIBSection(NULL, (BITMAPINFO *)&bmih, DIB_RGB_COLORS, (PVOID *)&pNewBits, NULL, 0);
if (NULL != hbmr)
{
int srcLineSize = (width*3+3)&~3; // размер строки исходной картинки в байтах
int dstLineSize = (cx*3+3)&~3; // размер строки конечной картинки в байтах

for (int j = 0; j < cy; j++)
{
for (int i = 0; i < cy; i++)
{
double xa = 2*ax*(i-cx/2.0f)/cx; // углы по координатам в новой картинке
double ya = 2*ay*(j-cy/2.0f)/cy;
int x = int(gFocusLength*tan(xa)*gPixelsPer10mm/10)+width/2; // координаты в старой
int y = int(gFocusLength*tan(ya)*gPixelsPer10mm/10)+height/2;
RGBQUAD *pSrc = (RGBQUAD *)(pBits + y*srcLineSize+x*3); // указатель на исходную точку
RGBQUAD *pDst = (RGBQUAD *)(pNewBits + j*dstLineSize+i*3); // указатель на конечную точку
pDst->rgbRed = pSrc->rgbRed; // копируем все 3 составляющие цвета
pDst->rgbGreen = pSrc->rgbGreen;
pDst->rgbBlue = pSrc->rgbBlue;
}
}
return hbmr;
}
}
}
return NULL;
}
Отредактировано: CodeGrinder - 20 авг 2014 12:57:32
  • +0.00 / 0
  • АУ
ОТВЕТЫ (0)
 
Комментарии не найдены!