Ocean
Loading...
Searching...
No Matches
FrameFilterPrewitt.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_CV_FRAME_FILTER_PREWITT_H
9#define META_OCEAN_CV_FRAME_FILTER_PREWITT_H
10
11#include "ocean/cv/CV.h"
14
15#include "ocean/base/Worker.h"
16
17namespace Ocean
18{
19
20namespace CV
21{
22
23/**
24 * This class implements a Prewitt frame filter.
25 * The horizontal (0 degree) and vertical (90 degree - clockwise) 3x3 Prewitt box filter (not convolution filter) are defined as:
26 * <pre>
27 * horizontal: vertical (90 degree):
28 * | -1 0 1 | | -1 -1 -1 |
29 * | -1 0 1 | | 0 0 0 |
30 * | -1 0 1 | | 1 1 1 |
31 * </pre>
32 *
33 * The diagonal 3x3 Prewitt filters are defined as:
34 * <pre>
35 * 45 degree: 135 degree:
36 * | -1 -1 0 | | 0 -1 -1 |
37 * | -1 0 1 | | 1 0 -1 |
38 * | 0 1 1 | | 1 1 0 |
39 * </pre>
40 * @ingroup cv
41 */
42class OCEAN_CV_EXPORT FrameFilterPrewitt : public FrameFilter
43{
44 public:
45
46 /**
47 * Horizontal and vertical Prewitt filter for images.
48 * If the target response data type is selected to be `int8_t`, each filter response is normalized by 1/6 to fit into the value range [-128, 127].<br>
49 * If the target response data type is selected to be `int16_t` no normalization will be applied.
50 * The border pixels are set to zero.
51 * @param source The source frame to which the Prewitt filter will be applied, with `tSourceChannels` channels, must be valid
52 * @param target The target response frame receiving the horizontal and vertical Prewitt responses, with `tSourceChannels * 2` channels, must be valid
53 * @param width The width of the frame in pixel, with range [3, infinity)
54 * @param height The height of the frame in pixel, with range [3, infinity)
55 * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
56 * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
57 * @param worker Optional worker object to distribute the computational load
58 * @tparam TTarget The data type of the response values, either `int8_t` or `int16_t`
59 * @tparam tSourceChannels The number of channels of the source frame, with range [1, infinity)
60 */
61 template <typename TTarget, unsigned int tSourceChannels>
62 static inline void filterHorizontalVertical8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
63
64 private:
65
66 /**
67 * Applies the horizontal and vertical Prewitt filter to one row of a source frame.
68 * @param sourceRow The row of the source frame, must be valid
69 * @param targetRow The row of the target response frame, must be valid
70 * @param width The width of the source and target frame in pixel, with range [3, infinity)
71 * @param height The height of the source and target frame in pixel, with range [3, infinity)
72 * @param rowIndex The index of the row to which the filter is applied, with range [0, height - 1]
73 * @param sourceStrideElements The number of elements between the start of two consecutive source rows, with range [width * tSourceChannels, infinity)
74 * @param targetStrideElements The number of elements between the start of two consecutive target rows, with range [width * tTargetChannels, infinity)
75 * @tparam TSource The data type of the source frame, must be `uint8_t`
76 * @tparam TTarget The data type oft he target response frame, must be `int8_t` or `int16_t`
77 * @tparam tSourceChannels The number of channels the source frame has, with range [1, infinity)
78 * @tparam tTargetChannels The number of channels the target frame has, must be `tSourceChannels * 2`
79 */
80 template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
81 static void filterHorizontalVerticalRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements);
82};
83
84template <typename TTarget, unsigned int tSourceChannels>
85inline void FrameFilterPrewitt::filterHorizontalVertical8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
86{
87 static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
88 static_assert(tSourceChannels >= 1u, "Invalid channel number!");
89
90 ocean_assert(source != nullptr && target != nullptr);
91 ocean_assert(width >= 3u && height >= 3u);
92
93 //using TSource = uint8_t;
94 constexpr unsigned int tTargetChannels = tSourceChannels * 2u;
95
96 FrameChannels::applyRowOperator<uint8_t, TTarget, tSourceChannels, tTargetChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, &filterHorizontalVerticalRow<uint8_t, TTarget, tSourceChannels, tTargetChannels>, worker);
97}
98
99template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
100void FrameFilterPrewitt::filterHorizontalVerticalRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int /*targetStrideElements*/)
101{
102 static_assert(std::is_same<TSource, uint8_t>::value, "Invalid source data type!");
103 static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
104
105 static_assert(tSourceChannels >= 1u, "Invalid source channel number!");
106 static_assert(tTargetChannels == tSourceChannels * 2u, "Invalid target channel number!");
107
108 ocean_assert(width >= 3u && height >= 3u);
109
110 if (rowIndex == 0u || rowIndex == height - 1u)
111 {
112 // setting the first row and last row to zero
113
114 memset(targetRow, 0, width * tTargetChannels * sizeof(TTarget));
115 return;
116 }
117
118 // setting first pixel to zero
119
120 for (unsigned int n = 0u; n < tTargetChannels; ++n)
121 {
122 targetRow[n] = TTarget(0);
123 }
124
125 targetRow += tTargetChannels;
126
127 const uint8_t* source0 = sourceRow - sourceStrideElements;
128 const uint8_t* source1 = sourceRow;
129 const uint8_t* source2 = sourceRow + sourceStrideElements;
130
131 for (unsigned int x = 1u; x < width - 1u; ++x)
132 {
133 if constexpr (std::is_same<TTarget, int8_t>::value)
134 {
135 for (unsigned int n = 0u; n < tSourceChannels; ++n)
136 {
137 // | -1 0 1 |
138 // | -1 0 1 |
139 // | -1 0 1 |
140 *targetRow++ = TTarget((*(source0 + tSourceChannels * 2u) - *(source0) + (*(source1 + tSourceChannels * 2u) - *(source1)) + *(source2 + tSourceChannels * 2u) - *(source2)) / 8);
141
142 // | -1 -1 -1 |
143 // | 0 0 0 |
144 // | 1 1 1 |
145 *targetRow++ = TTarget((*(source2) + (*(source2 + tSourceChannels) - *(source0 + tSourceChannels)) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) / 8);
146
147 ++source0;
148 ++source1;
149 ++source2;
150 }
151 }
152 else
153 {
154 ocean_assert((std::is_same<TTarget, int16_t>::value));
155
156 for (unsigned int n = 0u; n < tSourceChannels; ++n)
157 {
158 // | -1 0 1 |
159 // | -1 0 1 |
160 // | -1 0 1 |
161 *targetRow++ = TTarget(*(source0 + tSourceChannels * 2u) - *(source0) + (*(source1 + tSourceChannels * 2u) - *(source1)) + *(source2 + tSourceChannels * 2u) - *(source2));
162
163 // | -1 -1 -1 |
164 // | 0 0 0 |
165 // | 1 1 1 |
166 *targetRow++ = TTarget(*(source2) + (*(source2 + tSourceChannels) - *(source0 + tSourceChannels)) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u));
167
168 ++source0;
169 ++source1;
170 ++source2;
171 }
172 }
173 }
174
175 // setting last pixel to zero
176 for (unsigned int n = 0u; n < tTargetChannels; ++n)
177 {
178 targetRow[n] = TTarget(0);
179 }
180}
181
182}
183
184}
185
186#endif // META_OCEAN_CV_FRAME_FILTER_PREWITT_H
This class implements the base class for all filter.
Definition FrameFilter.h:29
This class implements a Prewitt frame filter.
Definition FrameFilterPrewitt.h:43
static void filterHorizontalVertical8BitPerChannel(const uint8_t *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Horizontal and vertical Prewitt filter for images.
Definition FrameFilterPrewitt.h:85
static void filterHorizontalVerticalRow(const TSource *sourceRow, TTarget *targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements)
Applies the horizontal and vertical Prewitt filter to one row of a source frame.
Definition FrameFilterPrewitt.h:100
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
The namespace covering the entire Ocean framework.
Definition Accessor.h:15