二值图像连通标记矩阵计算

原作者:avrmax

#include <stdlib.h>  
#include <stdio.h>  
#include <time.h>  
#include <windows.h>  

HANDLE hOut, hIn; /*标准输出输入句柄*/  
COORD size = {200, 1000}; /*窗口大小*/  
SMALL_RECT rc = {0, 0, 200-1, 50-1};  
CONSOLE_CURSOR_INFO cursor = {1, FALSE}; /*光标信息,用于隐藏光标*/  

typedef struct{  
    unsigned short sc;  
    unsigned short ec;  
    unsigned short r;  
    int label;  
}RunNode_t;  

typedef struct equivnode   
{  
    int LabelA;  
    int LabelB;  
    struct equivnode *next;  
}EquivNode;  

typedef struct equivlist   
{  
    EquivNode *head;  
    int length;  
}EquivList;  

typedef struct MapListNode_tag  
{  
    int idx;  
    struct MapListNode_tag* pNext;  
}MapListNode_t;  

typedef struct MapListList_tag  
{  
    MapListNode_t* pMapNodeList;  
    struct MapListList_tag* pNext;  
}MapListListNode_t;  

typedef struct    
{  
    int mode ;   
    int minarea ;   
    int minpixDiff;  
}SparseInfoExtractCondition_t;  

void DeleteEquivListHeadNode(EquivList *list)   
{  
    EquivNode *killNode;  
    if (list->head != NULL)   
    {  
        killNode = list->head;  
        list->head = killNode->next;  
        free(killNode);  
        list->length--;  
    }  
}  

void DestroyEquivList(EquivList *list)   
{  
    while (list->head != NULL)  
    {  
        EquivNode *killNode = list->head;  
        list->head = killNode->next;  
        free(killNode);  
        list->length--;  
    }  
}  

void UpdateRunNode(int *pTable , RunNode_t* pNode, int NodeNum)  
{  
    int i;  
    for(i = 0 ; i < NodeNum ; i++)  
    {  
        pNode[i].label = pTable[pNode[i].label-1];  
    }  
}  

