blob: 31b94932586830abfd27f9106cb4f08425f7f59a [file] [log] [blame]
Richard Burtoned35a6f2022-02-14 11:55:35 +00001/*
2 * Copyright (c) 2022 Arm Limited. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include "ImageUtils.hpp"
18
19#include <limits>
20
21namespace arm {
22namespace app {
23namespace image {
24
25 float Calculate1DOverlap(float x1Center, float width1, float x2Center, float width2)
26 {
27 float left_1 = x1Center - width1/2;
28 float left_2 = x2Center - width2/2;
29 float leftest = left_1 > left_2 ? left_1 : left_2;
30
31 float right_1 = x1Center + width1/2;
32 float right_2 = x2Center + width2/2;
33 float rightest = right_1 < right_2 ? right_1 : right_2;
34
35 return rightest - leftest;
36 }
37
38 float CalculateBoxIntersect(Box& box1, Box& box2)
39 {
40 float width = Calculate1DOverlap(box1.x, box1.w, box2.x, box2.w);
41 if (width < 0) {
42 return 0;
43 }
44 float height = Calculate1DOverlap(box1.y, box1.h, box2.y, box2.h);
45 if (height < 0) {
46 return 0;
47 }
48
49 float total_area = width*height;
50 return total_area;
51 }
52
53 float CalculateBoxUnion(Box& box1, Box& box2)
54 {
55 float boxes_intersection = CalculateBoxIntersect(box1, box2);
56 float boxes_union = box1.w * box1.h + box2.w * box2.h - boxes_intersection;
57 return boxes_union;
58 }
59
60 float CalculateBoxIOU(Box& box1, Box& box2)
61 {
62 float boxes_intersection = CalculateBoxIntersect(box1, box2);
63 if (boxes_intersection == 0) {
64 return 0;
65 }
66
67 float boxes_union = CalculateBoxUnion(box1, box2);
68 if (boxes_union == 0) {
69 return 0;
70 }
71
72 return boxes_intersection / boxes_union;
73 }
74
75 void CalculateNMS(std::forward_list<Detection>& detections, int classes, float iouThreshold)
76 {
77 int idxClass{0};
78 auto CompareProbs = [idxClass](Detection& prob1, Detection& prob2) {
79 return prob1.prob[idxClass] > prob2.prob[idxClass];
80 };
81
82 for (idxClass = 0; idxClass < classes; ++idxClass) {
83 detections.sort(CompareProbs);
84
85 for (auto it=detections.begin(); it != detections.end(); ++it) {
86 if (it->prob[idxClass] == 0) continue;
87 for (auto itc=std::next(it, 1); itc != detections.end(); ++itc) {
88 if (itc->prob[idxClass] == 0) {
89 continue;
90 }
91 if (CalculateBoxIOU(it->bbox, itc->bbox) > iouThreshold) {
92 itc->prob[idxClass] = 0;
93 }
94 }
95 }
96 }
97 }
98
99 void ConvertImgToInt8(void* data, const size_t kMaxImageSize)
100 {
101 auto* tmp_req_data = static_cast<uint8_t*>(data);
102 auto* tmp_signed_req_data = static_cast<int8_t*>(data);
103
104 for (size_t i = 0; i < kMaxImageSize; i++) {
105 tmp_signed_req_data[i] = (int8_t) (
106 (int32_t) (tmp_req_data[i]) - 128);
107 }
108 }
109
110 void RgbToGrayscale(const uint8_t* srcPtr, uint8_t* dstPtr, const size_t dstImgSz)
111 {
112 const float R = 0.299;
113 const float G = 0.587;
114 const float B = 0.114;
115 for (size_t i = 0; i < dstImgSz; ++i, srcPtr += 3) {
116 uint32_t int_gray = R * (*srcPtr) +
117 G * (*(srcPtr + 1)) +
118 B * (*(srcPtr + 2));
119 *dstPtr++ = int_gray <= std::numeric_limits<uint8_t>::max() ?
120 int_gray : std::numeric_limits<uint8_t>::max();
121 }
122 }
123
124} /* namespace image */
125} /* namespace app */
126} /* namespace arm */