int initAll() { initConfiguration(); // cout << "Use webcam? (Y/N)" <<endl; // // char cc = fgetc(stdin); if( !initCapture(true,cam_id)) //!initCapture(cc == 'Y' || cc == 'y',cam_id) ) return 0; if( !initFaceDet((OPENCV_ROOT + "/data/haarcascades/haarcascade_frontalface_default.xml").c_str())) { cerr << "failed initFaceDet with" << OPENCV_ROOT << "/data/haarcascades/haarcascade_frontalface_default.xml" << endl; return 0; } // Startup message tells user how to begin and how to exit printf( "\n********************************************\n" "To exit, click inside the video display,\n" "then press the ESC key\n\n" "Press <ENTER> to begin" "\n********************************************\n" ); fgetc(stdin); // Create the display window cvNamedWindow( DISPLAY_WINDOW, 1 ); // Initialize tracker captureVideoFrame(); if( !createTracker(pfd_pVideoFrameCopy) ) return 0; // Set Camshift parameters setVmin(60); setSmin(50); FdInit(); return 1; }
int encodeOneFrame(unsigned long fcounter) { /* Check if the encode was inited */ if (start_frame == -1) return 0; /*** Video ***/ debuglog(LCF_DUMP | LCF_FRAME, "Encode a video frame"); const uint8_t* orig_plane[4] = {0}; int orig_stride[4] = {0}; /* Access to the screen pixels */ captureVideoFrame(orig_plane, orig_stride); /* Initialize AVPacket */ AVPacket vpkt; vpkt.data = NULL; vpkt.size = 0; av_init_packet(&vpkt); /* Change pixel format to YUV420p and copy it into the AVframe */ int rets = sws_scale(toYUVctx, orig_plane, orig_stride, 0, video_frame->height, video_frame->data, video_frame->linesize); if (rets != video_frame->height) { debuglog(LCF_DUMP | LCF_ERROR, "We could only convert ",rets," rows"); return 1; } video_frame->pts = fcounter - start_frame; /* Encode the image */ int got_output; int ret = avcodec_encode_video2(video_st->codec, &vpkt, video_frame, &got_output); if (ret < 0) { debuglog(LCF_DUMP | LCF_ERROR, "Error encoding video frame"); return 1; } if (got_output) { /* Rescale output packet timestamp values from codec to stream timebase */ vpkt.pts = av_rescale_q_rnd(vpkt.pts, video_st->codec->time_base, video_st->time_base, static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); vpkt.dts = av_rescale_q_rnd(vpkt.dts, video_st->codec->time_base, video_st->time_base, static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); vpkt.duration = av_rescale_q(vpkt.duration, video_st->codec->time_base, video_st->time_base); vpkt.stream_index = video_st->index; if (av_interleaved_write_frame(formatContext, &vpkt) < 0) { debuglog(LCF_DUMP | LCF_ERROR, "Error writing frame"); return 1; } av_free_packet(&vpkt); } /*** Audio ***/ debuglog(LCF_DUMP | LCF_FRAME, "Encode an audio frame"); /* Initialize AVPacket */ AVPacket apkt; apkt.data = NULL; apkt.size = 0; av_init_packet(&apkt); int frame_size; if (audio_st->codec->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) frame_size = audiocontext.outNbSamples; else { frame_size = audio_st->codec->frame_size; if (frame_size > audiocontext.outNbSamples) { debuglog(LCF_DUMP | LCF_FRAME | LCF_ERROR, "This is bad..."); frame_size = audiocontext.outNbSamples; } } audio_frame->nb_samples = frame_size; audio_frame->pts = av_rescale_q(accum_samples, AVRational{1, audio_st->codec->sample_rate}, audio_st->codec->time_base); accum_samples += frame_size; avcodec_fill_audio_frame(audio_frame, audio_st->codec->channels, audio_st->codec->sample_fmt, &audiocontext.outSamples[0], frame_size*audiocontext.outAlignSize, 1); ret = avcodec_encode_audio2(audio_st->codec, &apkt, audio_frame, &got_output); if (ret < 0) { debuglog(LCF_DUMP | LCF_ERROR, "Error encoding audio frame"); return 1; } if (got_output) { /* We have an encoder output to write */ apkt.pts = av_rescale_q_rnd(apkt.pts, audio_st->codec->time_base, audio_st->time_base, static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); apkt.dts = av_rescale_q_rnd(apkt.dts, audio_st->codec->time_base, audio_st->time_base, static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); apkt.duration = av_rescale_q(apkt.duration, audio_st->codec->time_base, audio_st->time_base); apkt.stream_index = audio_st->index; if (av_interleaved_write_frame(formatContext, &apkt) < 0) { debuglog(LCF_DUMP | LCF_ERROR, "Error writing frame"); return 1; } av_free_packet(&apkt); } return 0; }
////////////////////////////////// // main() // int _tmain(int argc, _TCHAR* argv[]) { // try_conv(); if( !initAll() ) exitProgram(-1); // Capture and display video frames until a face // is detected int frame_count = 0; while( (char)27!=cvWaitKey(1) ) { //Retrieve next image and // Look for a face in the next video frame //read into pfd_pVideoFrameCopy if (!captureVideoFrame()){ if (frame_count==0) throw exception("Failed before reading anything"); break; //end of video.. } ++frame_count; CvSeq* pSeq = 0; detectFaces(pfd_pVideoFrameCopy,&pSeq); //Do some filtration of pSeq into pSeqOut, based on history etc, //update data structures (history ,face threads etc.)s list<Face> & faces_in_this_frame = FdProcessFaces(pfd_pVideoFrameCopy,pSeq); //== draw rectrangle for each detected face == if (!faces_in_this_frame.empty()){ //faces detected (??) int i = 0; for(list<Face>::iterator face_itr = faces_in_this_frame.begin(); face_itr != faces_in_this_frame.end(); ++face_itr) { CvPoint pt1 = cvPoint(face_itr->x,face_itr->y); CvPoint pt2 = cvPoint(face_itr->x + face_itr->width,face_itr->y + face_itr->height); if (face_itr->frame_id == frame_count) //detected for this frame cvRectangle( pfd_pVideoFrameCopy, pt1, pt2, colorArr[i++%3],3,8,0); else //from a previous frame cvRectangle( pfd_pVideoFrameCopy, pt1, pt2, colorArr[i++%3],1,4,0); } }else{ //no faces detected Sleep(100); } cvShowImage( DISPLAY_WINDOW, pfd_pVideoFrameCopy ); cvReleaseImage(&pfd_pVideoFrameCopy); } //end input while cout << "==========================================================" << endl; cout << "========== Input finished ================================" << endl; cout << "==========================================================" << endl << endl; cout << "Press a key to continue with history playback" <<endl; char cc = fgetc(stdin); cout << "==========================================================" << endl; cout << "==== Playback history + rectangles + =====" << endl; cout << "==== create output video(s) =====" << endl; cout << "==========================================================" << endl << endl; list<FDHistoryEntry> & pHistory = FdGetHistorySeq(); //== VIDEO WRITER START ===================== int isColor = 1; int fps = 12;//30;//25; // or 30 int frameW = 640; // 744 for firewire cameras int frameH = 480; // 480 for firewire cameras CvVideoWriter * playbackVidWriter=cvCreateVideoWriter((OUTPUT_PLAYBACK_VIDEOS_DIR + "\\playback.avi").c_str(), PFD_VIDEO_OUTPUT_FORMAT, fps,cvSize(frameW,frameH),isColor); CvVideoWriter * croppedVidWriter = 0; if (!playbackVidWriter) { cerr << "can't create vid writer" << endl; exitProgram(-1); } bool wasWrittenToVideo = false; //== VIDEO WRITER END ===================== int index = 0; // play recorded sequence---------------------------- // i.e. just what's in the history int playback_counter = 0; cout << "start finding consensus rect " << endl; //find min max bool found =false; int min_x = INT_MAX,//pFaceRect->x, max_x = 0,//pFaceRect->x+pFaceRect->width, min_y = INT_MAX,//pFaceRect->y, max_y = 0;//pFaceRect->y+pFaceRect->height; for (list<FDHistoryEntry>::iterator itr = pHistory.begin() ; itr != pHistory.end(); ++itr) { CvSeq* pFacesSeq = itr->pFacesSeq; assert(pFacesSeq); //TODO Might want to convert to Face here CvRect * pFaceRect = (CvRect*)cvGetSeqElem(pFacesSeq, 0); //works only on first rec series if (pFaceRect){ found = true; if (pFaceRect->x < min_x) min_x = pFaceRect->x; if (pFaceRect->x+pFaceRect->width > max_x) max_x = pFaceRect->x + pFaceRect->width; if (pFaceRect->y < min_y) min_y = pFaceRect->y; if (pFaceRect->y+pFaceRect->height > max_y) max_y = pFaceRect->y+pFaceRect->height; } } //assert(found); //some rect in history.. CvRect consensus_rect; consensus_rect.x = min_x; consensus_rect.y = min_y; consensus_rect.width = max_x - min_x; consensus_rect.height = max_y - min_y; Sleep(3000); //just to make sure that pruneHistory isn't modifying.. cout << "start playback loop " << endl; int k = 0; for (list<FDHistoryEntry>::iterator itr = pHistory.begin() ; itr != pHistory.end(); ++itr) { cout << ++k << endl; //cvResetImageROI(history_itr->pFrame); //now reset by FDFaceThread pfd_pVideoFrameCopy = cvCreateImage( cvGetSize(itr->pFrame ), 8, 3 ); //TODO query image for its properties cvCopy( itr->pFrame , pfd_pVideoFrameCopy, 0 ); CvSeq* pFacesSeq = itr->pFacesSeq; #ifndef NO_RECTS_ON_PLAYBACK for(int i = 0 ;i < pFacesSeq->total ;i++){ Face * pFaceRect = (Face*)cvGetSeqElem(pFacesSeq, i); assert(pFaceRect != NULL); CvPoint pt1 = cvPoint(pFaceRect->x,pFaceRect->y); CvPoint pt2 = cvPoint(pFaceRect->x + pFaceRect->width,pFaceRect->y + pFaceRect->height); if (itr->frame_id == pFaceRect->frame_id) cvRectangle( pfd_pVideoFrameCopy, pt1, pt2, colorArr[i%3],3,8,0); else cvRectangle( pfd_pVideoFrameCopy, pt1, pt2, colorArr[i%3],1,4,0); } #endif if (pFacesSeq->total > 0) { assert(found); //write 1st sequence if exists to cropped vid if (!croppedVidWriter) croppedVidWriter=cvCreateVideoWriter((OUTPUT_PLAYBACK_VIDEOS_DIR + "\\cropped_playback.avi").c_str(), PFD_VIDEO_OUTPUT_FORMAT, fps,cvSize(max_x-min_x,max_y-min_y),isColor); assert(croppedVidWriter); cvResetImageROI(pfd_pVideoFrameCopy); cvSetImageROI(pfd_pVideoFrameCopy,consensus_rect); //write cropped image to video file IplImage *croppedImg = cvCreateImage(cvGetSize(pfd_pVideoFrameCopy), pfd_pVideoFrameCopy->depth, pfd_pVideoFrameCopy->nChannels); assert(croppedImg); cvCopy(pfd_pVideoFrameCopy, croppedImg, NULL); assert(croppedVidWriter); cvWriteFrame(croppedVidWriter,croppedImg); cvReleaseImage(&croppedImg); } cvShowImage( DISPLAY_WINDOW, pfd_pVideoFrameCopy ); cvResetImageROI(pfd_pVideoFrameCopy); //CROP_PLAYBACK_FACE cvWriteFrame(playbackVidWriter,pfd_pVideoFrameCopy); if( (char)27==cvWaitKey(1) ) break;//exitProgram(0); Sleep(50); ++playback_counter; } cvReleaseVideoWriter(&playbackVidWriter); cvReleaseVideoWriter(&croppedVidWriter); exitProgram(0); //----------------------------------------------------------- //----------------------------------------------------------- //----------------------------------------------------------- }