change OpenCV Mat to NCHW format fp32 data
| 36 | |
| 37 | // change OpenCV Mat to NCHW format fp32 data |
| 38 | int32_t ImagePreprocess(const Mat& src_img, float* in_data) { |
| 39 | const int32_t height = src_img.rows; |
| 40 | const int32_t width = src_img.cols; |
| 41 | const int32_t channels = src_img.channels(); |
| 42 | |
| 43 | // convert data from bgr/gray to rgb |
| 44 | Mat rgb_img; |
| 45 | if (channels == 3) { |
| 46 | cvtColor(src_img, rgb_img, COLOR_BGR2RGB); |
| 47 | } else if (channels == 1) { |
| 48 | cvtColor(src_img, rgb_img, COLOR_GRAY2RGB); |
| 49 | } else { |
| 50 | fprintf(stderr, "unsupported channel num: %d\n", channels); |
| 51 | return -1; |
| 52 | } |
| 53 | |
| 54 | // split 3 channel to change HWC to CHW |
| 55 | vector<Mat> rgb_channels(3); |
| 56 | split(rgb_img, rgb_channels); |
| 57 | |
| 58 | // by this constructor, when cv::Mat r_channel_fp32 changed, in_data will also change |
| 59 | Mat r_channel_fp32(height, width, CV_32FC1, in_data + 0 * height * width); |
| 60 | Mat g_channel_fp32(height, width, CV_32FC1, in_data + 1 * height * width); |
| 61 | Mat b_channel_fp32(height, width, CV_32FC1, in_data + 2 * height * width); |
| 62 | vector<Mat> rgb_channels_fp32{r_channel_fp32, g_channel_fp32, b_channel_fp32}; |
| 63 | |
| 64 | // convert uint8 to fp32, y = (x - mean) / std |
| 65 | const float mean[3] = {0, 0, 0}; // change mean & std according to your dataset & training param |
| 66 | const float std[3] = {255.0f, 255.0f, 255.0f}; |
| 67 | for (uint32_t i = 0; i < rgb_channels.size(); ++i) { |
| 68 | rgb_channels[i].convertTo(rgb_channels_fp32[i], CV_32FC1, 1.0f / std[i], -mean[i] / std[i]); |
| 69 | } |
| 70 | |
| 71 | return 0; |
| 72 | } |
| 73 | |
| 74 | // get classification result from network output |
| 75 | int32_t GetClassificationResult(const float* scores, const int32_t size) { |
no outgoing calls
no test coverage detected