Были или нет американцы на Луне?
13,215,911 109,566
 

  Зумер ( Слушатель )
11 ноя 2009 20:16:45

Тред №164013

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

Цитата: 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;
Отредактировано: Зумер - 11 ноя 2009 20:23:05
  • +0.00 / 0
  • АУ
ОТВЕТЫ (0)
 
Комментарии не найдены!