algoLib/sourceCode/SG_labelling.cpp

141 lines
4.7 KiB
C++
Raw Normal View History

2025-06-08 10:46:41 +08:00
#include <opencv2/imgproc/types_c.h>
#include <iostream>
#include "SG_labelling.h"
using namespace std;
//using namespace cv;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע
/// </summary>
/// <param name="bwImg"> Ŀ<><C4BF><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>1<EFBFBD><31><EFBFBD><EFBFBD> <20>հ׵<D5B0>Ϊ<EFBFBD><CEAA>0<EFBFBD><30></param>
/// <param name="labImg"> <20><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD>ΪrgnID, ID<49><44>2<EFBFBD><32>ʼ </param>
/// <param name="labelRgns"></param>
void SG_TwoPassLabel(const cv::Mat& bwImg, cv::Mat& labImg, std::vector<SSG_Region>& labelRgns)
{
assert(bwImg.type() == CV_8UC1);
bwImg.convertTo(labImg, CV_32SC1);
int rows = bwImg.rows - 1;
int cols = bwImg.cols - 1;
//<2F><>ֵͼ<D6B5><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵΪ0<CEAA><30>1<EFBFBD><31>Ϊ<EFBFBD>˲<EFBFBD><CBB2><EFBFBD>ͻ<EFBFBD><CDBB>label<65><6C>2<EFBFBD><32>ʼ
int label = 2;
std::vector<int> labelSet;
labelSet.push_back(0);
labelSet.push_back(1);
//<2F><>һ<EFBFBD><D2BB>ɨ<EFBFBD><C9A8>
int* data_prev = (int*)labImg.data;
int* data_cur = (int*)(labImg.data + labImg.step);
int left, up;//ָ<><D6B8>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>󷽵<EFBFBD><F3B7BDB5><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>
int neighborLabels[2];
for (int i = 1; i < rows; i++)// <20><><EFBFBD>Ե<EFBFBD>һ<EFBFBD>к͵<D0BA>һ<EFBFBD><D2BB>,<2C><>ʵ<EFBFBD><CAB5><EFBFBD>Խ<EFBFBD>labImg<6D>Ŀ<EFBFBD><C4BF>߼<EFBFBD>1<EFBFBD><31>Ȼ<EFBFBD><C8BB><EFBFBD>ڳ<EFBFBD>ʼ<EFBFBD><CABC>Ϊ0<CEAA>Ϳ<EFBFBD><CDBF><EFBFBD><EFBFBD><EFBFBD>
{
data_cur++;
data_prev++;
for (int j = 1; j < cols; j++, data_cur++, data_prev++)
{
if (*data_cur != 1)//<2F><>ǰ<EFBFBD>㲻Ϊ1<CEAA><31>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
continue;
left = *(data_cur - 1);
up = *data_prev;
int count = 0;
for (int curLabel : {left, up})
{
if (curLabel > 1)
neighborLabels[count++] = curLabel;
}
if (!count)//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µ<EFBFBD>label
{
labelSet.push_back(label);
*data_cur = label;
label++;
continue;
}
//<2F><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>label<65><6C><EFBFBD><EFBFBD>Сֵ
int smallestLabel = neighborLabels[0];
if (count == 2 && neighborLabels[1] < smallestLabel)
smallestLabel = neighborLabels[1];
*data_cur = smallestLabel;
//<2F><><EFBFBD>õȼ۱<C8BC><DBB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><D0BF>ܱ<EFBFBD><DCB1>ϵ<EFBFBD>С<EFBFBD><D0A1>Ҳ<EFBFBD>п<EFBFBD><D0BF>ܱ<EFBFBD><DCB1>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>
//0 0 1 0 1 0 x x 2 x 3 x
//1 1 1 1 1 1 -> 4 4 2 2 2 2
//Ҫ<><D2AA>labelSet<65><74>3<EFBFBD><33>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ2
for (int k = 0; k < count; k++)
{
int neiLabel = neighborLabels[k];
int oldSmallestLabel = labelSet[neiLabel];
if (oldSmallestLabel > smallestLabel)
{
labelSet[oldSmallestLabel] = smallestLabel;
}
else if (oldSmallestLabel < smallestLabel)
labelSet[smallestLabel] = oldSmallestLabel;
}
}
data_cur++;
data_prev++;
}
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>,<2C>е<EFBFBD>labelSet<65><74>λ<EFBFBD>û<EFBFBD>δ<EFBFBD><CEB4>Ϊ<EFBFBD><CEAA>Сֵ<D0A1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//0 0 1 0 1 x x 2 x 3
//0 1 1 1 1 -> x 4 2 2 2
//1 1 1 0 1 5 4 2 x 2
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E2B2A8><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>labelSet[4]<5D><>Ϊ2<CEAA><32><EFBFBD><EFBFBD>labelSet[5]<5D><>Ϊ4
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD>labelSet[5]<5D><>Ϊ2
for (size_t i = 2; i < labelSet.size(); i++)
{
int curLabel = labelSet[i];
int prelabel = labelSet[curLabel];
while (prelabel != curLabel)
{
curLabel = prelabel;
prelabel = labelSet[prelabel];
}
labelSet[i] = curLabel;
}
//<2F>ڶ<EFBFBD><DAB6><EFBFBD>ɨ<EFBFBD><EFBFBD><E8A3AC>labelSet<65><74><EFBFBD>и<EFBFBD><D0B8>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
std::vector<SSG_Region*> labelInfo;
labelInfo.resize(labelSet.size(), nullptr);
data_cur = (int*)labImg.data;
for (int i = 0; i < labImg.rows; i++)
{
for (int j = 0; j < labImg.cols; j++)
{
*data_cur = labelSet[*data_cur];
if (*data_cur > 1) //<2F><>Чlabel
{
//ͳ<><CDB3>Region<6F><6E>Ϣ
SSG_Region* info_cur = (SSG_Region*)labelInfo[*data_cur];
if (nullptr == info_cur)
{
SSG_Region new_rgn = { {j,j,i,i}, 1, *data_cur };
labelRgns.push_back(new_rgn); //push_back()<29><><EFBFBD><EFBFBD>vector<6F><72><EFBFBD>ڴ浥Ԫ<E6B5A5><D4AA><EFBFBD>ܻᱻ<DCBB>Ķ<EFBFBD>
for (int m = 0; m < labelRgns.size(); m++)
{
info_cur = &labelRgns[m];
labelInfo[info_cur->labelID] = info_cur;
}
}
else
{
assert(*data_cur == info_cur->labelID);
if (info_cur->roi.left > j)
info_cur->roi.left = j;
if (info_cur->roi.right < j)
info_cur->roi.right = j;
if (info_cur->roi.top > i)
info_cur->roi.top = i;
if (info_cur->roi.bottom < i)
info_cur->roi.bottom = i;
info_cur->ptCounter++;
}
}
data_cur++;
}
}
return;
}