컴퓨터비전 HandGR

강준호·2023년 3월 22일
0

컴퓨터비전

목록 보기
1/4

그레이 스케일

  • 0(검은색)에서 255(흰색)
  • 데이터의 양을 줄여 분석을 단순화

2D 손 제스처 인식 절차

1. 분할(Binarization)

  • 정확하게 손모양 추출
  • 임계값 기법을 사용하여 입력 영상을 이진 영상으로 변환하여 배경과 손 제스처 영역을 분리합니다.

Otsu’s segmentation algorithm

  • 이진화를 위한 최적의 임계값을 결정 후에 임계값을 얻어 segment 과정에서 처리

  • 경계값을 임의로 정해서 픽셀들을 두 부류로 나누고

  • 두 부류의 명암 분포를 반복해서 구한 다음

  • 두 부류의 명암 분포를 가장 균일하게 하는 경게 값을 선택

  • threshold를 T라 하면, T를 기준으로 이진 분류된 픽셀의 비율의 차가 가장 작은 optimal T를 구하는 것

알고리즘 단계

  1. 그레이스케일 이미지의 히스토그램을 계산합니다. 각 강도 수준(0에서 L-1까지, 여기서 L은 일반적으로 8비트 이미지의 경우 256)에 대해 해당 강도의 픽셀 수를 결정합니다. => 히스토그램 계산을 통해 이미지의 픽셀 강도 분포에 대한 정보를 얻을 수 있음

  2. 히스토그램 정규화: 히스토그램 값을 이미지의 총 픽셀 수로 나누어 각 강도 수준 i에 대한 확률 분포 p(i)를 생성합니다.

  1. 임계값 T를 사용하여 두 클래스를 정의합니다.

배경 클래스(0 = 검정): {0, 1, ..., T}
포그라운드 클래스(1 = 흰색): {T+1, T+2, ..., L-1}

  1. 각 클래스의 확률을 계산합니다.

배경 클래스 확률: P1(T) = sum(p(i)) for i = 0 to T
포그라운드 클래스 확률: P2(T) = sum(p(i)) for i = T+1 to L-1

  1. 각 클래스의 평균 강도 수준을 계산합니다.

배경 클래스 평균: m1(T) = sum(i p(i)) / P1(T) for i = 0 to T
포그라운드 클래스 평균: m2(T) = sum(i
p(i)) / P2(T) for i = T+1 to L-1

  1. 각 강도 수준 T에 대해 해당 강도 수준에서 분리될 때 두 클래스가 얼마나 다른지에 대한 척도인 클래스 간 분산을 계산합니다.

σ²B(T) = [m(T) * P(T) - M(G)]² / [P(T) * (1 - P(T))]

여기서 m(T)는 누적 평균, P(T)는 누적 합계, M(G)는 전체 평균입니다.

variance = weight0 weight1 (mean0 / weight0 - mean1 / weight1)

  • (mean0 / weight0 - mean1 / weight1);
  • weight0 * weight1: 두 클래스의 확률을 곱한 값으로, 정규화 인자 역할을 하며 클래스 간의 상대적인 크기에 따라 클래스 간 분산에 가중치를 부여합니다.

  • (mean0 / weight0 - mean1 / weight1) * (mean0 / weight0 - mean1 / weight1): 두 클래스의 평균 강도 값 사이의 차이 제곱으로 강도 측면에서 클래스 간의 거리를 나타냅니다.

  1. 클래스 간 분산을 최대화하는 최적의 임계값 T*를 찾습니다.

T* = argmax(σ²B(T)) for T = 0 ~ L-1

  • otsu의 임계값 방법에서 분산이 크면 이미지의 전경 영역과 배경 영역을 효과적으로 구분하여 보다 정확한 이진화가 된다.

Segmented(분할된) image

  • 임계값을 이용해 이진화의 결과를 도출!

1=hand pixel, 0 : background pixel

for (i = 0; i < img. rows; ++i)
	for (j = 0; j < img.cols; ++j)
if (img[i][j] < T) oImg[i][j] = 0;
else oImg[i][j] = 1; //255

// 이진 그림으로 바꾸는

2. Filtering(Morphological operator)

  • 침식, 확장, 열기 또는 닫기와 같은 형태학적 작업을 적용하여 분할된 이미지에서 배경 및 개체 노이즈를 제거합니다.

침식

  • 개체의 경계(전경)을 축소
  • 큰 물체의 경계에서 작은 물체, 간격 및 불규칙성을 제거

(A ⊖ B) = {p | B_p ⊆ A}

  • 이미지 A에서 구조 요소 B를 제거하여 축소

  • 입력 이미지의 3x3 영역 내의 모든 값이 1이면, 중앙 픽셀의 출력 값을 1로 설정합니다. 그렇지 않으면 0으로 설정합니다.