void BWCreateRunNodeInfoEx(int* BW , int M ,int N ,  
                           SparseInfoExtractCondition_t* pCondtion,  
                           RunNode_t** ppRunNode, int *pRunNodeNum,  
                           int* plabels, EquivList** ppEquivList)  
{  
    int *pr = NULL;  
    int numRuns = 0;  
    RunNode_t* pNode = NULL;  
    int offset ;  
    int i ,j ,k ,p;    
    int currentRow = -1;  
    int nextLabel = 1;  
    int firstRunOnPreviousRow = -1;  
    int lastRunOnPreviousRow = -1;  
    int firstRunOnThisRow = -1;  
    EquivList* pEquivList = (EquivList*)malloc(sizeof(EquivList));  

    int Mode = pCondtion->mode;  
    int MinArea = pCondtion->minarea;  
    int MinpixDiff = pCondtion->minpixDiff;  

    //(1)Computer numRuns  
    for (i = 0; i < N; i++)   //按行遍历  
    {  
        pr = &BW[i*M] ;    //第row行的头指针  

        if (pr[0] != 0)  
            numRuns++;        //本行的第一个元素就是一个Run的头 Run的数目+1  

        for (j = 1; j < M; j++) {  
            if ((pr[j] != 0) && (pr[j-1] == 0))   //01的模式就是Run  
                numRuns++;                        //Run的总数+1  
        }  
    }  
    *pRunNodeNum = numRuns;  

    //(2) 生成 RunNode信息  
    pNode = (RunNode_t*)malloc(numRuns*sizeof(RunNode_t));  
    k = 0;  
    for (i = 0; i < N; i++)   
    {  
        pr = &BW[i*M];  //第row行的头指针  

        j = 0;  
        while (j < M)   
        {       
            //遍历该行  
            while (j < M && pr[j] == 0)  
                j++;                        //找到第一个Run所在的行号  

            if ((j < M) && (pr[j] != 0))   
            {  
                pNode[k].r = i ;       //  
                pNode[k].sc = j ;  
                while (j < M && pr[j] )   //走完这个Run  
                    j++;  
                pNode[k].ec = j-1;  //这个是结尾  
                pNode[k].label = 0;  
                k++;          //处理下一个Run  
            }  
        }  
    }  

    //(3)扫描标记 ,并统计Label 关系的  
    printf("\n\n");  
    printf("(2)打印等价关系对\n");  
    pEquivList->head = NULL;  
    pEquivList->length = 0;  
    offset = 1;  //八邻域为1  ,四邻域为0  
    for (k = 0; k < numRuns; k++)   
    {  
        if (pNode[k].r == currentRow + 1)   
        {     
            //第k个Run与第k-1个Run在相邻的两行上  
            firstRunOnPreviousRow = firstRunOnThisRow;   //firstRunOnPreviousColumn指向第k-1个Run所在的列的第一个(最上面的)Run  
            firstRunOnThisRow = k;  
            lastRunOnPreviousRow = k-1;  
            currentRow = pNode[k].r;  
        }  
        else if (pNode[k].r > (currentRow + 1))   
        {  
            /* 开始新列:前一列没有Run  直接进入下一轮循环*/  
            firstRunOnPreviousRow = -1;  
            lastRunOnPreviousRow = -1;  
            firstRunOnThisRow = k;  
            currentRow = pNode[k].r;  
        }  

        if (firstRunOnPreviousRow >= 0)   
        {  
            p = firstRunOnPreviousRow;  
            while (p <= lastRunOnPreviousRow && pNode[p].sc <= pNode[k].ec + offset)   
            {  
                if ((pNode[k].ec >= pNode[p].sc-offset) &&   
                    (pNode[k].sc <= pNode[p].ec+offset)) //有交叉  
                {  
                    if (pNode[k].label == 0)   
                    {  
                        pNode[k].label = pNode[p].label;  
                    }  
                    else   
                    {  
                        if (pNode[k].label != pNode[p].label)   
                        {  
                            EquivNode *newNode = (EquivNode *)malloc(sizeof(EquivNode));  
                            newNode->LabelA = pNode[k].label;  
                            newNode->LabelB = pNode[p].label;  
                            newNode->next = pEquivList->head;  
                            pEquivList->head = newNode;  
                            pEquivList->length++;  
                            printf("%4d %4d\n" , newNode->LabelA , newNode->LabelB);  
                        }  
                    }  
                }  
                p++;  
            }  
        }  

        if (pNode[k].label == 0)   
        {  
            pNode[k].label = nextLabel;  
            nextLabel++;  
        }  
    }  
    *plabels =nextLabel-1;  
    *ppRunNode = pNode;  
    *ppEquivList = pEquivList;  

    printf("\n\n(3) 打印初始RunNode信息\n");  
    printf("  sc   ec    r   label \n");  
    for(i=0;i<numRuns;i++)  
    {  
        printf("%4d ",pNode[i].sc);  
        printf("%4d ",pNode[i].ec);  
        printf("%4d ",pNode[i].r);  
        printf("%4d ",pNode[i].label);  
        printf("\n");  
    }  
}  

void MapListAddNode(MapListNode_t* pNode , int Idx)  
{  
    MapListNode_t* pNodeTemp = (MapListNode_t*)malloc(sizeof(MapListNode_t));  
    MapListNode_t* pNodeMove = pNode;  
    pNodeTemp->idx = Idx;  
    pNodeTemp->pNext = NULL;  

    while(pNodeMove->pNext)  
        pNodeMove = pNodeMove->pNext;  

    pNodeMove->pNext = pNodeTemp;  
}  

void MapListListAddNode(MapListListNode_t* pListListNode ,MapListNode_t* pListNode)  
{  
    MapListListNode_t* pListListNodeMove = pListListNode;  
    MapListListNode_t* pListListNodeNew = (MapListListNode_t*)malloc(sizeof(MapListListNode_t));  
    while(pListListNodeMove->pNext)  
        pListListNodeMove = pListListNodeMove->pNext;  

    pListListNodeNew->pMapNodeList = pListNode;  
    pListListNodeNew->pNext = NULL;  
    pListListNodeMove->pNext = pListListNodeNew;  
}  

void MapListListDeleteNode(MapListListNode_t* pListListNode ,MapListNode_t* pListNode)  
{  
    MapListListNode_t* pListListNodeMove = pListListNode;  
    MapListListNode_t* pListListNodeKill = NULL;  
    while(pListListNodeMove->pNext)  
    {  
        if(pListListNodeMove->pNext->pMapNodeList == pListNode)  
        {  
            pListListNodeKill = pListListNodeMove->pNext;  
            pListListNodeMove->pNext = pListListNodeMove->pNext->pNext;  
            free(pListListNodeKill);   
            break;  
        }  
        pListListNodeMove = pListListNodeMove->pNext;  
    }  

}  
int MapListMinIdx(MapListNode_t* pNode)  
{  
    int min = 0x7FFFFFFF;  
    while(pNode)  
    {  
        if(pNode->idx < min)  
            min = pNode->idx;  
        pNode = pNode->pNext;  
    }  
    return min;  
}  
MapListNode_t* MapListListFindIdx(MapListListNode_t* pMapListList ,int Idx)  
{  
    MapListNode_t* pMapListNodeHead = NULL;  
    MapListNode_t* pMapNodeListMove = NULL;  
    MapListListNode_t* pMapListListMove = pMapListList;  
    while(pMapListListMove->pNext)  
    {  
        pMapListListMove = pMapListListMove->pNext;  
        pMapListNodeHead = pMapListListMove->pMapNodeList;  
        pMapNodeListMove = pMapListNodeHead;  
        while(pMapNodeListMove)   
        {  
            if(Idx == pMapNodeListMove->idx)  
                return pMapListNodeHead;  

            pMapNodeListMove = pMapNodeListMove->pNext;  
        }  
    }  
    return NULL;  
}  

