Issue
I am currently working through "OpenCV Android Programming By Example" by Amgad Muhammad.
In chapter 6 the user is supposed to develop a panoramic viewer. I stuck in this chapter for about two weeks now and still facing errors when trying to sync the project. I've tried several other code adjustements, experimental-gradle-versions etc. but none of it worked.
This is my current build.gradle(project):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.4.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
and this my build.gradle(module):
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.example.moritz.ndktest"
minSdkVersion.apiLevel = 11
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "Pano"
ldLibs += ['log']
cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
cppFlags.add("-fexceptions")
cppFlags.add("-I${file("D:/Android/OpenCV-android-sdk/sdk/native/jni/include")}".toString())
//cppFlags += "-I${file("D:/Android/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()
ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])
stl = "gnustl_shared"
}
/*android.sources {
main {
jni {
source {
srcDir 'src/main/jni'
}
}
}
}*/
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.txt"))
}
}
android.productFlavors {
create("arm") {
ndk.with{
abiFilters.add("armeabi")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi\\"
ldLibs.add(libsDir + "libopencv_core.a")
ldLibs.add(libsDir + "libopencv_highgui.a")
ldLibs.add(libsDir + "libopencv_imgproc.a")
ldLibs.add(libsDir + "libopencv_java3.so")
ldLibs.add(libsDir + "libopencv_ml.a")
}
}
create("armv7") {
ndk.with {
abiFilters.add("armeabi-v7a")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi-v7a\\"
ldLibs.add(libsDir + "libopencv_core.a")
ldLibs.add(libsDir + "libopencv_highgui.a")
ldLibs.add(libsDir + "libopencv_imgproc.a")
ldLibs.add(libsDir + "libopencv_java3.so")
ldLibs.add(libsDir + "libopencv_ml.a")
ldLibs.add(libsDir + "libopencv_ts.a")
}
}
}
android.sources{
main{
jni{
source{
srcDirs += ['src/main/jni']
}
}
}
}
} dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
//compile 'com.android.support:design:23.2.1'
compile project(':openCVLibrary310')
}
and this my build.gradle(opencv310):
apply plugin: 'com.android.model.library'
model{
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig {
minSdkVersion.apiLevel = 11
targetSdkVersion.apiLevel = 23
}
}
android.buildTypes {
release {
minifyEnabled false
proguardFiles.add(file("proguard-rules.txt"))
}
}
}
in gradle.porperties I have:
android.useDeprecatedNdk=true
and my gradle-wrapper.properties looks like:
#Mon Apr 04 13:55:17 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
The error I get right now:
Error:Unable to load class 'com.android.build.gradle.managed.NdkConfig_Impl'. Possible causes for this unexpected error include:
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.
- Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.) Re-download dependencies and sync project (requires network)
- The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem. Stop Gradle build processes (requires restart)
- Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
Thanks in advance!!!
EDIT: I changed my classpath in build.gradle (project) to:
classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha5'
and therefore my gradle-wrapper.properties to:
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
(in Settings/Build, Excecution, Deployment/Gradle I've selected "Use default gradle wrapper" btw.)
and my buildToolsVersion to 23.0.1 and it seems that I made a step forward but now I am facing a bunch of new errors:
D:\Android\AndroidStudioProjects\NDKtest\app\src\main\jni\Pano.cpp Error:(16, 44) error: no matching function for call to 'cv::FastFeatureDetector::FastFeatureDetector(int)' Information:(16, 44) candidates are: In file included from D:\Android\AndroidStudioProjects\NDKtest\app\src\main\jni\Pano.cpp:4:0: D:\Android\OpenCV-android-sdk\sdk\native\jni\include/opencv2/features2d.hpp:411:20: note: cv::FastFeatureDetector::FastFeatureDetector() Error:(57, 9) error: 'OrbFeatureDetector' is not a member of 'cv' Error:(58, 9) error: 'detector' was not declared in this scope Error:(80, 48) error: no matching function for call to 'cv::FastFeatureDetector::FastFeatureDetector(int)' Information:(80, 48) candidates are: In file included from D:\Android\AndroidStudioProjects\NDKtest\app\src\main\jni\Pano.cpp:4:0: D:\Android\OpenCV-android-sdk\sdk\native\jni\include/opencv2/features2d.hpp:411:20: note: cv::FastFeatureDetector::FastFeatureDetector() Error:(86, 13) error: 'OrbFeatureDetector' is not a member of 'cv' Error:(87, 13) error: 'detector' was not declared in this scope Error:(93, 13) error: 'OrbDescriptorExtractor' is not a member of 'cv' Error:(94, 13) error: 'descriptor' was not declared in this scope Error:(99, 13) error: 'BriefDescriptorExtractor' is not a member of 'cv' Error:(100, 13) error: 'descriptor' was not declared in this scope Error:(111, 13) error: 'FREAK' is not a member of 'cv' Error:(112, 13) error: 'descriptor' was not declared in this scope descriptor.compute(grayObject,objectKeyPoints,objectDescriptor); ^ Error:Execution failed for task ':app:compilePanoArmeabiDebugArmSharedLibraryPanoMainCpp'. A build operation failed. C++ compiler failed while compiling Pano.cpp. See the complete log at: file:///D:/Android/AndroidStudioProjects/NDKtest/app/build/tmp/compilePanoArmeabiDebugArmSharedLibraryPanoMainCpp/output.txt
My Pano.cpp:
#include <jni.h>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <vector>
extern "C" {
JNIEXPORT void JNICALL Java_com_app3_pano_PanoActivity_FindFastFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba)
{
cv::Mat& mGr = *(cv::Mat*)addrGray;
cv::Mat& mRgb = *(cv::Mat*)addrRgba;
std::vector<cv::KeyPoint> v;
cv::FastFeatureDetector detector(50);
detector.detect(mGr, v);
for( unsigned int i = 0; i < v.size(); i++ )
{
const cv::KeyPoint& kp = v[i];
cv::circle(mRgb, cv::Point(kp.pt.x, kp.pt.y), 10, cv::Scalar(255,0,0,255));
}
}
JNIEXPORT void JNICALL Java_com_app3_pano_PanoActivity_FindHarrisCorners(JNIEnv*, jobject, jlong addrGray, jlong addrRgba)
{
cv::Mat& mGr = *(cv::Mat*)addrGray;
cv::Mat& mRgb = *(cv::Mat*)addrRgba;
cv::Mat dst_norm;
cv::Mat dst = cv::Mat::zeros(mGr.size(),CV_32FC1);
int blockSize = 2;
int apertureSize = 3;
double k = 0.04;
float threshold=150;
cv::cornerHarris( mGr, dst, blockSize, apertureSize, k, cv::BORDER_DEFAULT );
cv::normalize( dst, dst_norm, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat() );
for( unsigned int i = 0; i < dst_norm.rows; i++ )
{
float * row=dst_norm.ptr<float>(i);
for(int j=0;j<dst_norm.cols;j++)
{
if(row[j]>=threshold)
{
cv::circle(mRgb, cv::Point(j, i), 10, cv::Scalar(255,0,0,255));
}
}
}
}
JNIEXPORT void JNICALL Java_com_app3_pano_PanoActivity_FindORBFeatures(JNIEnv*, jobject, jlong addrRgba, jint featuresNumber)
{
cv::Mat& mRgb = *(cv::Mat*)addrRgba;
cv::Mat grayImg;
std::vector<cv::KeyPoint> v;
cv::cvtColor(mRgb,grayImg,cv::COLOR_RGBA2GRAY);
cv::OrbFeatureDetector detector(featuresNumber);
detector.detect(grayImg, v);
cv::drawKeypoints(grayImg,v,mRgb,cv::Scalar::all(-1),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
}
JNIEXPORT void JNICALL Java_com_app3_pano_PanoActivity_FindMatches(JNIEnv*, jobject, jlong objectAddress, jlong sceneAddress,jint detectorID, jint descriptorID,jlong matchingResult)
{
cv::Mat& object = *(cv::Mat*)objectAddress;
cv::Mat& scene = *(cv::Mat*)sceneAddress;
cv::Mat& result = *(cv::Mat*)matchingResult;
cv::Mat grayObject;
cv::Mat grayScene;
cv::cvtColor(object,grayObject,cv::COLOR_RGBA2GRAY);
cv::cvtColor(scene,grayScene,cv::COLOR_RGBA2GRAY);
std::vector<cv::KeyPoint> objectKeyPoints;
std::vector<cv::KeyPoint> sceneKeyPoints;
cv::Mat objectDescriptor;
cv::Mat scenceDescriptor;
if(detectorID==1)//FAST
{
cv::FastFeatureDetector detector(50);
detector.detect(grayObject, objectKeyPoints);
detector.detect(grayScene, sceneKeyPoints);
}
else if(detectorID==5)//ORB
{
cv::OrbFeatureDetector detector;
detector.detect(grayObject, objectKeyPoints);
detector.detect(grayScene, sceneKeyPoints);
}
if(descriptorID==3)//ORB
{
cv::OrbDescriptorExtractor descriptor;
descriptor.compute(grayObject,objectKeyPoints,objectDescriptor);
descriptor.compute(grayScene,sceneKeyPoints,scenceDescriptor);
}
else if(descriptorID==4)//BRIEF
{
cv::BriefDescriptorExtractor descriptor;
descriptor.compute(grayObject,objectKeyPoints,objectDescriptor);
descriptor.compute(grayScene,sceneKeyPoints,scenceDescriptor);
}
else if(descriptorID==5)//BRISK
{
cv::BRISK descriptor;
descriptor.compute(grayObject,objectKeyPoints,objectDescriptor);
descriptor.compute(grayScene,sceneKeyPoints,scenceDescriptor);
}
else if(descriptorID==6)//FREAK
{
cv::FREAK descriptor;
descriptor.compute(grayObject,objectKeyPoints,objectDescriptor);
descriptor.compute(grayScene,sceneKeyPoints,scenceDescriptor);
}
cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector< cv::DMatch > matches;
matcher.match( objectDescriptor, scenceDescriptor, matches);
double min_dist = 100;
for( int i = 0; i < objectDescriptor.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
}
std::vector< cv::DMatch > good_matches;
for( int i = 0; i < objectDescriptor.rows; i++ )
{
if( matches[i].distance <= 3*min_dist )
{
good_matches.push_back( matches[i]);
}
}
drawMatches( grayObject, objectKeyPoints, grayScene, sceneKeyPoints,good_matches, result, cv::Scalar::all(-1), cv::Scalar::all(-1),
std::vector<char>(),
cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS+cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
}
}
So it seems like my linking to my opencv-include-folder in my build.gradle(module) via cppFlags.add() does not work properly. But I really don't know what's wrong with it?
Developing Environment:
- Windows 10 (x64)
- Android Studio 1.5.1
- jdk1.8.0_73
- ndk-r11b
- OpenCV-3-1-0
Solution
Oh, I'm working through this book too. The code in this book work in older version of Opencv (2.4). You need to read the reference of Opencv 3.1.0 because some class(such as FastFeatureDetector
, OrbFeatureDetecture
,..) have changed. My FindFastFeature
and ORB function :
p/s: Don't just copy the code, you should modify it and go through the functions one by one.
JNIEXPORT void JNICALL
Java_com_hieuvecto_softscanner2_MainActivity_FindFastFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba){
cv::Mat& mGr = *(cv::Mat*)addrGray;
cv::Mat& mRgb = *(cv::Mat*)addrRgba;
std::vector<cv::KeyPoint> v;
cv::Ptr<cv::FeatureDetector> detector = cv::FastFeatureDetector::create(50);
detector->detect(mGr, v);
for (unsigned int i=0; i<v.size(); i++) {
const cv::KeyPoint& kp = v[i];
cv::circle(mRgb, cv::Point(kp.pt.x, kp.pt.y), 10, cv::Scalar(255,0,0,255));
}
}
JNIEXPORT void JNICALL
Java_com_hieuvecto_softscanner2_MainActivity_OrbFeaturesDetector(JNIEnv*, jobject, jlong addrRgba, jint featuresNumber) {
cv::Mat& mRgb = *(cv::Mat*)addrRgba;
cv::Mat grayImg;
std::vector<cv::KeyPoint> v;
cv::cvtColor(mRgb, grayImg, cv::COLOR_RGBA2GRAY);
cv::Ptr<cv::FeatureDetector> detector = cv::ORB::create(featuresNumber);
detector->detect(grayImg, v);
cv::drawKeypoints(grayImg,v,mRgb,cv::Scalar::all(-1),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
}
And My build.gradle of app module:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.3"
defaultConfig.with {
applicationId = "com.hieuvecto.softscanner2"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
//Make sure to build with JDK version 7
android.buildTypes {
release {
// minifyEnabled = false
// proguardFiles = getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
android.ndk {
moduleName = "Pano"
cppFlags.add("-I${file("D:/download/OpenCV-android-sdk/sdk/native/jni/include")}".toString())
cppFlags.add("-std=c++11")
cppFlags.add("-frtti")
cppFlags.add("-fexceptions")
ldLibs.addAll(["log", "opencv_java3"])
stl = "gnustl_static"
}
android.productFlavors {
create("arm") {
ndk.abiFilters.add("armeabi")
ndk.ldFlags.add("-L${file('src/main/jniLibs/armeabi')}".toString())
}
create("arm7") {
ndk.abiFilters.add("armeabi-v7a")
ndk.ldFlags.add("-L${file('src/main/jniLibs/armeabi-v7a')}".toString())
}
create("arm8") {
ndk.abiFilters.add("arm64-v8a")
ndk.ldFlags.add("-L${file('src/main/jniLibs/arm64-v8a')}".toString())
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':openCVLibrary310')
compile 'com.android.support:appcompat-v7:23.2.1'
}
Answered By - Hiệu Chính Hiệu
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.