Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ch.11. 이진영상처리를 이용한 영상인식.

Similar presentations


Presentation on theme: "Ch.11. 이진영상처리를 이용한 영상인식."— Presentation transcript:

1 Ch.11. 이진영상처리를 이용한 영상인식

2 영상인식 영상인식 물체분할 (Segmentation) 카메라로부터 입력된 영상신호를 해석하여, 물체를 분할하고 특징을 추출
배경(background) 에서 특정 물체 (object) 를 추출

3 영상이진화에 의한 물체인식 (입력영상) (이치화영상) (라벨링된 영상) (분할영상)

4 영상 라벨링 Labeling 인접하여 연결되어 있는 모든 화소에 동일한 번호(label) 을 붙이고, 다른 연결 성분에는 또 다른 번호를 붙이는 작업 (이치화 영상) (라벨링된 영상)

5 영상 라벨링 픽셀의 인접성 (neighborhood) (1) (2) x (0) (3) (3) (2) (1) (4) x (0)
(a) 4-근방 화소들 (b) 8-근방 화소들 (1) (2) x (0) (3) (3) (2) (1) (4) x (0) (5) (6) (7)

6 영상 라벨링 Grassfire 알고리즘 시작 라벨링 중심이동 라벨링 중심이동 라벨링 중심이동 라벨링

