Developer от Бога

DV

пятница, 7 июля 2017 г.

Android. RenderScript

Выше перечисленные методы и классы не подходят по обработке более сложных алгоритмов в разумных временных рамках чем простое преобразование цвета . Некоторое решение можно получить разбив изображение на части и обрабатывать их в разных потоках. Как видно в таблице, даже в случае разбивки изображения размеров 1920х1080 на 5 частей и обработки его в разных потоках на смартфоне Samsung Galaxy S5 , можно добиться скорости преобразования до 15 секунд с применением медианного фильтра. Много это времени или достаточно - зависит от ситуации и предназначения приложения. Но однозначно можно сказать, что для обработки видео в реальном времени или использования несколько разных алгоритмов одновременно - скорости явно не достаточно. Конечно решений есть несколько, это использование OpenGL или Android NDK который позволяет писать код на языках С. У них есть свои недостатки, такие как сложность, которая отвлекает от алгоритмов на разного рода стандартные интерфейсы, или зависимость от платформы. Идеальным решением есть использование, в некотором смысле, гибридной технологии RenderScript. Особенностью которого его есть возможность писать алгоритмы на языке С и обрабатывать код на более низком уровне, с последующей компиляцией уже на телефоне перед установкой приложения, для достижения максимальной совместимости. Разработчики постарались максимально найти компромисс между переносимостью, простотою использования и скоростью работы программ. Саму работу в RenderScript можно вести двумя способами - используя Java классы с готовыми решениями для таких операций как размытие, применение матрицы свертки, и некоторых других. Или более гибкий второй способ - написание алгоритмов на языке С99 с некоторыми ограничениями. Обработка изображений RenderScript длится если не мгновенно то иногда в десятки раз быстрее тех же алгоритмов работающих на Java. Пример кода на Java для использования RenderScript (Матрица свертки) :


  1. float[] matrix =
  2. {
  3. -1; -1; -1;
  4. -1; 9; -1;
  5. -1; -1; 1;}
  6. Bitmap src;
  7. resultt = Bitmap.createBitmap(src.getWidth(),src.getHeight(), Bitmap.Config.ARGB_8888);
  8. RenderScript renderScript = RenderScript.create(context);
  9. Allocation input = Allocation.createFromBitmap(renderScript, src);
  10. Allocation output = Allocation.createFromBitmap(renderScript, resultt);
  11. ScriptIntrinsicConvolve3x3 convolution = ScriptIntrinsicConvolve3x3
  12. .create(renderScript, Element.U8_4(renderScript));
  13. convolution.setInput(input);
  14. convolution.setCoefficients(matrix);
  15. convolution.forEach(output);
  16. output.copyTo(resultt); ut); 



Матрица свертки отдельная тема, если коротко - это произведение чисел матрицы на соответствующие пиксели участка изображения. Такой, на первый взгляд простой алгоритм выдает самые разные результаты после обработки в зависимости от цифр в матрице (в массиве). Сама работа программы идет примерно так : на вход (Bitmap) подается изображение, и создается с такими же параметрами Bitmap для результата. RenderScript - главный класс который принимает контекст. Allocation input - выделенная память для данных ( например изображения ), в качестве аргументов конструктора принимает объект RenderScript и само изображение в виде Bitmap. ScriptIntrinsicConvolve3x3 - создание матрицы 3х3, в которую далее отправляются ссылка на память с данными (Allocation input) , и матрица в виде массива, после чего вызывается главный метод forEach() который запускает обработку кода на низком уровне. В качестве параметра метод forEach() принимает участок памяти (Allocation output) для помещения туда результата обработки. В конечном итоге метод output.copyTo() преобразовывает данные к нужному виду и в указанный Bitmap. После чего возможен уже вывод или сохранение обработанного изображения. В следующих примерах будет показан способ работы с кодом непосредственно на языке С. 

Комментариев нет:

Отправить комментарий