'Developer/OpenCV'에 해당되는 글 29건

  1. 2013.08.08 전경과 객체 분리 1

차프레임

제일 간단한 배경 제거 방법으로 한프레임에서 다른 한 프레임을 뺀 후, 충분히 큰 변화가 있는 부분을 전경으로 추출

  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
Posted by No names
,