2012-02-21 4 views
4

openCV와 C++를 사용하여 걷기 동작 인식을하고 있는데, 제공된 그림에서 보여지는 효과를 얻기 위해 마스크 또는 복사 된 이미지를 만들고 싶습니다. extracted human. 다음은 이미지의 설명입니다. 인간의 걷는 결과 얼룩이 보입니다. 그런 다음 원래 프레임의 마스크 이미지 또는 복사 된 이미지가 만들어지며 이진 인간 블롭이 이제 마스크되고 마스크되지 않은 픽셀이 이제 0으로 설정됩니다. 결과는 검정색 배경의 추출 된 인체입니다. 아래의 다이어그램은 인간의 얼룩을 추출한 다음 마스크하는 방법을 보여줍니다. 이것은 비디오 시퀀스의 5 번째 프레임마다 수행됩니다. 지금까지 제 코드는 매 5 프레임마다 그레이 스케일링, 모든 얼룩의 영역 찾기, 임계 값을 적용하여 이진 이미지를 얻었습니다. 어느 정도 인간의 얼룩 만 흰색이고 나머지는 이미지입니다. 검은. 자, 나는 인체를 추출하려고 노력하고 있지만, 어떻게 진행할 지 아무 단서가 없습니다. 도와주세요.바이너리 이미지에서 블롭 마스크하기

#include "cv.h" 
#include "highgui.h" 
#include "iostream" 

using namespace std; 
int main(int argc, char* argv) { 

CvCapture *capture = NULL; 
capture = cvCaptureFromAVI("C:\\walking\\lady walking.avi"); 
if(!capture){ 
    return -1; 
} 

IplImage* color_frame = NULL; 
IplImage* gray_frame = NULL ; 

int thresh_frame = 28; 
CvMoments moments; 

int frameCount=0;//Counts every 5 frames 
cvNamedWindow("walking", CV_WINDOW_AUTOSIZE); 

while(1) { 
    color_frame = cvQueryFrame(capture);//Grabs the frame from a file 
    if(!color_frame) break; 
    gray_frame = cvCreateImage(cvSize(color_frame->width, color_frame->height), color_frame->depth, 1); 
    if(!color_frame) break;// If the frame does not exist, quit the loop 


    frameCount++; 
    if(frameCount==5) 
    { 
     cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY); 
     cvThreshold(gray_frame, gray_frame, thresh_frame, 255, CV_THRESH_BINARY); 
     cvErode(gray_frame, gray_frame, NULL, 1); 
     cvDilate(gray_frame, gray_frame, NULL, 1); 

     cvMoments(gray_frame, &moments, 1); 
     double m00; 
     m00 = cvGetCentralMoment(&moments, 0,0); 

     cvShowImage("walking", gray_frame); 
     frameCount=0; 
    } 
    char c = cvWaitKey(33); 
    if(c == 27) break; 
} 

double m00 = (double)cvGetCentralMoment(&moments, 0,0); 
cout << "Area - : " << m00 << endl; 
//area of lady walking = 39696. Therefore, using new threshold area as 30 for this video 
//area of walking man = 67929 

cvReleaseImage(&color_frame); 
cvReleaseImage(&gray_frame); 
cvReleaseCapture(&capture); 
cvDestroyWindow("walking"); 

return 0; 
} 

나는 또한 내가 코드에서 사용하고있는 동영상을 업로드하고 싶지만 사람도 그와 함께 나를 도울 수 있다면 난 여기에 업로드하는 방법을 알고, 그렇게하지 않습니다. 가능한 한 많은 정보를 제공하고 싶습니다. 내 질문.

+2

부수적으로, 절대로 그런 식으로 사용하지 마십시오! while do {}를 사용하고 거기에서 확인하십시오. –

+0

@MartinKristiansen openCV와 C++을 처음 접했을 때 코드가 작동되면서 나는 그것에 만족했다. 거기에 사용할 수있는 휴식을 받아 들일 수 있습니까? –

+0

그것은 제어 흐름을 덜 투명하게 할당하게합니다. while 루프가 종료 될 때를 알아 내면 정말 명확하지 않으며 코드가 커지면 훨씬 덜 명확 해집니다. –

답변

1

가장 쉬운 방법은 이미지에서 가장 큰 얼룩을 찾는 것입니다 (cvfind 등고선이 필요한 기능이 될 수 있음). 그런 다음 다른 모든 얼룩을 blac으로 설정합니다 (모든 윤곽을 스캔하고 cvfloadfill 사용). 마지막으로 고려한 픽셀이 흰색 인 경우 전체 이진 이미지를 스캔합니다. 픽셀이 검은 색이면 5 번째 프레임의 해당 픽셀을 검정색으로 설정합니다.

+0

그래서 cvBlobLib이라는 라이브러리를 설치할 필요가 없습니까? 얼룩을 추출하는 방법을 연구 할 때 여러 번 언급했지만 O'Reilly 나 openCV 참조 설명서에는 아무 것도 없었습니다. 그래서 그것을 사용하는 것에 대해 조금 의심 스러웠습니다. 그 cvBlobLib을 사용하는 대신 윤곽선을 선호합니다. 난 정말이 작품을 희망합니다 –

+1

나는 그것에 대해 잘 모르겠지만 CvBlob가 Opencv에 마지막 버전에 포함되었다고 생각합니다. (아직 확인) – andrea