void MapListMerge(MapListNode_t* pMapListA , MapListNode_t* pMapListB)  
{  
    while(pMapListA->pNext)  
        pMapListA = pMapListA->pNext;  
    pMapListA->pNext = pMapListB;  
}  


void CreateMapTable(EquivList* pList ,int MapTableSize ,int **ppMapTable )  
{  
    int i,j,k;  
    int labela,labelb;  
    MapListNode_t* pMapNodeList = (MapListNode_t*)malloc(sizeof(MapListNode_t));  
    MapListListNode_t* pMapListListNode = NULL;  
    MapListListNode_t* pMapListListforMove = NULL;  
    MapListNode_t* pMapListforMove = NULL ;  
    int *pMapTableInit = NULL;  
    pMapNodeList->idx = pList->head->LabelA;     
    pMapNodeList->pNext = NULL;  
    MapListAddNode(pMapNodeList,pList->head->LabelB);  

    DeleteEquivListHeadNode(pList);  

    pMapListListNode = (MapListListNode_t*)malloc(sizeof(MapListListNode_t));  
    pMapListListNode->pMapNodeList = NULL;  
    pMapListListNode->pNext = NULL;  
    MapListListAddNode(pMapListListNode,pMapNodeList);  

    while(pList->length)  
    {  
        MapListNode_t* pMapListFindA = NULL;  
        MapListNode_t* pMapListFindB = NULL;  
        labela = pList->head->LabelA;  
        labelb = pList->head->LabelB;  
        pMapListFindA = MapListListFindIdx(pMapListListNode,labela);  
        pMapListFindB = MapListListFindIdx(pMapListListNode,labelb);  

        if(pMapListFindA)  
        {  
            if(pMapListFindB)  
            {  
                if (pMapListFindA!=pMapListFindB)  
                {             
                    MapListMerge(pMapListFindA,pMapListFindB);  
                    MapListListDeleteNode(pMapListListNode,pMapListFindB);  
                }  
            }  
            else  
            {  
                MapListAddNode(pMapListFindA,labelb);  
            }  
        }  
        else  
        {  
            if(pMapListFindB)  
            {  
                MapListAddNode(pMapListFindB,labela);  
            }  
            else  
            {  
                pMapNodeList = (MapListNode_t*)malloc(sizeof(MapListNode_t));  
                pMapNodeList->pNext = NULL;  
                pMapNodeList->idx = labela;  
                MapListAddNode(pMapNodeList,labelb);  
                MapListListAddNode(pMapListListNode,pMapNodeList);  
            }  
        }  
        DeleteEquivListHeadNode(pList);  
    }  

    printf("\n\n(4)打印等价链表:\n");  
    pMapListListforMove = pMapListListNode;  
    while (pMapListListforMove->pNext)  
    {  
        pMapListforMove = pMapListListforMove->pNext->pMapNodeList;  
        while(pMapListforMove)  
        {  
            printf("%4d",pMapListforMove->idx);  
            pMapListforMove = pMapListforMove->pNext;  
        }  
        printf("\n");  
        pMapListListforMove = pMapListListforMove->pNext;  
    }  

    pMapTableInit = (int*)malloc(MapTableSize*sizeof(int));  
    printf("\n\n打印初始关系表");  
    for(i = 1 ; i <= MapTableSize ; i++ )  
    {  
        pMapListforMove = MapListListFindIdx(pMapListListNode,i);  
        if(pMapListforMove)  
        {  
            pMapTableInit[i-1] = MapListMinIdx(pMapListforMove);  
            printf("%3d " ,pMapTableInit[i-1]);  
        }  
        else  
        {  
            pMapTableInit[i-1] = i;  
            printf("%3d " ,i);  
        }  
    }  

    printf("\n\n打印对应关系表");  
    *ppMapTable = (int*)malloc(MapTableSize*sizeof(int));  
    (*ppMapTable)[0] = 1;  
    printf("%3d ",(*ppMapTable)[0]);  
    k = 2;  
    for(i = 1 ; i < MapTableSize ; i++ )  
    {  
        j = 0;  

        while(j<i)  
        {  
            if(pMapTableInit[j] == pMapTableInit[i])  
            {  
                (*ppMapTable)[i] = (*ppMapTable)[j];  
                break;  
            }  
            j++;  
        }  

        if(j == i)  
            (*ppMapTable)[i] = k++;  

        printf("%3d ",(*ppMapTable)[i]);  
    }  
}  

