1#include "preprocess.h"
2#include <android/bitmap.h>
3
4cv::Mat bitmap_to_cv_mat(JNIEnv *env, jobject bitmap) {
5 AndroidBitmapInfo info;
6 int result = AndroidBitmap_getInfo(env, bitmap, &info);
7 if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
8 LOGE("AndroidBitmap_getInfo failed, result: %d", result);
9 return cv::Mat{};
10 }
11 if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
12 LOGE("Bitmap format is not RGBA_8888 !");
13 return cv::Mat{};
14 }
15 unsigned char *srcData = NULL;
16 AndroidBitmap_lockPixels(env, bitmap, (void **)&srcData);
17 cv::Mat mat = cv::Mat::zeros(info.height, info.width, CV_8UC4);
18 memcpy(mat.data, srcData, info.height * info.width * 4);
19 AndroidBitmap_unlockPixels(env, bitmap);
20 cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGR);
21 /**
22 if (!cv::imwrite("/sdcard/1/copy.jpg", mat)){
23 LOGE("Write image failed " );
24 }
25 */
26
27 return mat;
28}
29
30cv::Mat resize_img(const cv::Mat &img, int height, int width) {
31 if (img.rows == height && img.cols == width) {
32 return img;
33 }
34 cv::Mat new_img;
35 cv::resize(img, new_img, cv::Size(height, width));
36 return new_img;
37}
38
39// fill tensor with mean and scale and trans layout: nhwc -> nchw, neon speed up
40void neon_mean_scale(const float *din, float *dout, int size,
41 const std::vector<float> &mean,
42 const std::vector<float> &scale) {
43 if (mean.size() != 3 || scale.size() != 3) {
44 LOGE("[ERROR] mean or scale size must equal to 3");
45 return;
46 }
47
48 float32x4_t vmean0 = vdupq_n_f32(mean[0]);
49 float32x4_t vmean1 = vdupq_n_f32(mean[1]);
50 float32x4_t vmean2 = vdupq_n_f32(mean[2]);
51 float32x4_t vscale0 = vdupq_n_f32(scale[0]);
52 float32x4_t vscale1 = vdupq_n_f32(scale[1]);
53 float32x4_t vscale2 = vdupq_n_f32(scale[2]);
54
55 float *dout_c0 = dout;
56 float *dout_c1 = dout + size;
57 float *dout_c2 = dout + size * 2;
58
59 int i = 0;
60 for (; i < size - 3; i += 4) {
61 float32x4x3_t vin3 = vld3q_f32(din);
62 float32x4_t vsub0 = vsubq_f32(vin3.val[0], vmean0);
63 float32x4_t vsub1 = vsubq_f32(vin3.val[1], vmean1);
64 float32x4_t vsub2 = vsubq_f32(vin3.val[2], vmean2);
65 float32x4_t vs0 = vmulq_f32(vsub0, vscale0);
66 float32x4_t vs1 = vmulq_f32(vsub1, vscale1);
67 float32x4_t vs2 = vmulq_f32(vsub2, vscale2);
68 vst1q_f32(dout_c0, vs0);
69 vst1q_f32(dout_c1, vs1);
70 vst1q_f32(dout_c2, vs2);
71
72 din += 12;
73 dout_c0 += 4;
74 dout_c1 += 4;
75 dout_c2 += 4;
76 }
77 for (; i < size; i++) {
78 *(dout_c0++) = (*(din++) - mean[0]) * scale[0];
79 *(dout_c1++) = (*(din++) - mean[1]) * scale[1];
80 *(dout_c2++) = (*(din++) - mean[2]) * scale[2];
81 }
82}