확장

  • 개체의 경계(전경)을 확대.

  • 경계의 작은 틈, 구멍 및 불규칙성을 채움

  • (A ⊕ B) = {p | B_p ∩ A ≠ ∅}

=> 이미지 A에 구조 요소 B를 추가하여 이미지를 확장

열기

  • 입력 이미지에 침식을 적용한 다음, 침식된 이미지에 팽창을 적용

  • 모양을 유지하며 노이즈와 작은 아티팩트를 제거

닫기

  • 입력 이미지에 확장을 적용한 다음, 확장된 이미지에 침식을 적용

  • 모양을 유지하며 노이즈와 작은 아티팩트를 채움

opening & closing

3. 인식할 영역 선택(Labeling)

바이너리 이미지에서 손 영역과 같은 연결된 구성 요소를 식별하고 레이블을 지정합니다.

4. 특징 추출(Contour)

  • 손 모양을 표현하기 위해 손 영역의 윤곽 또는 경계를 추출합니다.

5. 분류(인식)

  • 추출된 윤곽선과 10개의 손 모양의 기준 윤곽선을 유사성 측정을 통해 비교합니다. DTW(Dynamic Time Warping) 또는 SDTW(Statistical DTW)와 같은 선형 정렬 및 비선형 정렬 방법을 사용하여 등고선 시퀀스 간의 유사성을 측정할 수 있습니다.

HandGR 목표 시스템 환경 제약조건

한개의 사각형이 가질 수 있는값.

-RGB => 각각은 8 비트. RGB 해서 24비트니까.
8비트 하나는 0~155.

총 화소의 숫자는

컬러는 256 ^3

그레이 스케일은 256으로 줄어. => rgb 값이 다 똑같거든

인식 대상

그레이 스케일 수식

for (y =0; y<H; y++){
	for(x =0; x<w; x++){
		g[y][x] = (I[y][x]r + I[y][x]g + I[y][x]b /3) //이게 그레이 스케일 수식
		(h[g[y][x]]++;) #  **히스토 그램 만들려면 한줄 들어가면 된다**        
        if (g[y][x] >TH) #
        	O[y][x] =1;
        else
        	O[y][x] =0;
        
	}
}
`

TH 값을 얼마나 줄것인가..!

히스토그램

  • long h[256] = 0;

256
입력영상이 g 일때

h[g[y][x]]++;

g[0][0] 인 값은 1인데 이걸 증가.

히스토그램 그래프

0 값이 어둡고 255에 가까울 수록 밝은거

0~255 그래프 중 좌우측 임계값은 사진 찍을때마다 달라져.

  • 그라디언트 디센트 메소드, 힐클라이밍 => 경사를 이용한 임계점 찾기.

임계값 산출

  • 분산구하기야.

max 와 argmax 를 구분해야해.

M = max(i=0~255) R[i]; 256의 데이터 중 맥스값을 찾아 이게 M

A = argmax 인덱스

Max = 0;
for(i=0; i<256; i++)
	(h[i] = h[i] /(x_size+y_size)) //히스토그램 정규화. 어떤 단위 순자로 나눠.저걸 더하면 1이야
	if (R[i] > Max)
    	Max = R[i]
        A=i;

mt = 0;
mt = i+mt[i]

1 보다 작으면 백그라운드. 255는 있어야함으로 254까지 가.

for(t =0; t<256; t++)
	R[t] = w0(m0-mt)^2 + w1(m1-mt)^2

0, 255 임계값 안쓸꺼여서. 1~254야

임계값보다 작으면 0으로,

나올 수 있는 경우가 (256)^3 에서 (2) 111 or 000 으로 바뀜.

  • 바이너리에서 저거 지우는법.
  1. 곧바로 레이블링 해서 영역 숫자가 작은걸 버리기
  2. 잡음 처리 알고리즘

2번 알고리즘

입력 배열과 출력배열을 다르게 해야해.
1번 내 주변 3x3이 전부 오브젝트가 아니면 0으로 출력이 나가. 맞으면 1로.
2번 이번에는 거꾸로, 내가 오브젝트 이면, 3x3 전부를 오브젝트로 출력해.

=> 3x3 이 안되는 작은 짜투리(잡음)는 제외하게돼.

짝수를 쓰면 균형이 안맞아서 홀수를 써.

B[][]
for y=
	for x=
    	if (B[x][x] ==1)

OPEN

3x3 알고리즘으로 돌리면 OPEN 결과처럼됨

CLOSE

반대로 한개만 있어도 3x3 채우면 비어있던것도 채워짐.

수식으로 표현한것.

0개의 댓글