void BWCreateRunNodeInfo(int* BW , int M ,int N ,  
                         SparseInfoExtractCondition_t* pCondtion,  
                         RunNode_t** ppRunNode, int *pRunNodeNum)  
{  
    EquivList* pEquivList = NULL;  
    int *pMapTable = NULL;  
    int labels = 0;  
    BWCreateRunNodeInfoEx(BW ,M ,N ,pCondtion,ppRunNode, pRunNodeNum,&labels ,&pEquivList);  

    if(pEquivList->length)  
    {  
        CreateMapTable( pEquivList, labels,&pMapTable);  
        UpdateRunNode(pMapTable,*ppRunNode,*pRunNodeNum);  
    }  
}  

void UpadateBWData(int* BW, int M ,RunNode_t* pNode , int NodeNum)  
{  
    int k = 0 , p = 0;  
    int *pr = NULL;  
    for (k = 0; k < NodeNum; k++)   
    {  
        pr = &BW[pNode[k].r*M + pNode[k].sc];  
        for (p = 0; p < pNode[k].ec - pNode[k].sc + 1; p++)  
            *pr++ = pNode[k].label;  
    }  
}  

#define M 40  
#define N 30  

int main()   
{  
    int i = 0, j = 0;  
    RunNode_t* pRunNode = NULL;  
    int RunNum = 0;  
    SparseInfoExtractCondition_t ExtractCondition;  
    int BW[N][M];  

    hOut = GetStdHandle(STD_OUTPUT_HANDLE);  
    SetConsoleWindowInfo(hOut, TRUE, &rc);  
    SetConsoleScreenBufferSize(hOut, size);  
    SetConsoleCursorInfo(hOut, &cursor);  


    srand( (unsigned)time( NULL ) );  
    printf("(1) 打印实验矩阵\n");  
    for(i = 0; i< N ;i++)  
    {  
        for( j =0 ;j < M;j++ )  
        {  
            if(j == 0)  
                printf("\n");  

            BW[i][j] = (rand()%100)<40;  
            printf("%3d ",BW[i][j]);  
        }  
    }  

    ExtractCondition.minarea = 10;  
    ExtractCondition.minpixDiff = 10;  
    ExtractCondition.mode = 1;  
    BWCreateRunNodeInfo((int*)BW ,M ,N ,&ExtractCondition,&pRunNode, &RunNum);  

    printf("\n\n");  
    printf("(5) 打印最后RunNode信息\n");  
    printf("  sc  ec   r   label\n");  
    for(i=0;i<RunNum;i++)  
    {  
        printf("%4d ",pRunNode[i].sc);  
        printf("%4d ",pRunNode[i].ec);  
        printf("%4d ",pRunNode[i].r);  
        printf("%4d ",pRunNode[i].label);  
        printf("\n");  
    }  

    //(4)根据统计表建立,影射关系表  
    UpadateBWData((int*)BW,M,pRunNode,RunNum);  


    //打印矩阵  
    printf("\n(6) 生成最后的连通标记矩阵");  
    for(i = 0; i< N ;i++)  
    {  
        for( j =0 ;j<M;j++ )  
        {  
            if(j == 0)  
                printf("\n");  
            printf("%3d ",BW[i][j]);  
        }  
    }  
    printf("\n");  
}  

———————————————————————–

稍微改一下

#include "lib.h"

using namespace std;

/*
   二值图像连通域标记算法---8领域
  label = BWLABEL(BW) 返回一个矩阵L,维度与BW相同,包含了2-D二值图像中的连通的各部分的标签。
  label中的元素是整数,大于或等于0,像素为0表示背景,像素为1表示第1个物体,像素为2表示第2个物体,依次类推
*/
/*
   对物体的表示过程如下:
   1、从做到有,从上到下逐个像素扫描
   2、若该店的左上、正上、右上以及左前共四个点的像素都不为物体,则标号加1,且此数组值为1
   3、采用(行坐标,列坐标)方式标记物体。若遇到当前像素为物体A,依次判断该像素的右上点,正上点,
      左上点及左前点。右上点的优先级最高,左前点的优先级最低。
   4、若右上点为物体,则当前点跟右上点,并标记与右上点相同的值。
   5、若右上点不为物体,则判断正上点,当正上点为物体,标记为与正上点相同的值。
   6、同理,若右上点、正上点都不为物体,用同样的方法依次判断左上点,若左上点也不为物体,则再判断左前点。
   7、若右上点、正上点、左上点、左前点都不为物体,则当前点的值在原来的标记加1,以此标记来作为另一物体的区别。
*/

