#include "preprocess.h" #include cv::Mat bitmap_to_cv_mat(JNIEnv *env, jobject bitmap) { AndroidBitmapInfo info; int result = AndroidBitmap_getInfo(env, bitmap, &info); if (result != ANDROID_BITMAP_RESULT_SUCCESS) { LOGE("AndroidBitmap_getInfo failed, result: %d", result); return cv::Mat{}; } if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { LOGE("Bitmap format is not RGBA_8888 !"); return cv::Mat{}; } unsigned char *srcData = NULL; AndroidBitmap_lockPixels(env, bitmap, (void **) &srcData); cv::Mat mat = cv::Mat::zeros(info.height, info.width, CV_8UC4); memcpy(mat.data, srcData, info.height * info.width * 4); AndroidBitmap_unlockPixels(env, bitmap); cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGR); /** if (!cv::imwrite("/sdcard/1/copy.jpg", mat)){ LOGE("Write image failed " ); } */ return mat; } cv::Mat resize_img(const cv::Mat& img, int height, int width){ if (img.rows == height && img.cols == width){ return img; } cv::Mat new_img; cv::resize(img, new_img, cv::Size(height, width)); return new_img; } // fill tensor with mean and scale and trans layout: nhwc -> nchw, neon speed up void neon_mean_scale(const float* din, float* dout, int size, const std::vector& mean, const std::vector& scale) { if (mean.size() != 3 || scale.size() != 3) { LOGE("[ERROR] mean or scale size must equal to 3"); return; } float32x4_t vmean0 = vdupq_n_f32(mean[0]); float32x4_t vmean1 = vdupq_n_f32(mean[1]); float32x4_t vmean2 = vdupq_n_f32(mean[2]); float32x4_t vscale0 = vdupq_n_f32(scale[0]); float32x4_t vscale1 = vdupq_n_f32(scale[1]); float32x4_t vscale2 = vdupq_n_f32(scale[2]); float* dout_c0 = dout; float* dout_c1 = dout + size; float* dout_c2 = dout + size * 2; int i = 0; for (; i < size - 3; i += 4) { float32x4x3_t vin3 = vld3q_f32(din); float32x4_t vsub0 = vsubq_f32(vin3.val[0], vmean0); float32x4_t vsub1 = vsubq_f32(vin3.val[1], vmean1); float32x4_t vsub2 = vsubq_f32(vin3.val[2], vmean2); float32x4_t vs0 = vmulq_f32(vsub0, vscale0); float32x4_t vs1 = vmulq_f32(vsub1, vscale1); float32x4_t vs2 = vmulq_f32(vsub2, vscale2); vst1q_f32(dout_c0, vs0); vst1q_f32(dout_c1, vs1); vst1q_f32(dout_c2, vs2); din += 12; dout_c0 += 4; dout_c1 += 4; dout_c2 += 4; } for (; i < size; i++) { *(dout_c0++) = (*(din++) - mean[0]) * scale[0]; *(dout_c1++) = (*(din++) - mean[1]) * scale[1]; *(dout_c2++) = (*(din++) - mean[2]) * scale[2]; } }