1+ #pragma once
2+
3+ /* * @file */
4+
5+ #include < optional>
6+
7+ #include " vc/core/types/OrderedPointSet.hpp"
8+ #include " vc/core/types/VolumePkg.hpp"
9+ #include " vc/segmentation/ChainSegmentationAlgorithm.hpp"
10+ #include " vc/segmentation/lrps/FittedCurve.hpp"
11+
12+ namespace volcart ::segmentation
13+ {
14+ /* *
15+ * @brief Optical Flow Segmentation
16+ *
17+ * @author Julian Schilliger (May 2023)
18+ *
19+ * This algorithm propagates a chain of points forward through a volume from a
20+ * starting z-index to an ending z-index (inclusive). It uses optical flow to
21+ * track the shape of the layer. Each seed point is assumed to be placed within
22+ * the layer rather than on its surface boundary.
23+ *
24+ * @warning This algorithm is non-deterministic and yields slightly different
25+ * results each run.
26+ *
27+ * @ingroup Segmentation
28+ */
29+ class OpticalFlowSegmentation : public ChainSegmentationAlgorithm
30+ {
31+ public:
32+ /* * Pointer */
33+ using Pointer = std::shared_ptr<OpticalFlowSegmentation>;
34+
35+ /* * @brief Default constructor */
36+ OpticalFlowSegmentation () = default ;
37+
38+ /* * Default destructor */
39+ ~OpticalFlowSegmentation () override = default ;
40+
41+ /* * Make a new shared instance */
42+ template <typename ... Args>
43+ static auto New (Args... args) -> Pointer
44+ {
45+ return std::make_shared<OpticalFlowSegmentation>(
46+ std::forward<Args>(args)...);
47+ }
48+
49+ /* * @brief Set the target z-index */
50+ void setTargetZIndex (int z);
51+
52+ /* *
53+ * @brief Set the threshold of what pixel brightness is considered inside a
54+ * sheet (higher as threshold) and outside (lower as threshold)
55+ */
56+ void setOutsideThreshold (std::uint8_t outside);
57+
58+ /* *
59+ * @brief Set the threshold of what pixel brightness is considered while
60+ * calculating optical flow, darker pixels OF is interpolated from brighter
61+ * ones in the area
62+ */
63+ void setOFThreshold (std::uint8_t ofThr);
64+
65+ /* *
66+ * @brief Set the maximum single pixel optical flow displacement before
67+ * interpolating a pixel region
68+ */
69+ void setOFDispThreshold (std::uint32_t ofDispThrs);
70+
71+ /* *
72+ * @brief Set the threshold for what pixel brightness is considered as
73+ * being outside the sheet. Pixels above this threshold are considered
74+ * outside the sheet and are smoothed in an attempt to get them tracking
75+ * the sheet again.
76+ */
77+ void setSmoothBrightnessThreshold (std::uint8_t brightness);
78+
79+ /* *
80+ * @brief Set the estimated thickness of the substrate (in um)
81+ *
82+ * Used to generate the radius of the structure tensor calculation
83+ */
84+ void setMaterialThickness (double m);
85+
86+ /* * @brief Set the maximum number of threads */
87+ void setMaxThreads (std::uint32_t t);
88+
89+ /* * @brief Clear the maximum number of threads */
90+ void resetMaxThreads ();
91+
92+ /* * Debug: Shows intensity maps in GUI window */
93+ void setVisualize (bool b);
94+
95+ /* * Debug: Dumps reslices and intensity maps to disk */
96+ void setDumpVis (bool b);
97+
98+ /* * @brief Compute the segmentation */
99+ auto compute () -> PointSet override ;
100+
101+ /* * @brief Returns the maximum progress value */
102+ [[nodiscard]] auto progressIterations () const -> size_t override ;
103+
104+ private:
105+ /* * @brief Compute the segmentation 1 Line */
106+ auto compute_curve_ (const FittedCurve& currentCurve, int zIndex)
107+ -> std::vector<Voxel>;
108+
109+ /* *
110+ * @brief Debug: Draw curve on slice image
111+ * @param curve Input curve
112+ * @param sliceIndex %Slice on which to draw
113+ * @param particleIndex Highlight point at particleIndex
114+ * @param showSpline Draw interpolated curve. Default only draws points
115+ */
116+ [[nodiscard]] auto draw_particle_on_slice_ (
117+ const FittedCurve& curve,
118+ int sliceIndex,
119+ int particleIndex = -1 ,
120+ bool showSpline = false ) const -> cv::Mat;
121+
122+ /* * @brief Convert the internal storage array into a final PointSet */
123+ auto create_final_pointset_ (const std::vector<std::vector<Voxel>>& points)
124+ -> PointSet;
125+
126+ /* * Target z-index */
127+ int endIndex_{0 };
128+ /* *
129+ * Darker pixels are considered outside the sheet. This parameter sets the
130+ * threshold of what pixel brightness is considered too deep inside a sheet
131+ * (higher than the threshold) and then tries to smoothen those points back
132+ * towards the edge of the sheet. Range: 0-255.
133+ */
134+ std::uint8_t outsideThreshold_{80 };
135+ /* *
136+ * Disregarding pixel that are darker during optical flow computation. This
137+ * parameter sets the threshold for what pixel brightness is considered
138+ * while calculating optical flow. Darker pixels' optical flow is
139+ * interpolated from brighter ones in the area. Range: 0-255. Higher values
140+ * disregard more dark pixels during computation, while lower values
141+ * include more dark pixels.
142+ */
143+ std::uint8_t opticalFlowPixelThreshold_{80 };
144+ /* *
145+ * Threshold of how many pixel optical flow can displace a point, if
146+ * higher, recompute optical flow with region's average flow. This
147+ * parameter sets the maximum single pixel optical flow displacement before
148+ * interpolating a pixel region. Range minimum: 0. Higher values allow more
149+ * displacement before interpolation, while lower values trigger
150+ * interpolation more frequently.
151+ */
152+ std::uint32_t opticalFlowDisplacementThreshold_{10 };
153+ /* *
154+ * This parameter sets the threshold for what pixel brightness is considered
155+ * as being outside the sheet. Pixels considered outside the sheet are
156+ * smoothed in an attempt to get them tracking the sheet again.
157+ * Range: 0-255. Smooth curve at pixels above this threshold.
158+ */
159+ std::uint8_t smoothByBrightness_{180 };
160+ /* * Estimated material thickness in um */
161+ double materialThickness_{100 };
162+ /* * Maximum number of threads */
163+ std::optional<std::uint32_t > maxThreads_;
164+ /* * Dump visualization to disk flag */
165+ bool dumpVis_{false };
166+ /* * Show visualization in GUI flag */
167+ bool visualize_{false };
168+ };
169+ } // namespace volcart::segmentation
0 commit comments