typedef struct
{  
    unsigned short sc;  
    unsigned short ec;  
    unsigned short r;  
    int label;  
}RunNode_t;  

typedef struct equivnode   
{  
    int LabelA;  
    int LabelB;  
    struct equivnode *next;  
}EquivNode;  

typedef struct equivlist   
{  
    EquivNode *head;  
    int length;  
}EquivList;  

typedef struct MapListNode_tag  
{  
    int idx;  
    struct MapListNode_tag* pNext;  
}MapListNode_t;  

typedef struct MapListList_tag  
{  
    MapListNode_t* pMapNodeList;  
    struct MapListList_tag* pNext;  
}MapListListNode_t;  

typedef struct    
{  
    int mode ;   
    int minarea ;   
    int minpixDiff;  
}SparseInfoExtractCondition_t; 

//vector< vector<int> > bwlabel(vector< vector<int> > &BW, int N, int M);
void DeleteEquivListHeadNode(EquivList *list);
void DestroyEquivList(EquivList *list);
void UpdateRunNode(int *pTable , RunNode_t* pNode, int NodeNum);
void BWCreateRunNodeInfoEx(vector< vector<int> > &BW , int M ,int N ,  
                           SparseInfoExtractCondition_t* pCondtion,  
                           RunNode_t** ppRunNode, int *pRunNodeNum,  
                           int* plabels, EquivList** ppEquivList);
void MapListAddNode(MapListNode_t* pNode , int Idx);
void MapListListAddNode(MapListListNode_t* pListListNode ,MapListNode_t* pListNode);
void MapListListDeleteNode(MapListListNode_t* pListListNode ,MapListNode_t* pListNode);
int MapListMinIdx(MapListNode_t* pNode);
MapListNode_t* MapListListFindIdx(MapListListNode_t* pMapListList ,int Idx);
void MapListMerge(MapListNode_t* pMapListA , MapListNode_t* pMapListB);
void CreateMapTable(EquivList* pList ,int MapTableSize ,int **ppMapTable );
void BWCreateRunNodeInfo(vector< vector<int> > &BW , int M ,int N ,  
                         SparseInfoExtractCondition_t* pCondtion,  
                         RunNode_t** ppRunNode, int *pRunNodeNum);
void UpadateBWData(int* BW, int M ,RunNode_t* pNode , int NodeNum);

void DeleteEquivListHeadNode(EquivList *list)   
{  
    EquivNode *killNode;  
    if (list->head != NULL)   
    {  
        killNode = list->head;  
        list->head = killNode->next;  
        free(killNode);  
        list->length--;  
    }  
}  

void DestroyEquivList(EquivList *list)   
{  
    while (list->head != NULL)  
    {  
        EquivNode *killNode = list->head;  
        list->head = killNode->next;  
        free(killNode);  
        list->length--;  
    }  
}  

void UpdateRunNode(int *pTable , RunNode_t* pNode, int NodeNum)  
{  
    int i;  
    for(i = 0 ; i < NodeNum ; i++)  
    {  
        pNode[i].label = pTable[pNode[i].label-1];  
    }  
}  

