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