7 영상 라벨링 재귀호출 방법 void CWinTestDoc::grass_label(int height, int width) { // 라벨링된 영상을 저장하기 위한 배열의 메모리 할당 short *coloring = new short [height*width]; int i, j, curColor=0; for(i=0; i<height*width; i++) coloring[i]=0; // 입력 영상의 라벨링 for(i=0; i<height; i++) for(j=0; j<width; j++) if(m_InImg[i][j]==255 && coloring[i*width+j]==0) curColor++; grass(coloring, height,width,i,j,curColor); } float grayGap = 250.0f/(float)curColor; // 라벨링된 데이터를 m_OutImg배열을 이용하여 화면출력 int value = (int)(coloring[i*width+j]*grayGap); if(value==0) m_OutImg[i][j] = 255; else m_OutImg[i][j] = value; delete []coloring; // 메모리 해제 void CWinTestDoc::grass(short *coloring, int height, int width, int i, int j, int curColor) { int k, l, index; for(k=i-1; k<=i+1; k++) for(l=j-1; l<=j+1; l++) // 영상의 경계를 벗어나면 라벨링하지 않음 if(k<0 || k>=height || l<0 || l>=width) continue; index = k*width+l; // 아직 방문하지 않은 픽셀이고 값이 255라면 라벨링함 if(m_InImg[k][l]==255 && coloring[index]==0) coloring[index] = curColor; grass(coloring,height,width,k,l,curColor); }

8 영상 라벨링 반복법: Stack 사용 void CWinTestDoc::m_BlobColoring(int height, int width) { // 스택으로 사용할 메모리할당 short* stackx=new short [height*width]; short* stacky=new short [height*width]; ………. for(i=0; i<height; i++) for(j=0; j<width; j++) // 이미 방문한 점이거나 픽셀값이 255가 아니라면 처리안함 if(coloring[i*width+j]!=0 || m_InImg[i][j]!=255) continue; r=i; c=j; top=0; area=1; curColor++; while(1) { GRASSFIRE: for(m=r-1; m<=r+1; m++) for(n=c-1; n<=c+1; n++) if(m<0 || m>=height || n<0 || n>=width) continue; if((int)m_InImg[m][n]==255 && coloring[m*width+n]==0) coloring[m*width+n]=curColor; // 현재 라벨로 마크 if(push(stackx,stacky,(short)m,(short)n,&top)==-1) continue; r=m; c=n; area++; goto GRASSFIRE; } if(pop(stackx,stacky,&r,&c,&top)==-1) break; ……

9 영상 라벨링 실행 예

10 영상 경계의 추적 Edge Following
이진화된 영상 또는 라벨링된 영상에서 영역의 경계를 추적하여 경계픽셀의 순서화된 정보 (chain code) 추출 물체의 기하학적 특징 추출에 사용 (원 영상) (이치화 영상) (경계 영상)

11 영상 경계의 추척 Edge Following 단계 주위 픽셀번호 탐색순서 4→5 → 6 → … → 3 scan
n’ = (n+5) & 7 n: 현 벡터 번호 n’: 차기 시작 벡터 번호

12 영상경계의 추적 void CWinTestDoc::m_BorderFollow(int height, int width) {
// 관심점 주위에서 같은 칼라를 가진 경계점을 찾기 위함 for(k=0; k < 8; k++, n=((n+1) & 7)) // { // short u = (short)(x + nei[n].x); short v = (short)(y + nei[n].y); if(u<0 || u>=height || v<0 || v>=width) continue; if(m_InImg[u][v]==c0) break; // 관심점의 주위를 돌다가 같은 밝기의 // 경계를 만나면 다음으로 추적할 점이 됨 } if(k == 8) break; // isolated point occurs visited[x*width+y]=255; // 방문한 점으로 마크 xchain[border_count]=x; ychain[border_count++]=y; if(border_count>=10000) break; x = x + nei[n].x; y = y + nei[n].y; if(n%2==1) diagonal_count++; // n = (n + 5) & 7; // while(!(x == x0 && y == y0)); if (k == 8) continue; // isolated point occurs // 경계정보를 저장 if(border_count<10) continue; // 너무작은 영역의 경계이면 무시한다. stBorderInfo[numberBorder].x=new short [border_count]; stBorderInfo[numberBorder].y=new short [border_count]; for(k=0; k<border_count; k++) stBorderInfo[numberBorder].x[k]=xchain[k]; stBorderInfo[numberBorder].y[k]=ychain[k]; stBorderInfo[numberBorder].n=border_count; stBorderInfo[numberBorder++].dn=diagonal_count; if(numberBorder>= 1000) break; void CWinTestDoc::m_BorderFollow(int height, int width) { // 영역의 경계정보를 저장하기 위한 구조체 메모리 typedef struct tagBORDERINFO{ short *x,*y; short n, dn; } BORDERINFO; BORDERINFO stBorderInfo[1000]; // 영상에 있는 픽셀이 방문된 점인지를 마크하기 위해 영상 메모리 할당 unsigned char *visited = new unsigned char [height*width]; memset(visited,0,height*width*sizeof(char)); // 메모리 초기화 // 추적점을 임시로 저장하기 위한 메모리 short *xchain = new short [10000]; short *ychain = new short [10000]; // 관심 픽셀의 시계방향으로 주위점을 나타내기 위한 좌표 설정 const POINT nei[8] = // clockwise neighbors {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1} }; for(x=1; x < height; x++) for(y=1; y < width; y++) c0=m_InImg[x][y]; c1=m_InImg[x-1][y]; if(c0!=c1&&c0==(unsigned char)255 && visited[x*width+y]==0 ) //c0!=c1(경계이고) border_count=0; // 경계점의 갯수를 세기 위한 카운터 diagonal_count=0; // x0 = x; y0 = y; n = 4;

13 영상경계의 추적 실행 예

14 기하학적 특징 추출 면적 무게중심 경계길이 원형도 Area (i) : 라벨링된 영상 내에서 라벨 I 와 같은 픽셀의 수
경계영상의 픽셀 수 카운트 원형도

15 기하학적 특징 추출 종류 원 정사각형 삼각형 면적(pixels) 5819 6725 5487 주위길이(pixels) 282
324 349 원형도 0.92 0.80 0.57

16 실습 [리소스] IDM_BIN_LABELING [클래스 마법사]

17 [WinTestView.cpp] [WinTestDoc.h] void CWinTestView::OnBinLabeling() {
// TODO: Add your command handler code here CWinTestDoc* pDoc = GetDocument(); // 다큐멘트 클래스를 참조하기 위해 ASSERT_VALID(pDoc); // 인스턴스 주소를 가져옴 // 도큐멘트 클래스에 있는 재귀라벨링 함수 호출 pDoc->grass_label(256, 256); Invalidate(FALSE); //화면 갱신 } [WinTestDoc.h] public: void grass(short* coloring,int height,int width,int i, int j,int curColor); void grass_label(int height, int width);

18 [WinTestDoc.cpp] void CWinTestDoc::grass_label(int height, int width)
{ // 라벨링된 영상을 저장하기 위한 배열의 메모리 할당 short *coloring = new short [height*width]; int i, j, curColor=0; for(i=0; i<height*width; i++) coloring[i]=0; // 입력 영상의 라벨링 for(i=0; i<height; i++) for(j=0; j<width; j++) if(m_InImg[i][j]==255 && coloring[i*width+j]==0) curColor++; m_BlobPixelSum =0; grass(coloring,height,width,i,j,curColor); } float grayGap = 250.0f/(float)curColor; // 라벨링된 데이터를 m_OutImg배열을 이용하여 화면출력 int value = (int)(coloring[i*width+j]*grayGap); if(value==0) m_OutImg[i][j] = 255; else m_OutImg[i][j] = value; delete []coloring; // 메모리 해제 void CWinTestDoc::grass(short *coloring,int height,int width,int i, int j,int curColor) { int k, l, index; for(k=i-1; k<=i+1; k++) for(l=j-1; l<=j+1; l++) // 영상의 경계를 벗어나면 라벨링하지 않음 if(k<0 || k>=height || l<0 || l>=width) continue; index = k*width+l; // 아직 방문하지 않은 픽셀이고 값이 255라면 라벨링함 if(m_InImg[k][l]==255 && coloring[index]==0) coloring[index] = curColor; m_BlobPixelSum++; grass(coloring,height,width,k,l,curColor); }

19 연습문제

20 연습문제


Download ppt "Ch.11. 이진영상처리를 이용한 영상인식."

Similar presentations


Ads by Google