| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "kapanova_s_image_smoothing/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <cmath> | ||
| 5 | #include <cstddef> | ||
| 6 | #include <cstdint> | ||
| 7 | #include <cstdio> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "kapanova_s_image_smoothing/common/include/common.hpp" | ||
| 11 | |||
| 12 | namespace kapanova_s_image_smoothing { | ||
| 13 | |||
| 14 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | KapanovaSImageSmoothingSEQ::KapanovaSImageSmoothingSEQ(const InType &in) { |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | if (!in.empty()) { |
| 17 |
1/2✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
|
24 | GetInput() = in; |
| 18 | } else { | ||
| 19 | ✗ | GetInput() = InType(); | |
| 20 | } | ||
| 21 | 24 | width_ = 0; | |
| 22 | 24 | height_ = 0; | |
| 23 | 24 | } | |
| 24 | |||
| 25 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | bool KapanovaSImageSmoothingSEQ::ValidationImpl() { |
| 26 | const auto &input_data = GetInput(); | ||
| 27 |
2/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
24 | return !input_data.empty() && !input_data[0].empty(); |
| 28 | } | ||
| 29 | |||
| 30 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | bool KapanovaSImageSmoothingSEQ::PreProcessingImpl() { |
| 31 | const auto &input_data = GetInput(); | ||
| 32 |
2/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
24 | if (input_data.empty() || input_data[0].size() < 4) { |
| 33 | return false; | ||
| 34 | } | ||
| 35 | |||
| 36 | const auto &data = input_data[0]; | ||
| 37 | 24 | width_ = static_cast<int>((data[1] << 8) | data[0]); | |
| 38 | 24 | height_ = static_cast<int>((data[3] << 8) | data[2]); | |
| 39 | |||
| 40 | 24 | const auto width_u = static_cast<size_t>(width_); | |
| 41 | 24 | const auto height_u = static_cast<size_t>(height_); | |
| 42 | 24 | const auto expected_size = 4U + (width_u * height_u * 3U); | |
| 43 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if (data.size() < expected_size) { |
| 44 | return false; | ||
| 45 | } | ||
| 46 | |||
| 47 | 24 | input_.assign(data.begin() + 4, data.end()); | |
| 48 | 24 | result_.resize(width_u * height_u * 3U); | |
| 49 | |||
| 50 | 24 | CreateKernel(); | |
| 51 | 24 | return true; | |
| 52 | } | ||
| 53 | |||
| 54 | 24 | void KapanovaSImageSmoothingSEQ::CreateKernel() { | |
| 55 | 24 | const int size = (2 * radius_) + 1; | |
| 56 | 24 | const auto size_u = static_cast<size_t>(size); | |
| 57 | 24 | kernel_.resize(size_u * size_u); | |
| 58 | constexpr float kSigma = 1.5F; | ||
| 59 | constexpr float kSigmaSquared = kSigma * kSigma; // σ² | ||
| 60 | float norm = 0.0F; | ||
| 61 | |||
| 62 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 24 times.
|
96 | for (int i = -radius_; i <= radius_; ++i) { |
| 63 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 72 times.
|
288 | for (int j = -radius_; j <= radius_; ++j) { |
| 64 | 216 | const int temp_index = ((i + radius_) * size) + (j + radius_); | |
| 65 | 216 | const auto kernel_index = static_cast<size_t>(temp_index); | |
| 66 | |||
| 67 | // ПРАВИЛЬНАЯ формула Гаусса: exp(-(i² + j²) / (2σ²)) | ||
| 68 | 216 | kernel_[kernel_index] = std::exp(-static_cast<float>((i * i) + (j * j)) / (2.0F * kSigmaSquared)); | |
| 69 | |||
| 70 | 216 | norm += kernel_[kernel_index]; | |
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 24 times.
|
240 | for (auto &value : kernel_) { |
| 75 | 216 | value /= norm; | |
| 76 | } | ||
| 77 | 24 | } | |
| 78 | |||
| 79 | 232 | void KapanovaSImageSmoothingSEQ::SmoothPixel(int x_coord, int y_coord) { | |
| 80 | 232 | const int stride = width_ * 3; | |
| 81 | constexpr int kSize = (2 * 1) + 1; // radius_ = 1 | ||
| 82 | float out_r = 0.0F; | ||
| 83 | float out_g = 0.0F; | ||
| 84 | float out_b = 0.0F; | ||
| 85 | |||
| 86 | auto clamp = [](int n, int lo, int hi) { return std::min(std::max(n, lo), hi); }; | ||
| 87 | |||
| 88 |
2/2✓ Branch 0 taken 696 times.
✓ Branch 1 taken 232 times.
|
928 | for (int ry = -radius_; ry <= radius_; ++ry) { |
| 89 |
2/2✓ Branch 0 taken 2088 times.
✓ Branch 1 taken 696 times.
|
2784 | for (int rx = -radius_; rx <= radius_; ++rx) { |
| 90 | 2088 | const int idx = clamp(x_coord + rx, 0, width_ - 1); | |
| 91 | 2088 | const int idy = clamp(y_coord + ry, 0, height_ - 1); | |
| 92 | 2088 | const int temp_pos = (idy * stride) + (idx * 3); | |
| 93 | 2088 | const auto pos = static_cast<size_t>(temp_pos); | |
| 94 | 2088 | const int temp_kernel_pos = ((ry + radius_) * kSize) + (rx + radius_); | |
| 95 | 2088 | const auto kernel_pos = static_cast<size_t>(temp_kernel_pos); | |
| 96 | |||
| 97 | 2088 | out_r += static_cast<float>(input_[pos]) * kernel_[kernel_pos]; | |
| 98 | 2088 | out_g += static_cast<float>(input_[pos + 1U]) * kernel_[kernel_pos]; | |
| 99 | 2088 | out_b += static_cast<float>(input_[pos + 2U]) * kernel_[kernel_pos]; | |
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | 232 | const int temp_pos = (y_coord * stride) + (x_coord * 3); | |
| 104 | 232 | const auto pos = static_cast<size_t>(temp_pos); | |
| 105 | |||
| 106 | 232 | result_[pos] = static_cast<uint8_t>(std::clamp(static_cast<int>(std::round(out_r)), 0, 255)); | |
| 107 | 232 | result_[pos + 1U] = static_cast<uint8_t>(std::clamp(static_cast<int>(std::round(out_g)), 0, 255)); | |
| 108 | 232 | result_[pos + 2U] = static_cast<uint8_t>(std::clamp(static_cast<int>(std::round(out_b)), 0, 255)); | |
| 109 | 232 | } | |
| 110 | |||
| 111 | 24 | bool KapanovaSImageSmoothingSEQ::RunImpl() { | |
| 112 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 24 times.
|
96 | for (int y_coord = 0; y_coord < height_; ++y_coord) { |
| 113 |
2/2✓ Branch 0 taken 232 times.
✓ Branch 1 taken 72 times.
|
304 | for (int x_coord = 0; x_coord < width_; ++x_coord) { |
| 114 | 232 | SmoothPixel(x_coord, y_coord); | |
| 115 | } | ||
| 116 | } | ||
| 117 | 24 | return true; | |
| 118 | } | ||
| 119 | |||
| 120 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | bool KapanovaSImageSmoothingSEQ::PostProcessingImpl() { |
| 121 | kernel_.clear(); | ||
| 122 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | kernel_.shrink_to_fit(); |
| 123 | |||
| 124 | 24 | GetOutput() = result_; | |
| 125 | 24 | return true; | |
| 126 | } | ||
| 127 | |||
| 128 | } // namespace kapanova_s_image_smoothing | ||
| 129 |