diff --git a/android/Android.mk.in b/android/Android.mk.in index 2e895613cedb1c33b1bbbd5af0695718556be2fb..65d0826a77a335dd71e87736806a08238eb46a5a 100644 --- a/android/Android.mk.in +++ b/android/Android.mk.in @@ -3,7 +3,11 @@ LOCAL_PATH := ${CMAKE_CURRENT_SOURCE_DIR} include $(CLEAR_VARS) LOCAL_MODULE := ${android_module_name} - + +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +LOCAL_ARM_NEON := true +endif + LOCAL_SRC_FILES := ${android_srcs} LOCAL_CFLAGS := ${android_defs} diff --git a/android/android-jni/jni/Android.mk b/android/android-jni/jni/Android.mk index 98b101c8e9d95359a4722a3e4b0325a5ceaef387..8f387193754804d1dcb43e6bc9d0d3921223a1b7 100644 --- a/android/android-jni/jni/Android.mk +++ b/android/android-jni/jni/Android.mk @@ -16,7 +16,16 @@ LOCAL_C_INCLUDES += $(OPENCV_INCLUDES) LOCAL_MODULE := android-opencv LOCAL_SRC_FILES := gen/android_cv_wrap.cpp image_pool.cpp \ - yuv420sp2rgb.c gl_code.cpp Calibration.cpp + gl_code.cpp Calibration.cpp + + +#ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +# LOCAL_CFLAGS := -DHAVE_NEON=1 +# LOCAL_SRC_FILES += yuv2rgb_neon.c.neon +#else + LOCAL_SRC_FILES += yuv420sp2rgb.c +#endif + include $(BUILD_SHARED_LIBRARY) diff --git a/android/android-jni/jni/image_pool.cpp b/android/android-jni/jni/image_pool.cpp index 6b0ccf4da6d89f9319194085c7ec5faf9f62bb65..fcbd80e4591f7505ab4f27203eac31aa2c0aec9a 100644 --- a/android/android-jni/jni/image_pool.cpp +++ b/android/android-jni/jni/image_pool.cpp @@ -18,17 +18,17 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) return JNI_VERSION_1_4; } -JNIEXPORT void JNICALL Java_com_opencv_jni_opencvJNI_addYUVtoPool(JNIEnv * env, - jclass thiz, jlong ppool, jobject _jpool, jbyteArray jbuffer, - jint jidx, jint jwidth, jint jheight, jboolean jgrey) +JNIEXPORT void JNICALL Java_com_opencv_jni_opencvJNI_addYUVtoPool(JNIEnv * env, jclass thiz, jlong ppool, + jobject _jpool, jbyteArray jbuffer, jint jidx, + jint jwidth, jint jheight, jboolean jgrey) { - int buff_height = jheight + (jheight/2); - Size buff_size(jwidth,buff_height); - image_pool *pool = (image_pool *) ppool; + int buff_height = jheight + (jheight / 2); + Size buff_size(jwidth, buff_height); + image_pool *pool = (image_pool *)ppool; Mat mat = pool->getYUV(jidx); - if (mat.empty() || mat.size() != buff_size ) + if (mat.empty() || mat.size() != buff_size) { mat.create(buff_size, CV_8UC1); } @@ -36,7 +36,7 @@ JNIEXPORT void JNICALL Java_com_opencv_jni_opencvJNI_addYUVtoPool(JNIEnv * env, jsize sz = env->GetArrayLength(jbuffer); uchar* buff = mat.ptr (0); - env->GetByteArrayRegion(jbuffer, 0, sz, (jbyte*) buff); + env->GetByteArrayRegion(jbuffer, 0, sz, (jbyte*)buff); pool->addYUVMat(jidx, mat); @@ -51,8 +51,7 @@ JNIEXPORT void JNICALL Java_com_opencv_jni_opencvJNI_addYUVtoPool(JNIEnv * env, } //doesn't work unfortunately.. //TODO cvtColor(mat,color, CV_YCrCb2RGB); - color_convert_common(buff, buff + jwidth * jheight, jwidth, jheight, - color.ptr (0), false); + color_convert_common(buff, buff + jwidth * jheight, jwidth, jheight, color.ptr (0), false); } if (jgrey) @@ -84,7 +83,7 @@ Mat image_pool::getGrey(int i) Mat tm = yuvImagesMap[i]; if (tm.empty()) return tm; - return tm(Range(0, tm.rows * (2.0f/3)), Range::all()); + return tm(Range(0, tm.rows * (2.0f / 3)), Range::all()); } Mat image_pool::getYUV(int i) { @@ -99,3 +98,19 @@ void image_pool::addImage(int i, Mat mat) imagesmap[i] = mat; } +void image_pool::convertYUVtoColor(int i, cv::Mat& out) +{ + + Mat yuv = getYUV(i); + + if (yuv.empty()) + return; + int width = yuv.cols; + int height = yuv.rows * (2.0f / 3); + out.create(height, width, CV_8UC3); + const unsigned char* buff = yuv.ptr (0); + unsigned char* out_buff = out.ptr (0); + //doesn't work unfortunately.. + //TODO cvtColor(mat,color, CV_YCrCb2RGB); + color_convert_common(buff, buff + width * height, width, height, out_buff, false); +} diff --git a/android/android-jni/jni/image_pool.h b/android/android-jni/jni/image_pool.h index 6882cb63ce6d5cc5055d7290f4efcbc93e2ecafb..8ce13cbde9393be364b7269e786172267e207769 100644 --- a/android/android-jni/jni/image_pool.h +++ b/android/android-jni/jni/image_pool.h @@ -53,6 +53,8 @@ public: */ void addYUVMat(int i, cv::Mat mat); + void convertYUVtoColor(int i, cv::Mat& out); + // int addYUV(uchar* buffer, int size, int width, int height, bool grey,int idx); // // void getBitmap(int * outintarray, int size, int idx); diff --git a/android/android-jni/jni/yuv420sp2rgb.c b/android/android-jni/jni/yuv420sp2rgb.c index eec0e53767edf4747c558c94a249f257e0cbd863..0511df36735c4663963125e19911a712f7090b1b 100644 --- a/android/android-jni/jni/yuv420sp2rgb.c +++ b/android/android-jni/jni/yuv420sp2rgb.c @@ -25,7 +25,7 @@ #endif const int bytes_per_pixel = 2; -void color_convert_common(unsigned char *pY, unsigned char *pUV, int width, int height, unsigned char *buffer, int grey) +void color_convert_common(const unsigned char *pY, const unsigned char *pUV, int width, int height, unsigned char *buffer, int grey) { int i, j; diff --git a/android/android-jni/jni/yuv420sp2rgb.h b/android/android-jni/jni/yuv420sp2rgb.h index 48ca0c7ed74e07b544ca345bd2585b865d7ba41b..dfe9b5f3a4afd1648859ab9d5a025fe951a0fdb3 100644 --- a/android/android-jni/jni/yuv420sp2rgb.h +++ b/android/android-jni/jni/yuv420sp2rgb.h @@ -7,7 +7,7 @@ extern "C" { #endif void color_convert_common( - unsigned char *pY, unsigned char *pUV, + const unsigned char *pY, const unsigned char *pUV, int width, int height, unsigned char *buffer, int grey); diff --git a/android/android-jni/src/com/opencv/camera/CameraConfig.java b/android/android-jni/src/com/opencv/camera/CameraConfig.java index 6befd4e5f34793889bd11f4a3b5cc0c2895c2638..246415967b60d5e8c6983268b1d5e684640fb74d 100644 --- a/android/android-jni/src/com/opencv/camera/CameraConfig.java +++ b/android/android-jni/src/com/opencv/camera/CameraConfig.java @@ -24,7 +24,7 @@ public class CameraConfig extends Activity { // Restore preferences SharedPreferences settings = ctx.getSharedPreferences(CAMERA_SETTINGS, 0); - int mode = settings.getInt(CAMERA_MODE, CAMERA_MODE_COLOR); + int mode = settings.getInt(CAMERA_MODE, CAMERA_MODE_BW); return mode; } diff --git a/modules/features2d/src/brief.cpp b/modules/features2d/src/brief.cpp index d22302bb6bc2a01df9c435629d7b34cdd61ad5db..e0fbc2006d76646584a07538a693e7c8e5019693 100644 --- a/modules/features2d/src/brief.cpp +++ b/modules/features2d/src/brief.cpp @@ -44,6 +44,11 @@ #include #include +#if ANDROID && HAVE_NEON +#include +#include +#endif + using namespace cv; inline int smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x) @@ -106,16 +111,39 @@ HammingLUT::ResultType HammingLUT::operator()( const unsigned char* a, const uns Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned char* b, int size) const { #if __GNUC__ - ResultType result = 0; - for (int i = 0; i < size; i += sizeof(unsigned long)) + ResultType result = 0; +#if ANDROID && HAVE_NEON + static uint64_t features = android_getCpuFeatures(); + if ((features & ANDROID_CPU_ARM_FEATURE_NEON)) + { + for (int i = 0; i < size; i += 16) { - unsigned long a2 = *reinterpret_cast (a + i); - unsigned long b2 = *reinterpret_cast (b + i); - result += __builtin_popcountl(a2 ^ b2); + uint8x16_t A_vec = vld1q_u8 (a + i); + uint8x16_t B_vec = vld1q_u8 (b + i); + //uint8x16_t veorq_u8 (uint8x16_t, uint8x16_t) + uint8x16_t AxorB = veorq_u8 (A_vec, B_vec); + + uint8x16_t bitsSet += vcntq_u8 (AxorB); + //uint16x8_t vpadalq_u8 (uint16x8_t, uint8x16_t) + uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); + uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); + + uint64x2_t bitSet2 = vpaddlq_u32 (bitSet4); + result += vgetq_lane_u64 (bitSet2,0); + result += vgetq_lane_u64 (bitSet2,1); } - return result; + } + else +#endif + for (int i = 0; i < size; i += sizeof(unsigned long)) + { + unsigned long a2 = *reinterpret_cast (a + i); + unsigned long b2 = *reinterpret_cast (b + i); + result += __builtin_popcountl(a2 ^ b2); + } + return result; #else - return HammingLUT()(a,b,size); + return HammingLUT()(a,b,size); #endif }