Pull to refresh

Компьютерное зрение на Java для Android. Обзор библиотеки BoofCV

Reading time 3 min
Views 23K
Наверное, каждый Android программист хотя бы раз задумывался о написание чего-нибудь полезного с использованием компьютерного зрения или дополненной реальности. А некоторые даже написали hello, word при помощи opencv, которую таки портировали и на Android. К сожалению, если мы захотим написать что-то серьезное, мы обнаружим, что набор библиотек с уже реализованными функциями Computer Vision не так велик, особенно это касается платформы Android. Чаще всего для этой цели используют opencv, написанную на C++ либо пишут свои велосипеды, что в общем тоже хорошо, но не так быстро, как хотелось бы в плане реализации. Однако, не все так плохо. Существует такой замечательный проект BoofCV, который представляет из себя библиотеку компьютерного зрения, написанную на чистом Java. Последние две буквы в названии библиотеки означают именно то, о чем вы подумали. А в последнем релизе появилась долгожданная поддержка Android. Ниже мы рассмотрим основные плюшки, предоставляемые библиотекой на конкретном примере.

BoofCV – краткое описание



Итак, BoofCV – библиотека компьютерного зрения с открытым исходным кодом, написанная на чистом Java. Алгоритмы, используемые внутри, хорошо оптимизированы и, как показывает практика, по скорости в некоторых случаях не уступают реализации на C++ opencv. Основные возможности библиотеки:
• Работа с видео и web камерами;
• 3D Computer Vision;
• Фильтры (размытие, градиент), уборка шума (с помощью вейвлетов);
• Бинаризация, морфологические операции;
• Выделение границ (Кэнни, Собель);
• Поиск точек интереса;
• Поиск линий, сегментов, прямоугольников;
• Стерео изображения.

Кроме этого, библиотека содержит еще множество функций, используемых в компьютерном зрении. Подключается библиотека совсем просто – можно скачать исходники с официального сайта и собрать самому, а можно скачать уже собранные jar файлы и просто подключить их к проекту.

Для экспериментов возьмем такую картинку:



Для начала попробуем размытие Гаусса:



Для получения такой картинки мы используем функцию BlurImageOps.gaussian:
//Здесь и далее image – исходное изображение, имеющее тип ImageUInt8

ImageUInt8 blurred = new ImageUInt8(image.width,image.height) ImageUInt8 blurred = new ImageUInt8(image.width,image.height);

BlurImageOps.gaussian(image,blurred,-1,5,null);


Теперь добавим к исходной картинке шум и отфильтруем его:




Добавляем и убираем шум:

Random rand = new Random(234);
			ImageUInt8noisy = image.clone();
			GeneralizedImageOps.addGaussian(noisy,rand,20,0,255);
			ImageUInt8denoised = new ImageFloat32(ImageUInt8.width, ImageUInt8.height);
			int numLevels = 4;
			WaveletDenoiseFilter< ImageUInt8> denoiser = FactoryImageDenoise.waveletBayes(ImageUInt8.class,numLevels);
			denoiser.process(noisy,denoised);


Выделение границ:



Код:

I
mageUInt8 canny = new ImageUInt8(image.width,image.height);
//Canny
			DetectEdgeContour<ImageUInt8> simple = FactoryDetectEdgeContour.canny(30,200,false,ImageUInt8.class,ImageSInt16.class);
			simple.process(image);
			List<List<Point2D_I32>> edges = simple.getContours();
			for( List<Point2D_I32> l : edges ) {
				for( Point2D_I32 p : l ) {
					canny.set(p.x,p.y, 255);
				}
			}


Бинаризация изображения:



Код:

ImageUInt8 binary = new ImageUInt8(image.width,image.height);
float mean = PixelMath.sum(image)/(image.width*image.height);
ThresholdImageOps.threshold(image, binary,mean,false);



Разметка бинаризованного изображения:



Код:


ImageSInt32 blobs = new ImageSInt32(image.width, image.height);
int numBlobs = BinaryImageOps.labelBlobs4(binary,blobs);


Поиск точек интереса:



Код приводить не буду, дабы не загромождать статью, пример есть в мануале.

И тут возникает закономерный вопрос – а где здесь Android? Для того, что бы использовать библиотеку в Android существует класс ConvertBitmap, содержащий методы конвертации из формата Android в формат библиотеки BoofCV и обратно.
Например так:

Bitmap map = BitmapFactory.decodeResource(getResources(), R.drawable.car5);
ImageUInt8 image = ConvertBitmap.bitmapToGray(map, (ImageUInt8)null, null);


Заключение:



Безусловно, это лишь малая часть всех возможностей библиотеки. По функционалу BoofCV, конечно проигрывает таким монстрам как opencv. Однако, порог вхождения в компьютерное зрение для Android существенно снижается при использовании BoofCV.
При этом библиотека продемонстрировала неплохую производительность, что позволяет ее использовать в системах реального времени. Так поиск и локализация прямоугольника с нужными параметрами (например автомобильный номер) происходит примерно за 0.2 – 0.5 сек, в зависимости от величины картинки. Библиотека ко всему прочему неплохо документирована.
Tags:
Hubs:
+33
Comments 10
Comments Comments 10

Articles