forked from np-csu/SLIC-superpixel-with-OpenCV
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslic.h
272 lines (241 loc) · 9.23 KB
/
slic.h
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
// SLIC.h: interface for the SLIC class.
//===========================================================================
// This code implements the zero parameter superpixel segmentation technique
// described in:
//
//
//
// "SLIC Superpixels Compared to State-of-the-art Superpixel Methods"
//
// Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi, Pascal Fua,
// and Sabine Susstrunk,
//
// IEEE TPAMI, Volume 34, Issue 11, Pages 2274-2282, November 2012.
//
//
//===========================================================================
// Copyright (c) 2013 Radhakrishna Achanta.
//
// For commercial use please contact the author:
//
// Email: [email protected]
//===========================================================================
//
// Modified by nipan
// Email: [email protected]
//
#pragma once
#include <vector>
#include <string>
#include <algorithm>
#include <opencv2/opencv.hpp>
#if (defined WIN32 || defined _WIN32)
# define SLIC_EXPORTS __declspec(dllexport)
#else
# define SLIC_EXPORTS
#endif
typedef unsigned int UINT;
typedef unsigned char uchar;
enum imageType {RGB, GRAY};
class SLIC_EXPORTS SLIC
{
public:
SLIC();
virtual ~SLIC();
//===========================================================================
/// Perform SLIC algorithm on the given image
/// with the given number of superpixels
//===========================================================================
void GenerateSuperpixels(
cv::Mat& img,
UINT numSuperpixels);
//===========================================================================
/// Get label on each pixel which shows the number of superpixel it belongs to
//===========================================================================
int* GetLabel();
//===========================================================================
/// Get the result image with contours on the given color
//===========================================================================
cv::Mat GetImgWithContours(cv::Scalar color);
private:
//============================================================================
// Superpixel segmentation for a given step size (superpixel size ~= step*step)
//============================================================================
void PerformSLICO_ForGivenStepSize(
const unsigned int* ubuff,//Each 32 bit unsigned int contains ARGB pixel values.
const int width,
const int height,
int* klabels,
int& numlabels,
const int& STEP,
const double& m);
//============================================================================
// Superpixel segmentation for a given number of superpixels
//============================================================================
void PerformSLICO_ForGivenK(
const unsigned int* ubuff,//Each 32 bit unsigned int contains ARGB pixel values.
const int width,
const int height,
int* klabels,
int& numlabels,
const int& K,
const double& m);
void PerformSLICO_ForGivenK(
const unsigned char* ubuff,
const int width,
const int height,
int* klabels,
int& numlabels,
const int& K,//required number of superpixels
const double& m);//weight given to spatial distance
//============================================================================
// Save superpixel labels in a text file in raster scan order
//============================================================================
void SaveSuperpixelLabels(
const int* labels,
const int& width,
const int& height,
const std::string& filename,
const std::string& path);
//============================================================================
// Function to draw boundaries around superpixels of a given 'color'.
// Can also be used to draw boundaries around supervoxels, i.e layer by layer.
//============================================================================
void DrawContoursAroundSegments(
unsigned int* ubuff,
const int* labels,
const int& width,
const int& height,
const cv::Scalar& color );
void DrawContoursAroundSegments(
unsigned char* ubuff,
const int* labels,
const int& width,
const int& height,
const cv::Scalar& color );
void DrawContoursAroundSegmentsTwoColors(
unsigned int* ubuff,
const int* labels,
const int& width,
const int& height);
private:
//============================================================================
// Magic SLIC. No need to set M (compactness factor) and S (step size).
// SLICO (SLIC Zero) varies only M dynamicaly, not S.
//============================================================================
void PerformSuperpixelSegmentation_VariableSandM(
std::vector<double>& kseedsl,
std::vector<double>& kseedsa,
std::vector<double>& kseedsb,
std::vector<double>& kseedsx,
std::vector<double>& kseedsy,
int* klabels,
const int& STEP,
const int& NUMITR);
//============================================================================
// Pick seeds for superpixels when step size of superpixels is given.
//============================================================================
void GetLABXYSeeds_ForGivenStepSize(
std::vector<double>& kseedsl,
std::vector<double>& kseedsa,
std::vector<double>& kseedsb,
std::vector<double>& kseedsx,
std::vector<double>& kseedsy,
const int& STEP,
const bool& perturbseeds,
const std::vector<double>& edgemag);
//============================================================================
// Pick seeds for superpixels when number of superpixels is input.
//============================================================================
void GetLABXYSeeds_ForGivenK(
std::vector<double>& kseedsl,
std::vector<double>& kseedsa,
std::vector<double>& kseedsb,
std::vector<double>& kseedsx,
std::vector<double>& kseedsy,
const int& STEP,
const bool& perturbseeds,
const std::vector<double>& edges);
//============================================================================
// Move the seeds to low gradient positions to avoid putting seeds at region boundaries.
//============================================================================
void PerturbSeeds(
std::vector<double>& kseedsl,
std::vector<double>& kseedsa,
std::vector<double>& kseedsb,
std::vector<double>& kseedsx,
std::vector<double>& kseedsy,
const std::vector<double>& edges);
//============================================================================
// Detect color edges, to help PerturbSeeds()
//============================================================================
void DetectLabEdges(
const double* lvec,
const double* avec,
const double* bvec,
const int& width,
const int& height,
std::vector<double>& edges);
//============================================================================
// xRGB to XYZ conversion; helper for RGB2LAB()
//============================================================================
void RGB2XYZ(
const int& sR,
const int& sG,
const int& sB,
double& X,
double& Y,
double& Z);
//============================================================================
// sRGB to CIELAB conversion
//============================================================================
void RGB2LAB(
const int& sR,
const int& sG,
const int& sB,
double& lval,
double& aval,
double& bval);
//============================================================================
// sRGB to CIELAB conversion for 2-D images
//============================================================================
void DoRGBtoLABConversion(
const unsigned int*& ubuff,
double*& lvec,
double*& avec,
double*& bvec);
//============================================================================
// sRGB to CIELAB conversion for 3-D volumes
//============================================================================
void DoRGBtoLABConversion(
const unsigned int**& ubuff,
double**& lvec,
double**& avec,
double**& bvec);
//============================================================================
// Post-processing of SLIC segmentation, to avoid stray labels.
//============================================================================
void EnforceLabelConnectivity(
const int* labels,
const int& width,
const int& height,
int* nlabels,//input labels that need to be corrected to remove stray labels
int& numlabels,//the number of labels changes in the end if segments are removed
const int& K); //the number of superpixels desired by the user
void Mat2Buffer(const cv::Mat& img, UINT*& buffer);
void Mat2Buffer(const cv::Mat& img, uchar*& buffer);
private:
int m_width;
int m_height;
int m_depth;
double* m_lvec;
double* m_avec;
double* m_bvec;
double** m_lvecvec;
double** m_avecvec;
double** m_bvecvec;
UINT* bufferRGB; // buffer for if RGB image
uchar* bufferGray; // buffer if gray image
int* label; // label record which superpixel a pixel belongs to
imageType type;
};