void BWCreateRunNodeInfoEx(vector< vector<int> > &BW , int M ,int N ,  
                           SparseInfoExtractCondition_t* pCondtion,  
                           RunNode_t** ppRunNode, int *pRunNodeNum,  
                           int* plabels, EquivList** ppEquivList)  
{  
    int *pr = NULL;  
    int numRuns = 0;  
    RunNode_t* pNode = NULL;  
    int offset ;  
    int i ,j ,k ,p;    
    int currentRow = -1;  
    int nextLabel = 1;  
    int firstRunOnPreviousRow = -1;  
    int lastRunOnPreviousRow = -1;  
    int firstRunOnThisRow = -1;  
    EquivList* pEquivList = (EquivList*)malloc(sizeof(EquivList));  

    int Mode = pCondtion->mode;  
    int MinArea = pCondtion->minarea;  
    int MinpixDiff = pCondtion->minpixDiff;  

    //(1)Computer numRuns  
    for (i = 0; i < N; i++)   //按行遍历  
    {  
        if(BW[i][0] != 0)  //本行的第一个元素就是一个Run的头 Run的数目+1  
            numRuns++;

        for(j=1; j<M; j++)
        {
            if((BW[i][j] != 0) && (BW[i][j-1] == 0)) // 01的模式就是Run 
                numRuns++;                                   // Run的总数+1  
        }


        //pr = &BW[i*M] ;    //第row行的头指针  

        //if (pr[0] != 0)  
        //    numRuns++;        //本行的第一个元素就是一个Run的头 Run的数目+1  

        //for (j = 1; j < M; j++) {  
        //    if ((pr[j] != 0) && (pr[j-1] == 0))   //01的模式就是Run  
        //        numRuns++;                        //Run的总数+1  
        //}  
    }  
    *pRunNodeNum = numRuns;  

    //(2) 生成 RunNode信息  
    pNode = (RunNode_t*)malloc(numRuns * sizeof(RunNode_t));  
    k = 0;  
    for (i = 0; i < N; i++)   
    {  
        j = 0;
        while(j < M)
        {
            // 遍历该行
            while(j < M && BW[i][j] == 0)
                j++;

            if ((j < M) && (BW[i][j] != 0))   
            {  
                pNode[k].r = i ;       //  
                pNode[k].sc = j ;  
                while (j < M && BW[i][j] )   //走完这个Run  
                    j++;  
                pNode[k].ec = j-1;  //这个是结尾  
                pNode[k].label = 0;  
                k++;          //处理下一个Run  
            } 
        }
        //pr = &BW[i*M];  //第row行的头指针  

        //j = 0;  
        //while (j < M)   
        //{       
        //    //遍历该行  
        //    while (j < M && pr[j] == 0)  
        //        j++;                        //找到第一个Run所在的行号  

        //    if ((j < M) && (pr[j] != 0))   
        //    {  
        //        pNode[k].r = i ;       //  
        //        pNode[k].sc = j ;  
        //        while (j < M && pr[j] )   //走完这个Run  
        //            j++;  
        //        pNode[k].ec = j-1;  //这个是结尾  
        //        pNode[k].label = 0;  
        //        k++;          //处理下一个Run  
        //    }  
        //}  
    }  

    //(3)扫描标记 ,并统计Label 关系的  
    pEquivList->head = NULL;  
    pEquivList->length = 0;  
    offset = 1;  //八邻域为1  ,四邻域为0  
    for (k = 0; k < numRuns; k++)   
    {  
        if (pNode[k].r == currentRow + 1)   
        {     
            //第k个Run与第k-1个Run在相邻的两行上  
            firstRunOnPreviousRow = firstRunOnThisRow;   //firstRunOnPreviousColumn指向第k-1个Run所在的列的第一个(最上面的)Run  
            firstRunOnThisRow = k;  
            lastRunOnPreviousRow = k-1;  
            currentRow = pNode[k].r;  
        }  
        else if (pNode[k].r > (currentRow + 1))   
        {  
            /* 开始新列:前一列没有Run  直接进入下一轮循环*/  
            firstRunOnPreviousRow = -1;  
            lastRunOnPreviousRow = -1;  
            firstRunOnThisRow = k;  
            currentRow = pNode[k].r;  
        }  

        if (firstRunOnPreviousRow >= 0)   
        {  
            p = firstRunOnPreviousRow;  
            while (p <= lastRunOnPreviousRow && pNode[p].sc <= pNode[k].ec + offset)   
            {  
                if ((pNode[k].ec >= pNode[p].sc-offset) &&   
                    (pNode[k].sc <= pNode[p].ec+offset)) //有交叉  
                {  
                    if (pNode[k].label == 0)   
                    {  
                        pNode[k].label = pNode[p].label;  
                    }  
                    else   
                    {  
                        if (pNode[k].label != pNode[p].label)   
                        {  
                            EquivNode *newNode = (EquivNode *)malloc(sizeof(EquivNode));  
                            newNode->LabelA = pNode[k].label;  
                            newNode->LabelB = pNode[p].label;  
                            newNode->next = pEquivList->head;  
                            pEquivList->head = newNode;  
                            pEquivList->length++;  
                        }  
                    }  
                }  
                p++;  
            }  
        }  

        if (pNode[k].label == 0)   
        {  
            pNode[k].label = nextLabel;  
            nextLabel++;  
        }  
    }  
    *plabels =nextLabel-1;  
    *ppRunNode = pNode;  
    *ppEquivList = pEquivList;  
}  

