OpenCV의 Mat Format을 사용한 Source Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | void extractMainLabel(Mat input, int row, int col) { int x, y, top; short l_no = 0, r, c, m, n; unsigned char *m_ResultImg; m_ResultImg = (unsigned char*)malloc(sizeof(unsigned char)*row*col); unsigned char *arr; arr = (unsigned char*)malloc(sizeof(unsigned char)*row*col); // 스택으로 사용할 메모리 할당 short *stack_x; short *stack_y; stack_x = (short *)malloc(sizeof(short)*row*col); stack_y = (short *)malloc(sizeof(short)*row*col); // 속도개선을 위하여 배열에 Mat Pixel 값을 복사 for( y = 0 ; y < row ; y ++ ){ for( x = 0 ; x < col ; x++ ){ *(arr+(col*y)+x) = input.at<uchar>(y,x); } } // 결과 이미지 배열 초기화 for(y=0; y<row; y++){ for(x=0; x<col; x++) *(m_ResultImg+(col*y)+x) = 0; } for(y=0; y<row; y++){ for(x=0; x<col; x++) { // 이미 방문한 점이거나 픽셀값이 255가 아니면처리하지 않음 if(*(arr+(col*y)+x) != 255 ||*(m_ResultImg+(col*y)+x) != 0) continue; r=y; c=x; top=0; l_no++; while(1){ for(m=r-1; m<=r+1; m++){ if(m<0 || m>row-1) continue; for(n=c-1; n<=c+1; n++){ if(n<0 || n>col-1) continue; if(*(arr+(col*m)+n) != 255 || *(m_ResultImg+(col*m)+n) != 0) continue; // l_no: Labeling Number(Label Key) *(m_ResultImg+(col*m)+n) = (unsigned char)l_no; if(Push(stack_x, stack_y, m, n, &top) == -1) continue; } } if(Pop(stack_x, stack_y, &r, &c, &top) == -1) break; } } } //**************** 수정부분 시작 int max_ln = 0; // 가장 많은 픽셀을 갖고 있는 Labeling number int* max_px; max_px = new int[(int)l_no+1]; for(int i = 0 ; i <= l_no ; i ++){ max_px[i] = 0; } // Labeling Pixel 저장 for(y=0; y<row; y++){ for(x=0; x<col; x++){ if(*(m_ResultImg+(col*y)+x) == 0) continue; max_px[*(m_ResultImg+(col*y)+x)]++; } } // 가장 큰 Label Number 저장 for( int i = 1; i < l_no - 1 ; i ++ ){ if(max_px[max_ln] < max_px[i]) max_ln = i; } // 가장 큰 영역을 남기고 제거(가장 큰 영역은 흰색으로) for(y=0; y<row; y++){ for(x=0; x<col; x++){ if(*(m_ResultImg+(col*y)+x) == 0) continue; if(*(m_ResultImg+(col*y)+x) == max_ln) *(m_ResultImg+(col*y)+x) = 255; else *(m_ResultImg+(col*y)+x) = 0; } } delete[] max_px; //**************** 수정부분 종료 // Labeling Number로 나누어 색 변환 /*float l_gap = 250.0f / (float)l_no; for(y=0; y<row; y++){ for(x=0; x<col; x++){ *(m_ResultImg+(col*y)+x) *= (unsigned char)l_gap; } }*/ for( y = 0 ; y < row ; y ++ ){ for( x = 0 ; x < col ; x++ ){ input.at<uchar>(y,x) = *(m_ResultImg+(col*y)+x); } } free(arr); free(m_ResultImg); free(stack_x); free(stack_y); } |
Stack overflow 방지를 위한 Stack 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | int Push(short* st_x, short* st_y, short xx, short yy, int* top) { if(*top>=65536) return(-1); (*top)++; st_x[*top] = xx; st_y[*top] = yy; return(1); } int Pop(short* st_x, short* st_y, short* xx, short* yy, int* top) { if(*top == 0) return(-1); *xx = st_x[*top]; *yy = st_y[*top]; (*top)--; return(1); } |
728x90
반응형
'Programming > Image Processing' 카테고리의 다른 글
[OpenCV] 가장 긴 직선의 각도를 반환하는 함수(소스코드) (0) | 2014.02.21 |
---|---|
[OpenCV] 이미지 로드 + 출력예제 소스코드 (0) | 2014.02.08 |
[OpenCV] 2.4 이상 버전에서 SIFT + SURF 사용 설정 (3) | 2014.01.27 |
[OpenCV] Labeling(레이블링, 라벨링) 이론 및 소스코드 (3) | 2014.01.14 |
배열접근방식 세선화(Thinning) 함수 소스코드 (0) | 2014.01.13 |