차프레임
제일 간단한 배경 제거 방법으로 한프레임에서 다른 한 프레임을 뺀 후, 충분히 큰 변화가 있는 부분을 전경으로 추출
void cvAbsDiff(const CvArr* frameTime1, const CvArr* FrameTime2, CvArr* frameForground); |
영상은 잡음의 영향을 받기 때문에, 픽셀값의 차이가 15보다 작은 경우는 무시하고, 값의 차이가 큰 픽셀들만 두드러지게 표시하자!
픽셀값의 차이가 작으면0으로, 크면 255로 설정한다.
double cvThreshold( const CvArr* frameForground, CvArr* frameForground, double 15, double 255, int threshold_type ); |
작은 잡음 영역들을 지울때는 cvErode를 이용한다.
평균배경방법
배경모델을 생성하기 위해 각 픽셀의 평균과 표준편차를 이용한다.
평균방법은 네개의 OpenCV함수를 사용하여 구현할수 있다.
void cvAcc(const CvArr* image, CvArr* sum, const CvArr* mask=NULL); void cvAbsDiff(const CvArr* src1, const CvArr* src2, CvArr* dst); void cvInRange(const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst);
void cvOr(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL); |
cvAcc()함수를 이용하여 각 프레임 영상을 일정 시간 누적한다. (8비트 정수형 정수형 영상을 실수형 영상으로 더하여 합하는 연산수행)
cvAbsDiff()함수를 이용하여 한 프레임과 다른 프레임간 차이의 절대값을 구하여 이를 누적한다.
cvInRange()함수를 이용하여 영상을 전경과 배경 영역으로 분할한다.
cvOr()함수는 각 컬러 채널의 분할 결과로부터 최종 마스크 영상 하나를 생성하기 위하여 사용된다.
[배경영상과 프레임간의 차이의 절대값을 누적하여 학습]
void accumulateBackground(IplImage *I) { static int first=1; cvConvertScale(I, Iscratch, 1, 0); //8비트 3채널 -> float타입 3채널 변환
if(!first) { cvAcc(Iscratch, IavgF); //프레임을 누적 cvAbsDiff(Iscratch, IprevF, Iscratch2); //프레임간의 절대값 영상을 구함 cvAcc(Iscratch2, IdiffF); //프레임간의 절대값 누적 Icount+=1.0; }
first=0; cvCopy(Iscratch, IprevF); //현재프레임을 이전프레임으로 복사 } |
[누적된 영상을 이용하여 배경에 대한 통계적 모델을 구한다]
void createModelsFromStats() { cvConvertScale(IavgF, IavgF, (double)1.0/Icount); //누적한 영상의 평균 cvConvertScale(IdiffF, IdiffF, (double)1.0/Icount); //프레임간 절대값 누적 평균
//IdiffF 영상의 각 채널값은 0보다 커야한다. cvAddS(IdiffF, cvScalar(1.0, 1.0, 1.0), IdiffF); setHighThreshold(7.0); / setLowThreshold(6.0); }
//프레임간 차이의 절대값 평균을 이용하여 임계값을 결정 void setHighThreshold(float scale) { cvConvertScale(IdiffF, Iscratch, scale); cvAdd(Iscratch, IavgF, IhiF); cvSplit(IhiF, Ihi1, Ihi2, Ihi3, 0); }
//프레임간 차이의 절대값 평균을 이용하여 임계값을 결정 void setLowThreshold(float scale) { cvConvertScale(IdiffF, Iscratch, scale); cvAdd(IavgF, Iscratch, IlowF); cvSplit(IlowF, Ilow1, Ilow2, Ilow3, 0); } |
상위임계값 = lavgF + 7.0 * IdfffF
하위임계값 = lavgF - 6.0 * idfffF
현재 프레임의 픽셀값이 상위 임계값과 하위임계값 사이에 존재하면 배경으로 간주하고, 그렇지 않으면 전경 객체로 간주한다.
[배경모델, 상위임계값, 하위임계값을 이용하여 영상을 전경과 배경으로 분할]
void backgroundDiff(IplImage* I, IplImage* Imask) { cvConvertScale(I, Iscratch, 1, 0); cvSplit(Iscratch, Igray1, Igray2, Igray3, 0);
//채널1 cvInRange(Igray1, Ilow1, Ihi1, Imask);
//채널2 cvInRange(Igray2, Ilow2, Ihi2, Imask); cvOr(Imask, Imaskt, Imask);
//채널3 cvInRange(Igray3, Ilow3, Ihi3, Imask); cvOr(Imask, Imaskt, Imask);
//마지막으로 결과영상을 반전 cvSubRS(Imask, cvScalar(255), Imask); }
|
'Developer > OpenCV' 카테고리의 다른 글
CvStereoBMState 구조체 (0) | 2013.02.18 |
---|---|
매핑 (0) | 2013.02.04 |
기본행렬, 필수행렬 (0) | 2013.02.03 |
스테레오 영상 (0) | 2013.02.01 |
어파인변환, 투시변환 (0) | 2013.01.31 |