141 lines
4.7 KiB
C++
141 lines
4.7 KiB
C++
|
|
#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;
|
|||
|
|
}
|