Jak za pomocą OpenCV przetwarzać grafiki w React Native
Jeśli kiedykolwiek zastanawiałeś się czy i jak można przetwarzać obrazy za pomocą OpenCV w React Native, trafiłeś we właściwe miejsce. To prawda, procesowanie obrazów na urządzeniach mobilnych (najczęściej zdjęć zrobionych telefonem) za pomocą OpenCV w React Native, jest możliwe. Mało tego, ma nawet wiele zalet.
Piotr (Meph1k) Suwała. Programista w Brainhub, specjalizujący się w aplikacjach React i React Native. Pasjonat JavaScripta, uczenia maszynowego, lingwistyki. W wolnym czasie lubi się zajmować niestandardowymi problemami programistycznymi.
Do niewątpliwych plusów tego rozwiązania można zaliczyć:
- Łatwość implementacji
- Łatwość użycia
- Dostęp do dobrej jakości dokumentacji i tutoriali dotyczących korzystania z OpenCV
- Mały rozmiar aplikacji mobilnej – nie większy niż kilkanaście gigabajtów
W tym tutorialu pokażę Ci jak za pomocą OpenCV i React Native możesz łatwo stworzyć aplikację do przetwarzania obrazów na swoim telefonie. Ale najpierw kilka słów wprowadzenia.
Spis treści
Czym jest OpenCV?
OpenCV (Open Source Computer Vision Library) to open-source’owa biblioteka używana w uczeniu maszynowym i computer vision. OpenCV zostało stworzone, aby zapewnić wspólną infrastrukturę dla aplikacji korzystających z wizji komputerowej oraz przyspieszyć użycie percepcji maszynowej w produktach komercyjnych.
Biblioteka składa się z ponad 2500 zoptymalizowanych algorytmów, w tym rozbudowanego zestawu narzędzi zarówno klasycznych, jak i nowoczesnych, używanych w tak młodych dziedzinach, jak wizja komputerowa czy uczenie maszynowe.
Wspomniane algorytmy mogą być używane do detekcji i rozpoznawania twarzy, identyfikowania obiektów, klasyfikowania zachowań ludzkich w plikach wideo, śledzenia ruchu kamery, ruchu obiektów, tworzenia modeli 3d obiektów, tworzenia trójwymiarowych grup punktów za pomocą kamer stereo, znajdowania podobnych obrazów w bazie, rozpoznawania scenerii i przypisywania markerów rozszerzonej rzeczywistości, i tak dalej.
OpenCV jest wspierane przez społeczność liczącą ponad 47 tys. członków, a liczba jej pobrań w momencie pisania tego artykułu przekroczyła 14 milionów.
OpenCV zostało napisane w C++.
W 2010 roku zostało przeniesione do środowiska Android, które pozwala na użycie pełni jego możliwości w tworzeniu aplikacji mobilnych.
W 2012 roku zespół tworzący OpenCV rozpoczął prace nad rozszerzeniem wsparcia biblioteki do systemu iOS. Pełna integracja możliwa jest od wersji 2.4.2 (2012).
React Native natomiast, został wydany w 2015 roku przez zespół programistów Facebooka. Biblioteka ta umożliwia budowę aplikacji mobilnych za pomocą samego języka JavaScript. Ponieważ korzysta z tego samego designu co klasyczny React, tworzenie bogatych interfejsów mobilnych odbywa się z pomocą komponentów deklaratywnych.
React Native i OpenCV są dobrymi przyjaciółmi!
Wyszukując w google frazę “react native opencv” możemy natknąć się na takie linki jak:
- GitHub – ma-pe/react-native-opencv: OpenCV Bindings for React …
Jak wskazują pierwsze słowa dokumentu, biblioteka nie jest ukończona i do tej pory nie powstały żadne powiązania dla OpenCV i React Native. - Can i use openCV in react native ?? · Issue #88 · wix/react-native …
Pytanie o użycie OpenCV w połączeniu z React Native, na które niestety nie udzielono odpowiedzi. - opencv/opencv – GitHub.
Problem z łączeniem bibliotek bez żadnych wskazówek, jak autor w ogóle zaczął implementację OpenCV. - (Newbie) React Native with OpenCV : reactnative – Reddit
Jak wynika z komentarzy opublikowanych w tym wątku użycie OpenCV w React Native jest możliwe, niestety nie podano żadnych wyjaśnień jak tego dokonać.
Czego dotyczy ten tutorial?
W tym tutorialu pokażę Ci jak stworzyć aplikację mobilną, która do zrobienia zdjęć używa aparatu urządzenia a następnie, za pomocą natywnego kodu, przetwarza uzyskany obraz i zwraca informację czy wykonane zdjęcie wyszło ostre czy zamazane.
Napisanie takiej aplikacji w czystym JavaScripcie byłoby wysoce nieefektywne. JavaScript nie sprawdza się przy tak ciężkich obliczeniach.
Zanim przejdziemy do meritum, nadmienię jeszcze, że w żadnym wypadku nie jestem specjalistą Java ani Objective-C, stąd jakość kodu, który napisałem w tych technologiach może pozostawiać wiele do życzenia.
OpenCV podstawowe przygotowania
1. react-native init reactNativeOpenCvTutorial
2. W katalogu swojego projektu (możesz go znaleźć tutaj) uruchom skrypt “downloadAndInsertOpenCV.sh”, który pobiera i rozmieszcza pliki OpenCV zarówno dla Androida, jak i iOS. Ścieżki w pliku mogą nie odpowiadać Twoim preferencjom dlatego możesz musieć je zmodyfikować.
Tutorial dla Androida
1. Otwórz swój projekt w Android Studio.
2. Żeby zsynchronizować swój projekt kieruj się wskazówkami Android Studio.
3. Pobierz najnowszą wersję OpenCV dla Androida. W moim przypadku jest to 3.4.1.
4. Zaimportuj OpenCV do Android Studio
Otwórz File -> New -> Import Module, wybierz folder sdk/java w nierozapakowanym archiwum OpenCV.
5. Zaktualizuj build.gradle znajdujący się w zaimportowanym module OpenCV, tak aby 4 poniższe pola odpowiadały build.gradle twojego projektu:
- compileSdkVersion
- buildToolsVersion
- minSdkVersion
- targetSdkVersion
6. Dodaj moduł dependency:
Otwórz Application -> Module Settings, wybierz zakładkę Dependencies. Naciśnij “+” widoczny na dole ekranu, wybierz Module Dependency i wybierz zaimportowany moduł OpenCV.
W przypadku Android Studio v1.2.2, żeby uzyskać dostęp do Module Settings w widoku projektu, użyj prawego przycisku myszy i otwórz dependent module -> Open Module Settings.
Otwórz Module Settings.
Naciśnij “+”, wybierz “Module dependency” i wybierz z listy bibliotekę OpenCV.
7. W android/app/src/java stwórz paczkę o przykładowej nazwie “com.reactlibrary”.
8. Zaktualizuj odpowiednie uprawnienia w swoim Manifest.
<uses-permission android_name="android.permission.CAMERA" /> <uses-permission android_name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android_name="android.permission.WRITE_EXTERNAL_STORAGE" />
9. Stwórz plik RNOpenCvLibraryModule.java wewnątrz swojej świeżo stworzonej paczki i wypełnij go według tego wzoru.
10. Stwórz plik RNOpenCvLibraryPackage.java wewnątrz swojej świeżo stworzonej paczki i wypełnij go według tego wzoru.
11. Dodaj odpowiednie importy do swojego pliku MainApplication.java, dodaj paczkę OpenCV do listy oraz odpowiedni kod do klasy MainApplication, jak pokazano poniżej:
Imports: import com.reactlibrary.RNOpenCvLibraryPackage; import org.opencv.android.BaseLoaderCallback; import org.opencv.android.LoaderCallbackInterface; import org.opencv.android.OpenCVLoader; import android.util.Log;
Dodaj “new RNOpenCvLibraryPackage()” do swojej listy paczek.
Dodaj BaseLoaderCallback do swojej klasy MainApplication:
Oraz, dodaj poniższe callbacki do swojej klasy MainApplication:
Tutorial dla iOS
1. Otwórz projekt iOS w XCode.
2. Dodaj opencv2.framework do Linked Frameworks and Libraries.
3. Stwórz nową grupę w katalogu iOS. Ja nazwałem swoją “OpenCV”.
4. Dodaj plik .pch i umieść go w katalogu OpenCV.
5. Do swojego pliku .pch dodaj zawartość zgodną z wzorem zaprezentowanym tutaj.
6. Stwórz plik o nazwie RNOpenCvLibrary.h i wypełnij go jak wskazano tutaj.
7. Stwórz plik o nazwie RNOpenCvLibrary.mm i wypełnij go jak pokazano tutaj.
8. Ustaw Precompile Prefix Header na Yes, a ścieżkę Prefix Header jak pokazano poniżej.
9. Do swojego pliku Info.plist dodaj następującą treść:
<key>NSCameraUsageDescription</key> <string>Your message to user when the camera is accessed for the first time</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>Your message to user when the photo library is accessed for the first time</string>
Część końcowa – JavaScript
1. Wewnątrz swojego folderu src stwórz folder o nazwie “NativeModules” oraz plik nazwany OpenCV.js i wypełnij go następująco:
import { NativeModules } from 'react-native'; export default NativeModules.RNOpenCvLibrary;
2. Dla przyspieszenia konfiguracji używam biblioteki od zewnętrznych dostawców. Otwórz terminal i wpisz:
$ npm i –save react-native-svg $ npm i –save react-native-camera $ npm i –save react-native-easy-toast
3. Nie zapomnij połączyć swoich bibliotek: react-native link.
Jako odniesienia będziemy używaćtego pliku.
W linii 126 skonfiguruj swój aparat a w linii 135 stwórz element dotykowy, który posłuży do robienia zdjęć. Robienie zdjęć odbywać się będzie dzięki metody takePicture. W momencie gdy zdjęcie zostanie zrobione zostanie ono zapisane w lokalnym stanie i przetworzone w celu sprawdzenia czy jest ostre.
4. Uwaga: Jeśli napotkasz trudności z połączeniem się z aparatem w przypadku aplikacji na Androida, porównaj swój plik z moim build.gradle, zwłaszcza z linią “maven { url “https://jitpack.io” }” i zresynchronizuj swój projekt w Android Studio.
Jeśli pojawią się błędy związane z usługami Google Play, zapoznaj się z tym wątkiem na GitHubie.
Jeśli natomiast będziesz miał problemy związane z react-native-camera, zmień wersję paczki na “master” przez zmianę wersji w package.json jak pokazano poniżej:
"react-native-camera": "git+https://git@github.com/react-native-community/react-native-camera"
Przykładowy rezultat
Jeśli aplikacja uzna zrobione przez nas zdjęcie za ostre wyświetli nam jego podgląd, a wraz z nim przyciski, za pomocą których będziemy mogli je zatwierdzić lub powtórzyć.
Jeśli natomiast zdjęcie okaże się rozmazane, otrzymamy powiadomienie informujące nas o tym i będziemy zmuszeni je powtórzyć.
Zobacz ostateczny produkt otrzymany po ukończeniu tego tutorialu na moim GitHubie.
Linki:
- Setting up OpenCV for Android in Android Studio(StackOverflow)
- Setting up OpenCV for iOS in XCode (artykuł na blogu)
- Native modules for React Native (GitHub)
- Native Java code for checking if provided image is blurry (oficjalna strona OpenCV)
- Native Objective-C code for checking if provided image is blurry (StackOverflow)
- OpenCV’s official website(oficjalna strona OpenCV)
Artykuł jest tłumaczeniem posta “How to Use OpenCV in React Native for Image Processing” opublikowanego na blogu Brainhub.eu.