Перспективное искажение изображения

Приложение, над которым я сейчас работаю, требует функциональности Perspective Image Distortion. В основном то, что я хочу сделать, это позволить пользователям загружать изображение в приложение и настраивать его свойства перспективы на основе 4 угловых точек, которые они могут указать.

Я посмотрел на ImageMagic. Он имеет некоторые функции искажения с регулировкой перспективы, но работает очень медленно, а некоторые определенные входы дают неверные результаты.

Кто-нибудь из вас, ребята, использовал любую другую библиотеку или алгоритм. Я кодирую на С#.

Любые указатели будут высоко оценены.

Спасибо


person over.drive    schedule 17.04.2011    source источник
comment
См. Должны ли вопросы включать «теги» в свои заголовки? , где консенсуса нет, не должны!   -  person    schedule 03.04.2015


Ответы (5)


Кажется, это именно то, что вы (и я) искали: http://www.codeproject.com/KB/graphics/YLScsFreeTransform.aspx

Он возьмет изображение и исказит его, используя предоставленные вами 4 координаты X/Y.

Быстрый, бесплатный, простой код. Проверено, работает прекрасно. Просто скачайте код по ссылке, а затем используйте FreeTransform.cs следующим образом:

using (System.Drawing.Bitmap sourceImg = new System.Drawing.Bitmap(@"c:\image.jpg")) 
{ 
    YLScsDrawing.Imaging.Filters.FreeTransform filter = new YLScsDrawing.Imaging.Filters.FreeTransform(); 
    filter.Bitmap = sourceImg;
    // assign FourCorners (the four X/Y coords) of the new perspective shape
    filter.FourCorners = new System.Drawing.PointF[] { new System.Drawing.PointF(0, 0), new System.Drawing.PointF(300, 50), new System.Drawing.PointF(300, 411), new System.Drawing.PointF(0, 461)}; 
    filter.IsBilinearInterpolation = true; // optional for higher quality
    using (System.Drawing.Bitmap perspectiveImg = filter.Bitmap) 
    {
        // perspectiveImg contains your completed image. save the image or do whatever.
    } 
} 
person Doug S    schedule 12.01.2012
comment
Это не перспектива. Проверьте это: forums.getpaint. сеть/index.php?/topic/ - person ironic; 16.11.2014
comment
@ironic: этот код достаточно близок к перспективе. Если быть более точным, кодер может иметь дело с большим количеством кода/подслушанного кода, если он того пожелает. Вопрос лишь в том, где найти баланс для нужд каждого проекта. - person Doug S; 22.10.2015
comment
определить «достаточно близко». даже несмотря на то, что могут быть случаи использования, когда этот код может использоваться взаимозаменяемо с кодом преобразования перспективы, это ни в коем случае не является преобразованием «перспективы». - person ironic; 30.10.2015
comment
@ironic: Если вы хотите получить техническую информацию, нет ничего идеального. Чем ближе вы хотите приблизиться к совершенству, тем больше вы жертвуете в других областях. В большинстве случаев это скорость/простота против точности. Таким образом, вы решаете, что является вашим приоритетом и какие компромиссы вы хотите. - person Doug S; 31.10.2015
comment
@ironic прав: это не перспектива, это трансформация трапеции, которую сделать намного проще, чем перспективу. - person Fortega; 09.12.2015
comment
Опять же... можно весь день мудрить. Если вы хотите получить техническую информацию, нет ничего идеального в перспективе. Чем ближе вы хотите приблизиться к совершенству, тем больше вы жертвуете в других областях. В большинстве случаев это скорость/простота против точности. Таким образом, вы решаете, что является вашим приоритетом и какие компромиссы вы хотите. - person Doug S; 30.03.2016
comment
@DougS, позвольте мне пояснить, что мне нужно: преобразование, которое создаст изображение, соответствующее (с точки зрения позиционирования пикселей), созданное при обычном 3D-рендеринге. по этой причине трапецеидальное преобразование совершенно бесполезно. - person ironic; 18.11.2016
comment
@ironic Это нормально. Это ваш выбор. Это может быть не выбор ОП. Опять же, просто взвесьте все параметры (производительность, точность и т. д.), чтобы найти наилучшее для вас решение. - person Doug S; 07.12.2016

Paint .NET может это сделать, а также есть пользовательские реализации эффекта. Вы можете запросить исходный код или использовать Reflector, чтобы прочитать его и понять, как его кодировать.

person Emond Erno    schedule 17.04.2011
comment
@igor brejc: отличное дополнение! Только для преобразования это может быть излишним, но отличным источником информации. - person Emond Erno; 17.04.2011

Если это перспективное преобразование, вы должны иметь возможность указать матрицу преобразования 4x4, которая соответствует четырем углам.

Вычислите эту матрицу, затем примените каждый пиксель к результирующему изображению на матрице, в результате чего получится «отображенный» пиксель. Обратите внимание, что этот «сопоставленный» пиксель, скорее всего, будет лежать между двумя или даже четырьмя пикселями. В этом случае используйте свой любимый алгоритм интерполяции (например, билинейный, бикубический), чтобы получить интерполированный цвет.

Это действительно единственный способ сделать это и не может быть сделано быстрее. Если эта функция имеет решающее значение и вам абсолютно нужно, чтобы она работала быстро, вам нужно переложить задачу на GPU. Например, вы можете вызвать библиотеку DirectX для применения преобразования перспективы к текстуре. Это может сделать его чрезвычайно быстрым, даже если нет графического процессора, поскольку библиотека DirectX использует инструкции SIMD для ускорения матричных вычислений и интерполяции цветов.

person Stephen Chung    schedule 17.04.2011

Была такая же проблема. Вот демо код с исходными кодами, перенесенными с gimp.

person ironic    schedule 19.11.2014
comment
Это действительно полезно! Большое спасибо! - person Gope; 18.11.2016

YLScsFreeTransform не работает должным образом. Лучшее решение — ImageMagic.

Вот как вы используете его в С#:

using(MagickImage image = new MagickImage("test.jpg"))
{
    image.Distort(DistortMethod.Perspective, new double[] { x0,y0, newX0,newY0, x1,y1,newX1,newY1, x2,y2,newX2,newY2, x3,y3,newX3,newY3 });
    control.Image = image.ToBitmap();
}
person GO.exe    schedule 03.04.2015
comment
Пожалуйста, объясните, почему YLScsFreeTransform не работает должным образом. - person Doug S; 22.10.2015
comment
Потому что YLScsFreeTransform имеет меньше параметров для применения метода искажения, что делает результат нерелевантным тому, что задумано. - person GO.exe; 09.01.2016
comment
Не имеет отношения к тому, что задумано? OP просто хочет загрузить изображение в приложение и настроить его свойства перспективы на основе 4 угловых точек. YLScsFreeTransform делает это. Похоже, вы говорите, что это не делает то, что вы хотите, что не имеет отношения к вопросу ОП. - person Doug S; 30.03.2016
comment
+1 Очень хорошее предложение использовать ImageMagic. Это помогло мне открыть для себя много вещей. Тем не менее для вашего примера вам нужно добавить image.VirtualPixelMethod = VirtualPixelMethod.Transparent; - person 41686d6564; 29.08.2016