void MapListAddNode(MapListNode_t* pNode , int Idx)  
{  
    MapListNode_t* pNodeTemp = (MapListNode_t*)malloc(sizeof(MapListNode_t));  
    MapListNode_t* pNodeMove = pNode;  
    pNodeTemp->idx = Idx;  
    pNodeTemp->pNext = NULL;  

    while(pNodeMove->pNext)  
        pNodeMove = pNodeMove->pNext;  

    pNodeMove->pNext = pNodeTemp;  
}  

void MapListListAddNode(MapListListNode_t* pListListNode ,MapListNode_t* pListNode)  
{  
    MapListListNode_t* pListListNodeMove = pListListNode;  
    MapListListNode_t* pListListNodeNew = (MapListListNode_t*)malloc(sizeof(MapListListNode_t));  
    while(pListListNodeMove->pNext)  
        pListListNodeMove = pListListNodeMove->pNext;  

    pListListNodeNew->pMapNodeList = pListNode;  
    pListListNodeNew->pNext = NULL;  
    pListListNodeMove->pNext = pListListNodeNew;  
}  

void MapListListDeleteNode(MapListListNode_t* pListListNode ,MapListNode_t* pListNode)  
{  
    MapListListNode_t* pListListNodeMove = pListListNode;  
    MapListListNode_t* pListListNodeKill = NULL;  
    while(pListListNodeMove->pNext)  
    {  
        if(pListListNodeMove->pNext->pMapNodeList == pListNode)  
        {  
            pListListNodeKill = pListListNodeMove->pNext;  
            pListListNodeMove->pNext = pListListNodeMove->pNext->pNext;  
            free(pListListNodeKill);   
            break;  
        }  
        pListListNodeMove = pListListNodeMove->pNext;  
    }  

}  
int MapListMinIdx(MapListNode_t* pNode)  
{  
    int min = 0x7FFFFFFF;  
    while(pNode)  
    {  
        if(pNode->idx < min)  
            min = pNode->idx;  
        pNode = pNode->pNext;  
    }  
    return min;  
}  
MapListNode_t* MapListListFindIdx(MapListListNode_t* pMapListList ,int Idx)  
{  
    MapListNode_t* pMapListNodeHead = NULL;  
    MapListNode_t* pMapNodeListMove = NULL;  
    MapListListNode_t* pMapListListMove = pMapListList;  
    while(pMapListListMove->pNext)  
    {  
        pMapListListMove = pMapListListMove->pNext;  
        pMapListNodeHead = pMapListListMove->pMapNodeList;  
        pMapNodeListMove = pMapListNodeHead;  
        while(pMapNodeListMove)   
        {  
            if(Idx == pMapNodeListMove->idx)  
                return pMapListNodeHead;  

            pMapNodeListMove = pMapNodeListMove->pNext;  
        }  
    }  
    return NULL;  
}  

void MapListMerge(MapListNode_t* pMapListA , MapListNode_t* pMapListB)  
{  
    while(pMapListA->pNext)  
        pMapListA = pMapListA->pNext;  
    pMapListA->pNext = pMapListB;  
}  


