#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 = 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 = 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"); }
参考资料:
(1) 稀疏信息提取:读Matlab7.7 IPT的bwlabel函数(一)——bwlabel1的Python描述 http://blog.sina.com.cn/s/blog_4513dde60100o6oz.html
(2) MATLAB 使用的bwlabel1.c http://code.google.com/p/mirone/source/browse/trunk/mex/bwlabel1.c?spec=svn1874&r=1874
(3) 连通关系合并 http://blog.csdn.net/caiqi1123/article/details/7101168