GCC Code Coverage Report


Directory: ./
File: tasks/korolev_k_sobel_oprator/seq/src/ops_seq.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 46 49 93.9%
Functions: 7 7 100.0%
Branches: 29 46 63.0%

Line Branch Exec Source
1 #include "korolev_k_sobel_oprator/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <array>
5 #include <cmath>
6 #include <cstddef>
7 #include <cstdint>
8 #include <vector>
9
10 #include "korolev_k_sobel_oprator/common/include/common.hpp"
11
12 namespace korolev_k_sobel_oprator {
13
14 namespace {
15
16 // Матрицы Собеля для свертки
17 constexpr std::array<std::array<int, 3>, 3> kSobelX = {{{{-1, 0, 1}}, {{-2, 0, 2}}, {{-1, 0, 1}}}};
18 constexpr std::array<std::array<int, 3>, 3> kSobelY = {{{{-1, -2, -1}}, {{0, 0, 0}}, {{1, 2, 1}}}};
19
20 // Конвертация цветного изображения в grayscale
21 48 std::vector<uint8_t> ConvertToGrayscale(const std::vector<uint8_t> &pixels, int width, int height, int channels) {
22
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 if (channels == 1) {
23 24 return pixels;
24 }
25
26 24 const auto size = static_cast<std::size_t>(width) * static_cast<std::size_t>(height);
27 24 std::vector<uint8_t> grayscale(size);
28
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 24 times.
304 for (int row_idx = 0; row_idx < height; ++row_idx) {
29
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 280 times.
4480 for (int col_idx = 0; col_idx < width; ++col_idx) {
30 4200 const int idx = ((row_idx * width) + col_idx) * channels;
31 // Формула для конвертации RGB в grayscale: 0.299*R + 0.587*G + 0.114*B
32
1/2
✓ Branch 0 taken 4200 times.
✗ Branch 1 not taken.
4200 const uint8_t r = pixels[idx];
33
2/4
✓ Branch 0 taken 4200 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4200 times.
✗ Branch 3 not taken.
4200 const uint8_t g = (channels > 1) ? pixels[idx + 1] : 0;
34
1/2
✓ Branch 0 taken 4200 times.
✗ Branch 1 not taken.
4200 const uint8_t b = (channels > 2) ? pixels[idx + 2] : 0;
35 const int gray_idx = (row_idx * width) + col_idx;
36 4200 grayscale[gray_idx] = static_cast<uint8_t>((0.299 * r) + (0.587 * g) + (0.114 * b));
37 }
38 }
39 return grayscale;
40 }
41
42 // Применение оператора Собеля к grayscale изображению
43 48 std::vector<uint8_t> ApplySobelOperator(const std::vector<uint8_t> &grayscale, int width, int height) {
44 48 const auto size = static_cast<std::size_t>(width) * static_cast<std::size_t>(height);
45 48 std::vector<uint8_t> result(size, 0);
46
47 // Обрабатываем только внутренние пиксели (пропускаем границы)
48
2/2
✓ Branch 0 taken 464 times.
✓ Branch 1 taken 48 times.
512 for (int row_idx = 1; row_idx < height - 1; ++row_idx) {
49
2/2
✓ Branch 0 taken 6352 times.
✓ Branch 1 taken 464 times.
6816 for (int col_idx = 1; col_idx < width - 1; ++col_idx) {
50 int gx = 0;
51 int gy = 0;
52
53 // Применяем матрицы свертки
54
2/2
✓ Branch 0 taken 19056 times.
✓ Branch 1 taken 6352 times.
25408 for (int ky = -1; ky <= 1; ++ky) {
55
2/2
✓ Branch 0 taken 57168 times.
✓ Branch 1 taken 19056 times.
76224 for (int kx = -1; kx <= 1; ++kx) {
56 57168 const int pixel_idx = ((row_idx + ky) * width) + (col_idx + kx);
57 57168 const int pixel_value = static_cast<int>(grayscale[pixel_idx]);
58 57168 const int kernel_y = ky + 1;
59 57168 const int kernel_x = kx + 1;
60 57168 gx += pixel_value * kSobelX.at(static_cast<std::size_t>(kernel_y)).at(static_cast<std::size_t>(kernel_x));
61 57168 gy += pixel_value * kSobelY.at(static_cast<std::size_t>(kernel_y)).at(static_cast<std::size_t>(kernel_x));
62 }
63 }
64
65 // Вычисляем величину градиента: |Gx| + |Gy|
66 6352 int magnitude = std::abs(gx) + std::abs(gy);
67
68 // Нормализуем в диапазон [0, 255]
69 // Максимальное значение для |Gx| + |Gy| при uint8_t: 255 * 4 = 1020
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6352 times.
6352 magnitude = std::min(255, magnitude / 4);
71
72 6352 const int result_idx = (row_idx * width) + col_idx;
73 6352 result[result_idx] = static_cast<uint8_t>(magnitude);
74 }
75 }
76
77 48 return result;
78 }
79
80 } // namespace
81
82
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 KorolevKSobelOpratorSEQ::KorolevKSobelOpratorSEQ(const InType &in) {
83 SetTypeOfTask(GetStaticTypeOfTask());
84 GetInput() = in;
85 GetOutput() = {};
86 48 }
87
88 48 bool KorolevKSobelOpratorSEQ::ValidationImpl() {
89 const auto &input = GetInput();
90 // Проверяем, что размеры корректны и массив пикселей имеет правильный размер
91
3/6
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
48 if (input.width <= 0 || input.height <= 0 || input.channels <= 0) {
92 return false;
93 }
94 48 const auto expected_size = static_cast<std::size_t>(input.width) * static_cast<std::size_t>(input.height) *
95
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 static_cast<std::size_t>(input.channels);
96
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (input.pixels.size() != expected_size) {
97 return false;
98 }
99 48 return GetOutput().empty();
100 }
101
102 48 bool KorolevKSobelOpratorSEQ::PreProcessingImpl() {
103 GetOutput() = {};
104 48 return true;
105 }
106
107 48 bool KorolevKSobelOpratorSEQ::RunImpl() {
108 const auto &input = GetInput();
109
110 // Если изображение слишком маленькое для применения оператора Собеля
111
2/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
48 if (input.width < 3 || input.height < 3) {
112 const auto size = static_cast<std::size_t>(input.width) * static_cast<std::size_t>(input.height);
113 GetOutput() = std::vector<uint8_t>(size, 0);
114 return true;
115 }
116
117 // Конвертируем в grayscale, если нужно
118 48 std::vector<uint8_t> grayscale = ConvertToGrayscale(input.pixels, input.width, input.height, input.channels);
119
120 // Применяем оператор Собеля
121
2/6
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
96 GetOutput() = ApplySobelOperator(grayscale, input.width, input.height);
122
123 return true;
124 }
125
126 48 bool KorolevKSobelOpratorSEQ::PostProcessingImpl() {
127 48 return true;
128 }
129
130 } // namespace korolev_k_sobel_oprator
131