18 #ifndef PIC_ALGORITHMS_CONNECTED_COMPONENTS_HPP 19 #define PIC_ALGORITHMS_CONNECTED_COMPONENTS_HPP 26 #include "../base.hpp" 28 #include "../image.hpp" 30 #include "../util/buffer.hpp" 88 void secondPass(
uint *imgOut, std::vector<LabelOutput> &ret, std::set<LabelInfo> &labelEq,
int n)
92 std::set<LabelInfo> labelEq_new;
94 for(
auto it2 = labelEq.begin() ; it2 != labelEq.end(); it2++) {
101 auto it = labelEq.find(tmpLI);
103 if(it != labelEq.end()) {
104 auto tmpMinLabel = (*it).minLabel;
106 if(minVal > tmpMinLabel) {
107 minVal = tmpMinLabel;
116 labelEq_new.insert(tmp_it);
122 std::set<uint> unique;
124 std::map<uint, int> mapping;
128 for(
int i = 0; i < n; i++) {
129 tmpLI.
id = imgOut[i];
130 auto it = labelEq_new.find(tmpLI);
132 if(it != labelEq_new.end()) {
133 imgOut[i] = it->minLabel;
138 auto uniqueIt = unique.find(
id);
140 if(uniqueIt != unique.end()) {
141 ret[mapping[id]].push_back(i);
143 std::pair<uint, int> tmp = std::make_pair(
id, counter);
147 ret.push_back(tmpRet);
155 void track(
uint *imgOut,
int &label, std::set<LabelInfo> &labelEq,
156 int neighbors[2],
int nNeighbors,
int ind)
158 std::set<LabelInfo>::iterator it;
160 if(nNeighbors == 0) {
165 if(nNeighbors == 1) {
166 imgOut[ind] = imgOut[neighbors[0]];
169 if(nNeighbors == 2) {
172 t1 = imgOut[neighbors[0]];
173 t2 = imgOut[neighbors[1]];
174 minVal =
MIN(t1, t2);
183 it = labelEq.find(tmpLI);
185 if(it != labelEq.end()) {
186 float tmpMinLabel = it->minLabel;
188 if(minVal > tmpMinLabel) {
189 minVal = tmpMinLabel;
195 imgOut[ind] = minVal;
200 it = labelEq.find(tmpLI);
202 if(it != labelEq.end()) {
208 labelEq.insert(tmp_it);
211 tmpLabelInfo.
id = t1;
213 labelEq.insert(tmpLabelInfo);
218 it = labelEq.find(tmpLI);
220 if(it != labelEq.end()) {
226 labelEq.insert(tmp_it);
229 tmpLabelInfo.
id = t2;
231 labelEq.insert(tmpLabelInfo);
244 this->thr =
thr > 0.0f ?
thr : 0.05f;
260 float *data = imgIn->
data;
261 int width = imgIn->
width;
262 int height = imgIn->
height;
265 int n = width * height;
268 imgOut =
new uint[n];
277 std::set<LabelInfo> labelEq;
278 for(
int j = 0; j < height; j++) {
279 int indY = j * width;
281 for(
int i = 0; i < width; i++) {
282 int ind = (indY + i);
284 int ind_img = ind * channels;
291 int ind_img_prev = ind_img - channels;
295 float dist = sqrtf(
Arrayf::distanceSq(&data[ind_img], &data[ind_img_prev], channels));
297 if(dist <= (
thr *
MAX(n1, n2))) {
298 neighbors[0] = ind - 1;
304 int ind_img_prev = ind_img - (width * channels);
308 float dist = sqrtf(
Arrayf::distanceSq(&data[ind_img], &data[ind_img_prev], channels));
310 if(dist <= (
thr *
MAX(n1, n2))) {
311 neighbors[nNeighbors] = ind - width;
316 track(imgOut, label, labelEq, neighbors, nNeighbors, ind);
333 uint *
execute(T *imgIn,
int width,
int height,
uint *imgOut, std::vector<LabelOutput> &ret)
340 int n = width * height;
343 imgOut =
new uint[n];
353 std::set<LabelInfo> labelEq;
354 for(
int j = 0; j < height; j++) {
355 int indY = j * width;
357 for(
int i = 0; i < width; i++) {
358 int ind = (indY + i);
365 int ind_prev = ind - 1;
366 if(data[ind] == data[ind_prev]) {
367 neighbors[0] = ind_prev;
373 int ind_prev = ind - width;
374 if(data[ind] == data[ind_prev]) {
375 neighbors[nNeighbors] = ind_prev;
380 track(imgOut, label, labelEq, neighbors, nNeighbors, ind);
396 if(imgLabel == NULL) {
401 for(
uint i = 0; i < labelsList.size(); i++) {
402 if(labelsList[i].bValid) {
403 labelsList[i].id = c;
422 if(imgLabel == NULL) {
427 imgOut =
new Image(1, width, height, 1);
430 int n = width * height;
431 for(
int i = 0; i < n; i++) {
432 imgOut->
data[i] = float(imgLabel[i]);
446 if(labels == NULL || n < 1) {
452 std::set<uint> labels_tracker;
454 std::map<uint, int> labels_map;
457 for(
int i = 0; i < n; i++) {
459 auto search = labels_tracker.find(j);
460 if (search != labels_tracker.end()) {
461 labels_tracker.insert(j);
466 labelsList.push_back(tmp);
471 labelsList[labels_map[j]].push_back(i);
484 if(n < 1 || labelsList.empty()) {
489 labels =
new uint[n];
492 for(
uint i = 0; i < labelsList.size(); i++) {
493 if(labelsList[i].bValid) {
494 for(
uint j = 0; j < labelsList[i].coords.size(); j++) {
495 int k = labelsList[i].coords[j];
496 labels[k] = labelsList[i].id;
512 for(
uint i = 0; i < labelsList.size(); i++) {
513 labels_map[labelsList[i].id] = i;
526 std::map<uint, int> labels_map;
529 int width_m_1 = width - 1;
530 int height_m_1 = height - 1;
532 for(
int i = 0; i < height; i++) {
533 int shift = i * width;
535 for(
int j = 0; j < width; j++) {
538 uint l_ind = labels[ind];
539 int ind2 = labels_map[l_ind];
542 if(l_ind != labels[ind - width]) {
543 labelsList[ind2].neighbors.insert(labels[ind - width]);
548 if(l_ind != labels[ind - 1]) {
549 labelsList[ind2].neighbors.insert(labels[ind - 1]);
554 if(l_ind != labels[ind + width]) {
555 labelsList[ind2].neighbors.insert(labels[ind + width]);
560 if(l_ind != labels[ind + 1]) {
561 labelsList[ind2].neighbors.insert(labels[ind + 1]);
579 if(threshold < 1 || labels == NULL || labelsList.empty()) {
583 if(labelsList[0].neighbors.empty()) {
587 std::map<uint, int> labels_map;
590 for(
uint i = 0; i < labelsList.size(); i++) {
591 if(!labelsList[i].bValid || labelsList[i].neighbors.empty()) {
595 if(labelsList[i].neighbors.size() == 1) {
596 uint id = *labelsList[i].neighbors.begin();
597 int index = labels_map[id];
599 if(labelsList[index].bValid) {
601 if(labelsList[i].coords.size() > labelsList[index].coords.size()) {
602 labelsList[index].bValid =
false;
605 labelsList[i].coords.insert(labelsList[i].coords.begin(),
606 labelsList[index].coords.begin(),
607 labelsList[index].coords.end());
610 if(labelsList[index].neighbors.size() > 1) {
611 labelsList[i].neighbors.insert(labelsList[index].neighbors.begin(), labelsList[index].neighbors.end());
614 for (
auto it = labelsList[index].neighbors.begin(); it != labelsList[index].neighbors.end(); it++) {
616 int index2 = labels_map[id2];
618 labelsList[index2].neighbors.erase(index);
619 labelsList[index2].neighbors.insert(i);
623 labelsList[i].bValid =
false;
626 labelsList[index].coords.insert(labelsList[index].coords.begin(),
627 labelsList[i].coords.begin(),
628 labelsList[i].coords.end());
631 labelsList[index].neighbors.erase(i);
unsigned int uint
Definition: base.hpp:23
static void getMappingLabelsList(std::vector< LabelOutput > &labelsList, std::map< uint, int > &labels_map)
getMappingLabelsList
Definition: connected_components.hpp:510
static Image * convertFromIntegerToImage(uint *imgLabel, Image *imgOut, int width, int height)
convertFromIntegerToImage
Definition: connected_components.hpp:420
float * data
data is the main buffer where pixel values are stored.
Definition: image.hpp:91
int channels
Definition: image.hpp:80
std::set< int > neighbors
Definition: connected_components.hpp:50
uint id
Definition: connected_components.hpp:48
float thr
Definition: connected_components.hpp:81
static void assign(T *dataDst, IntCoord &coord, T dataSrc)
assign
Definition: indexed_array.hpp:340
static void mergeIsolatedAreasWithThreshold(uint *labels, int width, int height, std::vector< LabelOutput > &labelsList, int threshold=1)
mergeIsolatedAreasWithThreshold
Definition: connected_components.hpp:577
bool bValid
Definition: connected_components.hpp:51
uint minLabel
Definition: connected_components.hpp:37
uint id
Definition: connected_components.hpp:36
LabelOutput()
Definition: connected_components.hpp:53
static T distanceSq(T *data0, T *data1, int n)
distanceSq
Definition: array.hpp:195
static uint * computeImageLabelsFromLabelsList(std::vector< LabelOutput > &labelsList, uint *labels, int n)
computeImageLabelsFromLabelsList
Definition: connected_components.hpp:482
static uint * reCount(uint *imgLabel, std::vector< LabelOutput > &labelsList)
reCount
Definition: connected_components.hpp:394
uint * execute(T *imgIn, int width, int height, uint *imgOut, std::vector< LabelOutput > &ret)
execute
Definition: connected_components.hpp:333
Definition: connected_components.hpp:45
void track(uint *imgOut, int &label, std::set< LabelInfo > &labelEq, int neighbors[2], int nNeighbors, int ind)
Definition: connected_components.hpp:155
static void computeLabelsListFromImageLabels(uint *labels, int n, std::vector< LabelOutput > &labelsList)
computeLabelsList
Definition: connected_components.hpp:444
void secondPass(uint *imgOut, std::vector< LabelOutput > &ret, std::set< LabelInfo > &labelEq, int n)
secondPass
Definition: connected_components.hpp:88
void push_back(int i)
Definition: connected_components.hpp:66
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
Definition: connected_components.hpp:34
ConnectedComponents(float thr=0.05f)
ConnectedComponents.
Definition: connected_components.hpp:242
Definition: bilateral_separation.hpp:25
#define MAX(a, b)
Definition: math.hpp:73
static T norm(float *data, int n)
norm
Definition: array.hpp:245
static void computeNeighbors(uint *labels, int width, int height, std::vector< LabelOutput > &labelsList)
computeNeighbors
Definition: connected_components.hpp:524
uint * execute(Image *imgIn, uint *imgOut, std::vector< LabelOutput > &ret)
execute
Definition: connected_components.hpp:253
int width
Definition: image.hpp:80
int height
Definition: image.hpp:80
std::vector< int > coords
Definition: connected_components.hpp:49
Definition: connected_components.hpp:78
static T * assign(T *buffer, int n, T value)
assign assigns value to buffer
Definition: buffer.hpp:45
LabelOutput(uint id, int i)
Definition: connected_components.hpp:59
friend bool operator<(LabelOutput const &a, LabelOutput const &b)
Definition: connected_components.hpp:71
friend bool operator<(LabelInfo const &a, LabelInfo const &b)
Definition: connected_components.hpp:39