2009-03-18 4 views
6

Мне нужно преобразовать растровые изображения с их 4-мя угловыми точками, перемещенными из одного места в другое.4-точечное преобразование изображений

Любой код, который может работать в Windows, C#/VB.NET, предпочтительно, даже поможет использовать скриптовые программы, такие как Paint.NET или Photoshop. Java Advanced Imaging API звучит обнадеживающе.

мне нужна для системы манипуляции экрана, что позволяет получить такие эффекты:

alt text http://www.wholetomato.com/images/tour/mondoPerspectiveTrans.gif

ответ

1

легче, чем имитируя перспективу искажать с помощью манипуляции с изображениями, вы можете использовать OpenGL или DirectX (XNA) в фактически выполняют отображение перспективы.

Извлечь простой квадратик с изображением в качестве текстурной карты. Настройте свою сцену, визуализируйте в буфер, и у вас есть изображение.

Обновление Получается, что XNA - это смешная библиотека (предназначенная для создания игр и ничего больше, зевая). Управляемый DirectX требует лоботомии мозга. OpenGL прост в использовании, но отсутствует код загрузки изображения. Это оставляет нас с WPF:

alt text http://praeclarum.org/so/persp.png

Изображение может быть улучшено путем принуждения WPF в режиме анти-псевдонима (почему о, почему Microsoft вы так близоруким?), И не используя Aero стекла, силы что 1 пиксельная черная рамка на всех снимках экрана (или путем удаления этой 1 пиксельной границы).

(Извините за длину этого кода, но WPF является болтливый API.)

public partial class Window1 : Window { 
    const float ANGLE = 30; 
    const float WIDTH = 8; 
    public Window1() { 
     InitializeComponent(); 

     var group = new Model3DGroup(); 
     group.Children.Add(Create3DImage(@"C:\Users\fak\Pictures\so2.png")); 
     group.Children.Add(new AmbientLight(Colors.White)); 

     ModelVisual3D visual = new ModelVisual3D(); 
     visual.Content = group; 
     viewport.Children.Add(visual); 
    } 

    private GeometryModel3D Create3DImage(string imgFilename) { 
     var image = LoadImage(imgFilename); 

     var mesh = new MeshGeometry3D(); 
     var height = (WIDTH * image.PixelHeight)/image.PixelWidth; 
     var w2 = WIDTH/2.0; 
     var h2 = height/2.0; 
     mesh.Positions.Add(new Point3D(-w2, -h2, 0)); 
     mesh.Positions.Add(new Point3D(w2, -h2, 0)); 
     mesh.Positions.Add(new Point3D(w2, h2, 0)); 
     mesh.Positions.Add(new Point3D(-w2, h2, 0)); 
     mesh.TriangleIndices.Add(0); 
     mesh.TriangleIndices.Add(1); 
     mesh.TriangleIndices.Add(2); 
     mesh.TriangleIndices.Add(0); 
     mesh.TriangleIndices.Add(2); 
     mesh.TriangleIndices.Add(3); 
     mesh.TextureCoordinates.Add(new Point(0, 1)); // 0, 0 
     mesh.TextureCoordinates.Add(new Point(1, 1)); 
     mesh.TextureCoordinates.Add(new Point(1, 0)); 
     mesh.TextureCoordinates.Add(new Point(0, 0)); 

     var mat = new DiffuseMaterial(new ImageBrush(image)); 
     mat.AmbientColor = Colors.White; 

     var geometry = new GeometryModel3D(); 
     geometry.Geometry = mesh; 
     geometry.Material = mat; 
     geometry.BackMaterial = mat; 

     geometry.Transform = new RotateTransform3D(
      new AxisAngleRotation3D(new Vector3D(0,1,0), ANGLE), 
      new Point3D(0, 0, 0)); 

     return geometry; 
    } 

    public static BitmapSource LoadImage(string filename) { 
     return BitmapDecoder.Create(new Uri(filename, UriKind.RelativeOrAbsolute), 
      BitmapCreateOptions.None, BitmapCacheOption.Default).Frames[0]; 
    } 
} 

И требуется XAML:

<Window x:Class="Persp.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Perspective Window" Height="480" Width="640"> 
<Grid> 
    <Viewport3D x:Name="viewport"> 
     <Viewport3D.Resources> 
     </Viewport3D.Resources> 
     <Viewport3D.Camera> 
      <PerspectiveCamera x:Name="cam" 
        FarPlaneDistance="100" 
        LookDirection="0,0,-1" 
        UpDirection="0,1,0" 
        NearPlaneDistance="1" 
        Position="0,0,10" 
        FieldOfView="60" /> 
     </Viewport3D.Camera> 
    </Viewport3D> 
</Grid> 
</Window> 
+0

Проблема в том, как вы преобразовываете 4 точки в 3D-поворот? –

2

Ключевое слово здесь homography. Манолис Луракис написал GPL-версию гомографии в C, которая доступна here; однако это не будет легко переноситься, поскольку оно зависит от некоторых внешних библиотек, таких как LAPACK.

2

Отказ от ответственности: Я работаю в Atalasoft

Если вы готовы пойти коммерческий, DotImage фотография может сделать это с QuadrilateralWarpCommand. Образец C# Код

// Load an image. 
AtalaImage image = new AtalaImage("test-image.jpg"); 

// Prepare the warp positions. 
Point bottomLeft = new Point(100, image.Height - 80); 
Point topLeft = new Point(130, 45); 
Point topRight = new Point(image.Width - 60, 140); 
Point bottomRight = new Point(image.Width - 20, image.Height); 

// Warp the image. 
QuadrilateralWarpCommand cmd = new QuadrilateralWarpCommand(bottomLeft, 
    topLeft, topRight, bottomRight, InterpolationMode.BiLinear, Color.White); 
AtalaImage result = cmd.Apply(image).Image; 

http://www.atalasoft.com/products/dotimage

+0

Является ли это аффинной деформацией или перспективной основой? –

+0

Я не верю, что вы можете получить это с помощью Affine warp (по крайней мере, не 2d). Мы поддерживаем несколько общих аффинных преобразований, и вы можете создать свою собственную 2D-матрицу. Мы не поддерживаем 3D-преобразования (это то, что, я думаю, вам нужно будет делать с помощью такой матрицы). –

Смежные вопросы