Esse tutorial é composto por duas partes, ambas partem do princípio que você já tenha seguido o tutorial Iniciando com OpenCV e Android Studio :
- Como utilizar um código nativo em OpenCV no Android Studio.
- Como capturar uma imagem da câmera e salvar na memória interna.
1. Como utilizar um código nativo em OpenCV no Android Studio
Configurando o Ambiente
Requisitos:
- Se não possuir a biblioteca do OpenCV para Android, faça o download no site.
- Faça o download do NDK no link.
Primeiramente devemos adicionar as ferramentas externas:
- javah: responsável por gerar os arquivos de cabeçalho .h a partir do arquivo .java
- ndk-build: responsável por compilar o código nativo.
Para adicionarmos as ferramentas, no Android Studio, devemos ir em Preferences->External Tools e adicionar a ferramenta externa javah, com as seguintes configurações:
- Program: /usr/bin/javah ou o caminho onde o binário javah se encontra em seu computador, se seu sistema operacional for unix digite which javah
- Parameters:
-v -jni -d $ModuleFileDir$/src/main/jni $FileClass$
- Working directory: $SourcepathEntry$
Para adicionarmos a ferramenta externa ndk-build, devemos ir em Preferences->External Tools, com as seguintes configurações:
- Program: /Users/user/android-ndk-r10e/ndk-build ou o caminho onde se encontra o ndk-build
- Parameters:
NDK_PROJECT_PATH=$ModuleFileDir$/build/intermediates/ndk NDK_LIBS_OUT=$ModuleFileDir$/src/main/jniLibs NDK_APPLICATION_MK=$ModuleFileDir$/src/main/jni/Application.mk APP_BUILD_SCRIPT=$ModuleFileDir$/src/main/jni/Android.mk V=1
- Working directory: $SourcepathEntry$
Na classe MainActivity.java devemos indicar o nome das bibliotecas que serão geradas através da compilação do código nativo para que elas sejam carregadas. Para isso devemos adicionar este trecho de código na classe MainActivity.java:
public class MainActivity extends AppCompatActivity implements CvCameraViewListener2,
View.OnClickListener {
//...
static {
//O nome da biblioteca corresponde ao nome definido no arquivo Android.mk, que
será visto posteriormente
System.loadLibrary("NdkLib");
System.loadLibrary("opencv_java3");
}
//o nome da função é definido pelo programador
public native int grayOpenCV(long matRgba, long matGray);
//...
}
Ao clicar com o botão direito na classe MainActivity.java, deverão aparecer as ferramentas que adicionamos anteriormente. Clique em javah para que seja criado o diretório jni e gerado o arquivo de cabeçalho, nesse exemplo, com_example_giovaniromani_tutorialopencv_MainActivity.h em /src/main /jni:
Uma vez criado o diretório /src/main/jni, devemos adicionar três arquivos, dois responsáveis pela compilação e um contendo o código nativo que queremos utilizar, são eles: Android.mk, Application.mk e nativeCodeSobel.cpp
Criando e Editando os Arquivos de Configuração para a Compilação do Código Nativo
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#diretorio onde se encontra o sdk do OpenCV em seu computador
OPENCVROOT:= /Users/user/OpenCV-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk
#arquivo contendo o código nativo
LOCAL_SRC_FILES := nativeCodeSobel.cpp
LOCAL_LDLIBS += -llog
LOCAL_MODULE := NdkLib
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_ABI := armeabi-v7a x86 APP_PLATFORM := android-16
nativeCodeGray.cpp
Neste arquivo se encontram as instruções que desejamos utilizar em código nativo.
#include "nativeCodeGray.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <nativeCodeGray.h>
//Atencao ao nome da biblioteca, ele deverá ser igual ao arquivo contido no diretório
///src/main/libs
#include <com_example_giovaniromani_tutorialopencv_MainActivity.h>
using namespace cv;
/** @function main */
//Atenção ao nome do método, ele deverá ser igual ao nome contido no
//com_example_giovaniromani_tutorialopencv_MainActivity.h
JNIEXPORT jint
JNICALL Java_com_example_giovaniromani_tutorialopencv_MainActivity_grayOpenCV
(JNIEnv *, jobject, jlong matRgba, jlong matGray) {
Mat &rgba = *(Mat *) matRgba;
Mat &gray = *(Mat *) matGray;
cvtColor(rgba, gray, CV_BGR2GRAY);
}
Logo, teremos 5 arquivos no diretório src/main/jni.
No arquivo build.gradle do app devemos adicionar o seguinte trecho de código:
//...
android{
//...
sourceSets.main {
jni.srcDirs = [] //desabilita chamada automática ao ndk-build
}
//Será necessário verificar e atualizar o caminho para o ndk-build
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
commandLine "/Users/giovaniromani/MEGA/CodigoFonte/android-ndk-r10e/ndk-build",
'NDK_PROJECT_PATH=build/intermediates/ndk',
'NDK_LIBS_OUT=src/main/jniLibs',
'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
'NDK_APPLICATION_MK=src/main/jni/Application.mk'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
//....
Utilizando o Código Nativo
Por fim, para que seja exibida a imagem, devemos chamar o método passando como parâmetro duas matrizes:
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
Mat gray = new Mat();
grayOpenCV(rgba.getNativeObjAddr(), gray.getNativeObjAddr());
//retorna o objeto Mat que está em escala de cinza ao View para que seja exibida na tela
return gray;
}
2. Como capturar uma imagem da câmera e salvar na memória interna
Implementando o tratamento do evento OnClick
Devemos, inicialmente, implementar a interface View.OnClickListener, ela será responsável por obter e tratar o evento, que no nosso caso, será um toque na tela:
public class MainActivity extends AppCompatActivity implements CvCameraViewListener2, View.OnClickListener {
Você notará que a assinatura estará sublinhada de vermelho, isso acontece porque devemos, obrigatoriamente, sobrescrever o método OnClick.
@Override
public void onClick(View v) {
}
Para que a View possa capturar o evento, temos que ativar o seu listener, assim, devemos colocar a seguinte linha de código no método OnCreate da classe MainActivity:
mOpenCvCameraView.setOnClickListener(this);
Salvando a Imagem
Será necessário criar um atributo do tipo Mat que armazenará a imagem em escala de cinza, conforme nosso objetivo. Dessa forma teremos a declaração do atributo no início da classe e atribuiremos o objeto gray do tipo Mat ao atributo matGray dentro do método OnCameraFrame, conforme código abaixo:
public class MainActivity extends AppCompatActivity implements CvCameraViewListener2, View.OnClickListener {
//...
private Mat matGray;
//...
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
Mat gray = new Mat();
grayOpenCV(rgba.getNativeObjAddr(), gray.getNativeObjAddr());
matGray=gray;
return gray;
}
//...
}
Para que a imagem seja salva ao clicarmos na tela, devemos inserir as seguintes linhas de código no método OnClick:
@Override
public void onClick(View v) {
//Armazena uma cópia da matriz matGray na matriz src
Mat src = matGray.clone();
//Realiza a cnoversão de Mat para Bitmap
Bitmap bitmap = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(src, bitmap);
ContentValues contentValues = new ContentValues();
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues);
OutputStream outputStream;
try {
//Salva a imagem
outputStream = getContentResolver().openOutputStream(uri);
boolean compressed = bitmap.compress(Bitmap.CompressFormat.PNG, 0,
outputStream);
outputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Atenção
O Aplicativo deve ter permissão para pode acessar a memória externa do aparelho, para isso, devemos inserir as seguintes linhas no arquivo AndroidManifest.xml
[sourcecode language=”xml”]
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
[/sourcecode]
Para mais detalhes, o código está disponível no GitHub.
Referência:
[1] http://hujiaweibujidao.github.io/blog/2014/10/22/android-ndk-and-opencv-development-with-android-studio/







Boa noite,
copiei e colei o código logo abaixo da mensagem:
” No arquivo build.gradle do app devemos adicionar o seguinte trecho de código:”
Verifiquei o caminho para ndk-build e mesmo assim ocorre um erro no programa. Poderia me ajudar?
Grato.
Boa noite André,
há um problema de formatação no código.
A linha
compileTask – & g t; compileTask.dependsOn ndkBuild
deverá ser substituída por
compileTask -> compileTask.dependsOn ndkBuild
Caso tenha dúvidas sobre o código, ele está disponível no GitHub.
Se o problema persistir, nos comunique novamente indicando o erro.
Boa tarde,
o erro ainda continua, aparece a seguinte mensagem.
Error:Execution failed for task ‘:app:ndkBuild’.
> A problem occurred starting process ‘command ‘/C:/Users/andre/Downloads/android-ndk-r10e/ndk-build”
Boa tarde.
Tem algum desenvolvedor para um aplicativo android que interligue a captura de imagens do celular( OPENCV/TESSERAT… ) com um banco de dados e o sinesp cidadão. Seria usado embarcado em um veiculo visando o combate de ilícitos penais.
Aguardo maiores informações.
Obrigado.
rb.moc.liamgnull@livadlaicilop
Olá pessoal. Alguém consegue montar programar um aplicativo para android utilizando a tecnologia para obter placas de veículos e pesquisar no Senasp cidadão?
Caso afirmativo entre em contato no email moc.liamgnull@alivadlaicilop
Ei lá só queria dar-lhe um rápida heads-սp e qսe você saiba aⅼguns do imagens não estão carregando corretamente.
Nã᧐ sei porquê, mas еu acho qᥙe é սma գuestão dе
vinculaçãߋ. Já tentei em dois diferentes navegadores internet е ambos mostram a mesma resultado.