Сферический фильтр в андроиде

Мне нужно применить сферический фильтр к изображению в Android, я прикрепил входное и ожидаемое выходное изображение. Выходное изображение будет обработано из квадратной центрированной области входного изображения и сопоставлено с сферой. Любая идея, как это сделать в Android. Придется ли мне использовать openGL для этого или только 2D-трансформация решит эту задачу.

Входное изображение
Выходное изображение


person Manish Agrawal    schedule 07.06.2012    source источник


Ответы (4)


следующий код объектив Fish Eye для создания Сфера и применить некоторые модификации для масштабирования сферы и генерации фона, это будет работать в основном для квадратных изображений.

person strike    schedule 16.06.2012

Я только что получил реализацию этой работы с использованием OpenGL ES 2.0 на iOS:

Пример сферического преломления

Пока это на iOS, фрагментный шейдер, который я использовал, можно перенести прямо на Android. Часть сферического преломления выполняется с использованием следующего фрагментного шейдера:

 varying highp vec2 textureCoordinate;

 uniform sampler2D inputImageTexture;

 uniform highp vec2 center;
 uniform highp float radius;
 uniform highp float aspectRatio;
 uniform highp float refractiveIndex;

 void main()
 {
     highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
     highp float distanceFromCenter = distance(center, textureCoordinateToUse);
     lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);

     distanceFromCenter = distanceFromCenter / radius;

     highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);
     highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));

     highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);

     gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;     
 }

center — это нормализованная координата центра сферы (от 0,0 до 1,0 в обоих измерениях), radius — это нормализованный радиус, refractiveIndex — индекс воздуха/материала вашей сферы, а aspectRatio — это аспект соотношение изображения (чтобы убедиться, что сфера круглая, а не эллиптическая в нормализованном координатном пространстве).

Это вычисляет нормали поверхности для сферы с предоставленным центром и радиусом и использует функцию GLSL refract() для преломления входящего вектора и предоставления координат поиска в текстуре изображения.

Фон размыт с помощью разделяемого размытия по Гауссу, которое я описываю в этом ответе.

Этот фильтр достаточно быстр, чтобы фильтровать живое видео в режиме реального времени на iPhone, поэтому он должен работать достаточно эффективно на большинстве устройств Android. Исходный код для него можно найти в GPUImageSphereRefractionFilter в моем фреймворке GPUImage с открытым исходным кодом.

person Brad Larson    schedule 09.07.2012
comment
Я использовал это в openGL, и это сработало отлично. Однако у меня проблемы с пониманием математики. При вычислении y textureCoordinateToUse я понимаю, почему умножается аспектRatio, но зачем нужны остальные вычисления? - person tanvi; 22.11.2017

Это проблема трассировки лучей. OpenGL, скорее всего, даже не поможет вам здесь, поскольку OpenGL не обеспечивает 3D на основе лучей. Тем не менее, это может быть то, что вы ищете.

http://www1.cs.columbia.edu/CAVE/publications/pdfs/Garg_TR04.pdf

person trumpetlicks    schedule 08.06.2012
comment
Я не думаю, что это обязательно сложная проблема с трассировкой лучей, если фон — это просто текстура. Вы можете просто сопоставить текстуру со сферой с помощью какой-либо сферической системы координат или кубической карты. Если бы он отражал динамическую 3D-сцену, я бы с вами согласился, но просто отразить текстуру не так уж сложно. - person Tim; 08.06.2012
comment
Пример без трассировки лучей - это то, о чем я предоставил документ (я почти уверен) !!! Другой способ сделать это (даже если фон является текстурой) — использовать трассировку лучей. - person trumpetlicks; 08.06.2012
comment
OpenGL не обеспечивает 3D на основе лучей — это определенно возможно при использовании шейдеров. Я сделал искажение, близкое к этому, с помощью шейдера OpenGL ES 2.0: stackoverflow.com/a/9896856/19679 и GLSL даже определяет функцию refract() для преломления света через объекты. Позвольте мне посмотреть, смогу ли я создать шейдер для воспроизведения этого конкретного эффекта. - person Brad Larson; 09.06.2012
comment
Очень хорошая информация :-) Я не думаю, что это делает настоящую трассировку лучей. Довольно хорошо известно, что видеокарты еще не могут выполнять трассировку лучей, это то, к чему они хотели бы пойти, и они действительно близки к живой трассировке лучей, но еще не достигли этого. Эти фильтры искажения являются математическими приближениями к эффекту. Отличная ссылка, выглядит забавно, и, возможно, что-то близкое именно то, что нужно этому пользователю :-) - person trumpetlicks; 09.06.2012
comment
Я должен исправить себя. Современные видеокарты выполняют трассировку лучей, но не в обычном смысле OpenGL. На данный момент они делают это с точки зрения OpenCL или CUDA. - person trumpetlicks; 09.06.2012
comment
Хорошо, я наконец-то собрал для этого фрагментный шейдер OpenGL ES 2.0. Результаты можно увидеть в моем ответе, и они очень близки к изображению выше. Там может быть немного прозрачности, которой у меня нет, но ее можно добавить с помощью простой настройки. Функция refract() GLSL выполняет здесь большую часть тяжелой работы. - person Brad Larson; 09.07.2012
comment
@BradLarson - Это ДЕЙСТВИТЕЛЬНО КРУТО. Эти шейдерные движки очень мощные. Спасибо, что оставили мне быстрый комментарий. +1 - person trumpetlicks; 09.07.2012

Я согласен с Тимом. Преобразование одного растрового изображения в другое не требует ни 3D-точек, ни трассировки лучей, вообще забудьте об этом, это просто 2D. Я не знаю, есть ли в opengl что-то встроенное, но у меня достаточно опыта работы с 3D, чтобы указать вам правильное направление. Вы должны перебрать все точки внутри * выбранной области круга * это подсказка и найти цвет с помощью преобразования РЫБИЙ ГЛАЗ. Вас много в сети. надеюсь это поможет

person Community    schedule 08.06.2012
comment
Показанный пример человека показывает зеркальное отражение, преломление и истинный круг, связанный с водой / стеклом и т. Д. Даже если вы посмотрите на ссылку, предоставленную Брэдом Ларсоном (кстати, отличная ссылка +1), края на круглом связаны плавным переходом обратно к самому изображению. Это эффект, а не ОБЯЗАТЕЛЬНО то, о чем просит этот пользователь. Если приведенное выше изображение действительно то, что они ищут, то оно может быть немного сложнее, чем более простые функции типа шейдера. Однако не получил много слов от спрашивающего об их интерпретации??? - person trumpetlicks; 09.06.2012