핸드 트래킹을 통해 손의 제스쳐를 이용해 컴퓨터를 제어할 수 있는 프로그램제작을 위한 예광탄을 만들었다.
RGB 컬러모델을 HSV로 변환하여 피부영역을 구하고, 해당 피부영역의 최대 면적의 영역을 남긴다. 해당 영역의 윤곽을 구하고 영역 중의 가장 긴 부분을 손가락으로 판정하였으며, 판정 결과 오차와 정확한 손가락 검출이 불가능하여 손의 무게중심을 이용하는 방법으로 테스트 해봐야 할 것 같다.
플러드필은 영상에서 특정 영역을 고립시키거나 구분할 때 사용되는 기능이며, 영상 처리 및 영상 분석 등의 전처리 과정으로 널리 사용된다. 플러드필은 입력 영상으로부터 마스크를 만드는 용도로 사용될 수 있는데, 이러한 마스크는 추후 제한된 영역에서만 연산을 수행하도록 하여 전체 연산 속도를 향살시키는 용도로 사용될 수 있다.마스트는 Cv.FloodFill() 함수의인자로도사용될수있으며, 이경우채우기가완료된곳을제어하는용도로사용된다.
첫 번째 인자 image는 입력 영상이며, 8비트 또는 실수형이고, 1또는 3채널 영상이다. 플러드필은 씨앗점에서 시작하고, 추후 선택된 영역은 newVal값으로 색칠한다. 특정 픽셀값이 이미 색칠되어 있는 이웃 픽셀의 밝기값에서 lo_diff를 뺀 값보다 같거나 크고, up_Diff를 더한 값보다는 같거나 작을 경우, 이 픽셀을 newVal 값으로 색칠한다. 만약flags 인자에 CV_FLOODFILL_FIXED_RANGE 값이 포함되어 있따면, 인접한 이웃 픽셀과 값을 비교하지 않고 씨앗점의 픽셀값과 비교한다. comp인자가 null이 아니면, 채워진 영역에 대한 통계 정보를 담고 있는 CvConnectedComp 구조체를 가리킨다.
씨앗점으로 (흰색)지정
mask 인자는 cvFloodFill() 함수의 입력으로도 작용하고, 출력으로도 사용된다. 입력으로 사용될 경우에는 채우기가 적용될 영역을 제한하는 역할을 담당하고, 출력으로 사용될 경우에는 실제 채워진 영역을 가리키는 용도로 사용된다. Mask가 null이 아니라면, 입력 영상보다 가로, 세로 방향으로 2픽셀 더 큰, 8비트 1채널 영상이어야 한다. 입력영상보다 큰 영상으로 mask를 설정하는 이유는 내부 작업을 쉽고 빠르게 수행하기 위함이다. Mask 영상에서(x+1,y+1)위치의 픽셀은 입력 영상의 (x,y)좌표의 픽셀과 대응된다. Flags의 하위 8비트는 4또는 8값을 가질 수 있다. 이 값은 채우기 알고리즘에서 연결성을 제어하는 용도로 사용된다. 이 값이 8이면, 양쪽 대각선 방향으로 인접한 픽셀들도 이웃 픽셀로 간주도니다. 상위 8비트(16~23)는 CV_FLOODFILL_FIXED_RANGE 또는 CV_FLOODFILL_MASK_ONLY 값을 가질 수 있다. CV_FLOODFILL_FIXED_RANGE가 설정되면, 채우기 알고리즘에서 이웃 픽셀의 값과 비교하는 대신 씨앗점 픽셀값과 비교한다. CV_FLOODFILL_MASK_ ONLY가 설정되면 원본 영상에 채우기 결과를 설정하는 대신mask 영상에만 결과를 표현한다. CV_FLOODFILL_MASK_ONLY를 설정하는 경우 반드시 mask 인자값을 설정해 주어야 한다.
열기와 닫기 연산은 침식과 팽창 연산을 조합하여 사용함으로써 이루어진다. 열기 연산의 경우, 침식 연산을 수행한 후 팽창 연산을 수행한다. 열기 연산은 종종 이진 영상에서 독립된 영역들의 개수를 세기 위해서 사용된다. 예를 들어, 현미경으로 관찰한 세포 영상을 임계값을 이용하여 이진화한 후, 열기 연산을 수행하여 가까이 붙어 있는 세포들을 서로 떨어뜨리려 놓고 나서 세포의 수를 세곤 한다. 닫기 연산은 팽창을 먼저 하고 침식 연산을 수행한다. 닫기 연산은 연결된 구성 요소 알고리즘 등에서 잡음에 의한 원치 않은 분할을 최소한으로 줄이고자 사용한다. 연결된 구성 요소 레이블링을 수행하기 위해 보통 침식 또는 닫기 연산을 수행하여 잡음을 먼저 제거하고, 열기 연산을 수행하여 다시 가까이 인접한 큰 영역들을 합쳐준다. 열기 또는 닫기 연산의 결과는 침식 또는 팽창 연산의 결과와 유사하지만, 열기 및 닫기 연산이 연결된 영역을 보다 정확하게 보존해준다.
IplImage tempimage = src.Clone();
IplConvKernel element = Cv.CreateStructuringElementEx(3,3, 2, 2, ElementShape.Rect, null);
모폴로지 열기 연산의 결과, 작은 크기의 밝은 영역은 사라지고, 남아 있는 밝은 역역의 크기는 유지된채 고립되어 있다.
모폴로지 닫기 연산의 결과, 밝은 영역들이 서로 합쳐졌지만 기본 크기는 유지하고 있다.
Iterations에 2를 전달하여 닫기 연산을 두 번 수행하는 것은 팽창-침식-팽창-침식 연산을 수행하는 것 같은 효과를 나타낸다. 그러나 이러한 연산은 그다지 유용하지 않다. 보통의 경우, 팽창-팽창-침식-침식 같은 연산을 원할 것이다. 팽창-팽창-침식-침식과 같은 방식으로 모폴로지 연산을 수행해야 팽창-침식을 한 번 수행하는 것보다 더 큰 잡을을 제거하는 효과가 있다.
모폴로지 그래디언트
이 연산을 이진 영상에 적용하면 영역의 외곽선만 남기는 효과가 있다.
Gradient(src) = dilate(src) - erdoe(src)
모폴로지 그래디언트 연산의 결과. 주변부 엣지가 밝게 표현된다.
그래이스케일 영상에 대한 모폴로지 그래디언트 연산 결과는 영상에서 밝기값 변화량의 정도를 알려준다. 모폴로지 그래디언트는 밝은 영역 주위를 고립시켜서 이를 하나의 객체로써 다룰 수 있도록 해준다. 영역의 완전한 외곽선은 확정된 영역으로부터 수축된 영역을 빼는 차연산을 통해 쉽게 구할 수 있다. 이는 객체의 그래디언트를 계산 하는 것과는 다르다.(그래디언트 관한 소벨, 샤르 연산)
탑-햇 연산과 블랙-햇 연산
이들 연산은 주변보다 밝거나 어두운 영역을 고립시키는 효과가 있기 때문에 특정 객체 내부에서 밝기 변화가 두드러진 부분을 찾아내기 위해 사용된다. 예를 들어, 생체조직 또는 세포를 촬영한 현미경 영상을 다룰 때 사용되기도 한다.
TopHat(src) = src - open(src)
BlackHat(src) = close(src) - src
탑-햇 연산은 입력 영상에서 열기 연산이 수행된 영상을 빼는 연산이다. 열기 연산은 영상에서 밝기값이 크게 튀는 작은 덩어리를 제거하는 효과가 있다. 그러므로 src에서open(src)를 빼게 되면 결과적으로 원본 src영상에서 주변보다 밝았던 부분만 남아서 강조되어 보인다. 이러한 효과는 커널의 크기에 의존적이다. 이와 반대로 블랙-햇 연산은 원본 영상에서 주변보다 어두운 영역만 강조한다.
OpenCV에서는 IplConvKernel 구조체를 사용하여 자체적인 모폴로지 커널을 사용할 수 있다. 이 커널은 Cv.CreateStructuringElementEx()함수를 통해서 생성하고,ReleaseStructuringElement() 함수를이용하여해제한다.
publicstaticIplConvKernel CreateStructuringElementEx(int cols, int rows, int anchor_x, int anchor_y, ElementShape shape, int[,] values);
모폴로지 커널은 컨볼루션 커널과 달리 수치값을 필요로 하지 않는다. 모폴로지 커널의 모양은 커널이 영상을 스캔하는 동안 최대값 또는 최소값 계산에 필요한 픽셀 위치를 알려주는 역할만 할 뿐이다. 고정점은 커널이 원본 영상에 어떻게 정렬되어야 하는지 알려주는 역할을 하고, 또한 모폴로지 연산의 결과값이 원본 영상의 어느 픽셀에 대입되어야 하는지 알려준다. 커널을 새로 생성하려면 구성요소를 감싸는 사각형을 표현하는 cols와 rows를 지정해주어야 한다. 그 다음으로 고정점의 좌표 (x,y)를 나타내는 anchor_x와anchor_y를 지정한다. CV_SHAPE_CUSTOM 값이 사용되면 정수형 배열 values에 의해 지정된 형태의 커널이 생성된다. 이 배열은 rows x cols 크기의 1차원 배열이며 0이 아닌 값으로 지정된 위치의 원소는 커널에서 사용되는 픽셀이다. Values가 null이면 모든 원소값이 0이 아닌 것으로 간주되어 사각형 형태의 커널이 생성된다.
OpenCV는 빠르고 사용하기 쉬운 영상의 모폴로지 변환을 제공한다. 기본적인 모톨로지 연산은 팽창과 침식이다. 이들 기법은 영상 내에서 잡음 제거, 또는 구성 요소들의 결합 또는 분리 등의 폭넓은 분야에서 널리 사용된다. 모폴로지는 밝기값이 뭉쳐있는 영역이나 영상의 그래디언트를 구하는 용도로도 사용될 수 있다.
팽창과 침식 팽창연산도 영상과 커널과의 컨볼루션이다. 이때 영상을 A라고 하고, 커널을 B라고 하면 커널은 임의의 모양과 크기를 가질 수 있고, 고정점을 하나 갖는다. 대부분의 경우 커널은 중앙에 고정점을 가지고 있는 작은 정사각형 또는 원형으로 구성된다. 커널은 템플릿 또는 마스크의 일종이라고 생각할 수 있으며 팽창 연산은 국지적 최대값을 선택하는 효과가 있다. 영상 A를 커널 B로 스캔하면서 B와 겹치는 영역에서 최대 픽셀값을 구하고, 이 값을 고정점 아래에 있는 픽셀의 값으로 설정한다.
참조 :한빛미디어 Learining OpenCV 제대로 배우기
침식은 팽창과 반대되는 개념이다. 침식 연산은 커널 아래에서 국지적 최소값을 계산하는 것과 유사하다. 침식 연산 알고리즘은 영상 A를 커널 B로 스캔하면 B와 겹치는 영역에서 최소 픽셀값을 구하고, 이 값을 고정점 아래에 있는 픽셀의 값으로 설정한다.
영상 모톨로지는 임계값 연산 후 얻어지는 이진 영상에 대해서도 자주 실행된다. 그러나 팽창은 단지 최대값 연산이고 침식은 단지 최소값 연산이기 때문에 모폴로지는 일반 영상에서도 사용될 수 있다.
일반적으로 팽창은 영역 A를 확장시키는 반면, 침식은 영역 A를 축소시킨다. 또한 팽창은 영역 A에서 오목하게 들어간 부분을 채우는 효과가 있고, 침식은 볼록 튀어나온 부분을 제거하는 효과가 있다. 물론 이러한 결과는 커널의 모양에 따라 달라지기는 하지만 속이 꽉 채워져 있는 컨백스 형태의 커널이 사용될 경우에는 일반적으로 참이다. OpenCV에서는 침식을 위한 cvErode()와 팽창을 위한 cvDilate() 함수를 제공한다.
publicstaticvoid Erode(CvArr src, CvArr dst, IplConvKernel element, int iterations);
publicstaticvoid Dilate(CvArr src, CvArr dst, IplConvKernel element, int iterations);
cvErode() 와 cvDilate() 함수는 입력과 출력 영상을 인자로 받으며 바꿔치기 호출을 지원한다. 즉, 입력과 출력 영상을 동일한 영상으로 지정할 수 있다. 세번쨰 인자 B에는 커널을 전달할 수 있으며, 기본값으로 null이 설정된다. 커널이 null이면 중앙에 고정점이 있는 3x3 크기의 커널이 자동으로 사용된다. 마지막 인자 iterations에는 반복 횟수를 지정한다. 만약 iterations가 기본값 1이 아니면 함수 내부에서 해당 연산을 여러 번 반복하게 된다.
침식 또는 최소값 연산의 결과, 밝은 영역은 고립되거나 줄어든다.
Cv.Erode(src, dst,null,3);
침식연산은 영상에서 얼룩 잡음을 제거하기 위해 종종 사용되곤 한다. 얼룩은 침식으로 인해 없어지고, 중요한 큰 영역들은 영향을 받지 않고 그대로 남아있게 된다. 팽창 연산은 종종 연결된 구성 요소를 찾고자 할 때 사용된다. 잡음, 그림자 등 다양한 이유로 인하여 하나의 큰 영역이 여러 개의 구성 요소로 분리되는 경우가 발생하기 때문에 팽창 연산은 종종 필요하다.
스무딩 또는 블러링은 매우 간단하면서도 빈번하게 사용되는 영상처리 기법이다. 스무딩 기법은 주로 영상의 잡음(noise) 또는 손상을 완화시키기 위해서 사용된다. 스무딩은 영상의 크기를 줄이는 경우에도 중요한 역할을 담당한다. OpenCV는 현재 다섯 가지 스무딩 방법을 제공한다. 모든 스무딩 연산은 하나의 함수 cvSmooth()에 구현되어 있으며, 함수의 인자에 의해 연산 방법이 결정된다.
publicstaticvoid Smooth(CvArr src, CvArr dst, SmoothType smoothtype, int param1);
publicstaticvoid Smooth(CvArr src, CvArr dst, SmoothType smoothtype, int param1, int param2);
publicstaticvoid Smooth(CvArr src, CvArr dst, SmoothType smoothtype, int param1, int param2, double param3);
publicstaticvoid Smooth(CvArr src, CvArr dst, SmoothType smoothtype, int param1, int param2, double param3, double param4);
Src와 dst는 각각 입력 영상과 출력 영상을 가리킨다. cvSmooth() 함수는 param1, param2, param3, param4 라는 평이한 이름의 매개변수 네 개를 갖는데, 이들 매개변수의 의미는 세 번째 인자 smoothtype에 의해 결정된다.
Smoothtype 값
이름
바꿔치기
채널개수
입력영상타입
출력영상타입
설명
CV_BLUR
단술
블러
O
1,3
8u,32f
8u,32f
Param1 x param2 크기의 이웃 필셀값의 평균
CV_BLUR_NO_SCALE
스케일링 없는
단순
블러
X
1
8u
입력이 8u이면 16s 32f 이면 32f
Param1 x param2 크기의 이웃 픽셁밧의 합
CV_MEDIAN
중간값 블러
X
1,3
8u
8u
Param1 x param2 크기의 이웃 픽셀값에서 중간값
CV_GAUSSIAN
가우시안 블러
O
1,3
8u,32f
입력이 8u이면 16s, 32f 이면 32f
Param1 x param2 크기의 이웃 픽셀값의 가중치 합
CV_BILATERAL
양방향 블러
X
1,3
8u
8u
3 x 3 크기의 양방향 필터를 적용
색상 시그마 = param1
공간 시그마 = param2
단순 필터
CV_BLUR 값을 전달할 때 시행되는 단순 블러는 가장 간단한 형태의 스무딩 이다. 단순 블러는 1 또는 3채널, 8비트 또는 32 비트 실수형 영상에서 동작한다.
단순 블러, 부젼 픽셀값의 평균을 이용하여 스무딩을 수행한다. 왼쪽이 원본 영상이고 오른쪽이 결과 영상이다.
모든 스무딩 연산이 동일한 형태의 영상에서 동작하는 것은 아니다. Smoothtype 값에 CV_BLUR_NO_SCAL를 지정하면 스케일링 없는 단순 블러 연산이 수행된다. 이 연산은 기본적으로 단순 블러와 동일하지만 평균값 계산을 위한 나눗셈 연산이 없다. 이 때문에 입력 영상과 출력 영상은 서로 다른 데이터 타입을 가져야 하는데, 이는 계산 과정에서 오버플로가 생기는 것을 방지하기 위함이다. 스케일링 없는 단순 블러는 일반적으로 8비트 영상을 입력으로 받고, IPL_DEPTH_16S 또는 32S 데이터 타입의 출력 영상을 생성한다. 32비트 실수형 영상에서 실행할 경우, 결과 영상도 32비트 실수형 영상이다. 32비트 영상을 사용할 경우에도 반드시 지켜져야 만 한다. 스케일링 없는 단순 블러는 나눗셈 연산이 있는 단순 블러에 비해 연산 속도가 빠르다.
중간값 필터
중간값 필터는 픽셀 주변 사각형 영역에서 중간값을 선택하여 해당 픽셀의 값으로 교체하는 방식이며, smoothtype 값을 CV_MEDIAN으로 지정한다. 중간값 필터는 1 또는 3채널, 8비트 영상에서 동작하며, 원본 영상을 바꿔치기할 수 없다. 평균값을 사용하는 단순 블러는 홀로 독립되어 나타나는 잡음(이러한 잡음을 샷 잡음(shot noise)라고 부른다)에 민감하게 반응할 수 있다. 적은 개수의 픽셀에서 크게 튀는 값을 갖는 픽셀은 평균값 계산에 큰 영향을 줄 수 있기 때문이다. 중간값필터는 중간값을 선택함으로써 그러한 이상치를 무시할 수 있다. 중간값 블러, 주변 픽셀의 중간값을 이용하여 스무딩을 수행한다.
가우시안 필터
가우시안 필터는 동작이 빠른편은 아니지만 가장 유용한 필터이다. 가우시안 필터는 입력 영상의 각 픽셀에서 가우시안 커널과 컨볼루션을 하여 결과 영상을 생성한다. CvSmooth() 함수를 이용하여 가우시안 블러를 수행하려면 매개변수 값을 설정해 주어야 한다. Param1과 param2에서 필터 윈도우의 가로와 세로 크기를 지정한다. Param3에는 선택적으로 가우시안 커널의 시그마값(표준편차)을 지정한다. Param3이 기본값인 0으로 설정되면 시그마 값을 자체적으로 계산하여 사용한다. 비대칭 모양의 커널 윈도우를 사용하려면 param4를 지정할 수 있다. 이 경우, param3은 가로 방향의 시그마값을, pararm4는 세로 방향의 시그마값을 나타낸다.
만약 param3과 pararm4의 값을 지정하였는데 pararm1 = param2 = 0 으로 설정이되어 있다면, 커널 윈도우의 크기는 시그마값에 의해 자동으로 결정된다.
OpenCV는 자주 사용하는 가우시안 커널에 대하여 최적화된 성능의 스무딩을 보여준다. 표준 시그마값(param3 =0.0)을 갖는 3x3, 5x5, 7x7 크기의 가우시안 커널일 경우, 다른 커널에 비하여 연산 속도가 빠르다. 가우시안 블러는 8비트 또는 32비트 실수형을 갖는 1또는 3채널 영상에 대하여 적용할 수 있다.
양방향 필터
양방향 필터는 엣지 보존 스무딩 이라고 알려져 있는 영상 분석 방법 중의 하나이다. 양방향 필터는 가우시안 스무딩과 비교하면 쉽게 이해할 수 있다. 전형적인 가우시안 스무딩은 실제 영상의 픽셀값이 공간 상에서 천천히 변화하고, 이로 인하여 이웃 픽셀과 연관성을 많이 갖고 있지만 잡음은 갑작스럽게 값이 튄다는 점에서 착안되었다. 이러한 이유로 가우시안 스무딩은 신호는 보존하면서 잡음만 제거한다. 그러나 이 방법은 엣지 근처에서는 문제가 발생한다. 주변 값들과 상관성이 적은 엣지 부근에서도 가우시안 스무딩은 영상을 평탄하게 만듦으로써 엣지를 없애버린다. 양방향 필터는 약간의 연산 시간을 더 소모하지만 엣지를 보존하면서 영상의 스무딩을 수행한다.
가우시안 스무딩과 유사하게 양방향 필터 또한 각 픽셀과 주변 요소들로부터 가중 평균을 구한다. 이때 가중치는 두 개의 성분을 갖는데, 하나는 가우시안 스무딩에서 사용되는 가중치와 동일하다. 나머디 가중치 성분도 가우시안 가중치와 유사하지만 중심으로부터의 거리에 의해 결정되는 값이 아니라 중심 픽셀 값과의 밝기 차이에 의해 결정되는 가중치를 사용한다. 양방향 필터는 유사한 픽셀에 대하여 더 큰 가중치를 부여하는 가우시안 스무딩이라고 간주할 수 있다. 이 필터는 영상을 마치 수채화 그림처럼 바꿔주는 효과가 있다. 양방향 필터는 영상 분할을 위한 전처리 과정으로 사용되기도 한다. 양방향 필터는 두 개의 매개변수를 사용한다. Param1은 색 공간에서 사용되는 가우시안 커널의 크기를 나타낸다. Param1값이 클수록 더 넓은 분포의 밝기값(또는 생상값)이 평탄화 된다.param2는 공간 영역에서 사용되는 가우시안 커널의 너비를 나타낸다. 이는 가우시안 필터에서 시그마값과 유사하다.
C,M,Y 세 가지 색을 더하면 (1,1,1)dl 되어 색의 밝기가 낮아지는 감산체계를 사용 한다.
RGB컬러와는 정반대 공간에 위치하므로, 청록색-빨강색, 자홍색-초록색, 노랑색-파란색은 보색 관계이다.
컬러 모델의 가산과 감산체계
HSI 컬러 모델
HSI = Hue(색상), Saturation(채도), Intensity(명도)
YCrCb 모델
명도에 더 민감한 인간 눈을 감안해 YCrCb컬러 모델이 개발 되었다. 명도는 Y, 푸른색 정보를 Cr, 붉은색 정보를 츄로 기호화 하고 눈에 민감한 명도 정보 Y는 그대로 유지, 민감하지 않은 Cr과 Cb색상 정보는 그 양을 줄여서 사용한다. 정지영상 압축 표준 방식인 JPEG와 동영상 압축 표준 방식인 MPEG에서 사용 된다.