void CreateMapTable(EquivList* pList ,int MapTableSize ,int **ppMapTable )  
{  
    int i,j,k;  
    int labela,labelb;  
    MapListNode_t* pMapNodeList = (MapListNode_t*)malloc(sizeof(MapListNode_t));  
    MapListListNode_t* pMapListListNode = NULL;  
    MapListListNode_t* pMapListListforMove = NULL;  
    MapListNode_t* pMapListforMove = NULL ;  
    int *pMapTableInit = NULL;  
    pMapNodeList->idx = pList->head->LabelA;     
    pMapNodeList->pNext = NULL;  
    MapListAddNode(pMapNodeList,pList->head->LabelB);  

    DeleteEquivListHeadNode(pList);  

    pMapListListNode = (MapListListNode_t*)malloc(sizeof(MapListListNode_t));  
    pMapListListNode->pMapNodeList = NULL;  
    pMapListListNode->pNext = NULL;  
    MapListListAddNode(pMapListListNode,pMapNodeList);  

    while(pList->length)  
    {  
        MapListNode_t* pMapListFindA = NULL;  
        MapListNode_t* pMapListFindB = NULL;  
        labela = pList->head->LabelA;  
        labelb = pList->head->LabelB;  
        pMapListFindA = MapListListFindIdx(pMapListListNode,labela);  
        pMapListFindB = MapListListFindIdx(pMapListListNode,labelb);  

        if(pMapListFindA)  
        {  
            if(pMapListFindB)  
            {  
                if (pMapListFindA!=pMapListFindB)  
                {             
                    MapListMerge(pMapListFindA,pMapListFindB);  
                    MapListListDeleteNode(pMapListListNode,pMapListFindB);  
                }  
            }  
            else  
            {  
                MapListAddNode(pMapListFindA,labelb);  
            }  
        }  
        else  
        {  
            if(pMapListFindB)  
            {  
                MapListAddNode(pMapListFindB,labela);  
            }  
            else  
            {  
                pMapNodeList = (MapListNode_t*)malloc(sizeof(MapListNode_t));  
                pMapNodeList->pNext = NULL;  
                pMapNodeList->idx = labela;  
                MapListAddNode(pMapNodeList,labelb);  
                MapListListAddNode(pMapListListNode,pMapNodeList);  
            }  
        }  
        DeleteEquivListHeadNode(pList);  
    }  

    pMapListListforMove = pMapListListNode;  
    while (pMapListListforMove->pNext)  
    {  
        pMapListforMove = pMapListListforMove->pNext->pMapNodeList;  
        while(pMapListforMove)  
        {   
            pMapListforMove = pMapListforMove->pNext;  
        }  
        pMapListListforMove = pMapListListforMove->pNext;  
    }  

    pMapTableInit = (int*)malloc(MapTableSize*sizeof(int)); 
    for(i = 1 ; i <= MapTableSize ; i++ )  
    {  
        pMapListforMove = MapListListFindIdx(pMapListListNode,i);  
        if(pMapListforMove)  
        {  
            pMapTableInit[i-1] = MapListMinIdx(pMapListforMove); 
        }  
        else  
        {  
            pMapTableInit[i-1] = i; 
        }  
    }  

    *ppMapTable = (int*)malloc(MapTableSize*sizeof(int));  
    (*ppMapTable)[0] = 1;   
    k = 2;  
    for(i = 1 ; i < MapTableSize ; i++ )  
    {  
        j = 0;  

        while(j<i)  
        {  
            if(pMapTableInit[j] == pMapTableInit[i])  
            {  
                (*ppMapTable)[i] = (*ppMapTable)[j];  
                break;  
            }  
            j++;  
        }  

        if(j == i)  
            (*ppMapTable)[i] = k++;    
    }  
}  

void BWCreateRunNodeInfo(vector< vector<int> > &BW , int M ,int N ,  
                         SparseInfoExtractCondition_t* pCondtion,  
                         RunNode_t** ppRunNode, int *pRunNodeNum)  
{  
    EquivList* pEquivList = NULL;  
    int *pMapTable = NULL;  
    int labels = 0;  
    BWCreateRunNodeInfoEx(BW ,M ,N ,pCondtion,ppRunNode, pRunNodeNum,&labels ,&pEquivList);  

    if(pEquivList->length)  
    {  
        CreateMapTable( pEquivList, labels,&pMapTable);  
        UpdateRunNode(pMapTable,*ppRunNode,*pRunNodeNum);  
    }  
}  

void UpadateBWData(vector< vector<int> > &BW, int M ,RunNode_t* pNode , int NodeNum)  
{  
    int k = 0 , p = 0;  
    for (k = 0; k < NodeNum; k++)   
    {  
        for (p = 0; p < pNode[k].ec - pNode[k].sc + 1; p++)  
            BW[ pNode[k].r][ pNode[k].sc + p] = pNode[k].label;  
    }
}   

vector< vector<int> > bwlabel(vector< vector<int> > &BW, int N, int M)
{  
    int i = 0, j = 0;  
    RunNode_t* pRunNode = NULL;  
    int RunNum = 0;  
    SparseInfoExtractCondition_t ExtractCondition;  

    ExtractCondition.minarea = 10;  
    ExtractCondition.minpixDiff = 10;  
    ExtractCondition.mode = 1;  
    BWCreateRunNodeInfo(BW ,M ,N ,&ExtractCondition, &pRunNode, &RunNum);  

    //(4)根据统计表建立,映射关系表  
    UpadateBWData(BW, M, pRunNode, RunNum);  

    return BW;
}  

void testBwlabel()
{
    int BW1[][4] = 
    {
        {1, 1, 0, 0},
        {1, 0, 0, 0},
        {1, 0, 0, 1},
        {1, 0, 0, 0},
        {1, 1, 0, 0},
    };

    vector< vector<int> > BW(5, vector<int>(4));

    for(int i=0; i<5; i++)
        for(int j=0; j<4; j++)
            BW[i][j] = BW1[i][j];

    vector< vector<int> > label = bwlabel(BW, 5, 4);
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<4; j++)
            printf("%d ", label[i][j]);
        printf("\n");
    }
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值