Цитата: codegrinder
Это не сферические, а перспективные искажения. Нечто подобное я уже делал, кстати:
Нелинейных сферических искажений там должно быть совсем немного. А можно запостить сюда код преобразования (с АУ 1 сутки)? Только непосредственно часть с преобразованием. Или хотя бы формулы.
Я же уже показывал, где программа с исходным кодом:
http://glav.su/redir…ru/1247563Хоть перспективные, хоть еще какие, суть этих искажений в том, что сфера отображается на плоскость. Примерно так:
Здесь угол специально пошире - 90 вместо 45, чтобы было понятно, как к краю пластнки один и тот же угол начинает занимать все больше и больше пикселей, пропорционально тангенсу угла от оптической оси.
П.С. Да вот, соственно, вся процедура:
function TForm1.DoAnnihilate2(const fname: String): Boolean;
var J: PJpeg;
B, B2: PBitmap;
y, x, Cx, Cy: Integer;
focus_dist_w, angle_per_pixel_at_center_w, pixels_per_angle: Double;
Src, Dst: PRGBQuadArray;
R, angle, R1: Double;
x1, y1: Integer;
Lens_Angle: Double;
begin
Result := FALSE;
Lens_Angle := Str2Double( EditBox1.Text );
if Lens_Angle <= 1 then
begin
ShowMessage( 'Angle too low!' );
Exit;
end;
J := NewJpeg;
B2 := nil;
TRY
J.LoadFromFile( fname );
B := J.Bitmap;
B.PixelFormat := pf32bit;
B2 := NewDIBBitmap( B.Width, B.Height, pf32bit );
B2.Canvas.Brush.Color := clWhite;
B2.Canvas.FillRect( B2.BoundsRect );
focus_dist_w := B.Width / 2 / tan( Lens_Angle / 2 * PI / 180.0 );
angle_per_pixel_at_center_w := arctan2( 1, focus_dist_w );
pixels_per_angle := 1 / angle_per_pixel_at_center_w;
Cx := B.Width div 2;
Cy := B.Height div 2;
for y := 0 to B.Height-1 do
begin
Applet.ProcessMessages;
Src := B.ScanLine[y];
for x := 0 to B.Width-1 do
begin
R := sqrt( sqr( x - Cx ) + sqr( y - Cy ) );
angle := arctan2( R, focus_dist_w );
R1 := angle * pixels_per_angle;
if Abs(R1) > 0.0000001 then
begin
x1 := Cx + Round( R1 * (x - Cx) / R );
y1 := Cy + Round( R1 * (y - Cy) / R );
Dst := B2.ScanLine[ y1 ];
Dst[ x1 ] := Src[ x ];
end;
end;
end;
//B2.SaveToFile( ReplaceExt( fname, '_UPD2.bmp' ) );
J.Bitmap := B2;
J.CompressionQuality := 90;
J.SaveToFile( ReplaceExt( fname, '_UPD2.jpg' ) );
FINALLY
J.Free;
B2.Free;
END;
Result := TRUE;
end;