//Extract key-frame using moments of YCbCr color space
vector<int> KeyframeMomentExtractor(VideoCapture cap)
{
	//Extract all frame from video as a list
	vector<int> keyFrames;

	int numFrame = (int)cap.get(CV_CAP_PROP_FRAME_COUNT);

	if (numFrame <= 2)
	{
		keyFrames.push_back(numFrame/2);
		return keyFrames;
	}

	//Setup parameter to used for Simple Breakpoint method to decide the key-frames
	double _totalDistance = 0.0;
	vector<KeyFrame> _listKeyframeCandidate;

	//Extract Color Structure Descriptor and compute distance to choose candidate key-frames
	Mat currentDescriptor;
	Mat previousDescriptor;

	for (int i = 0; i < numFrame; i++)
	{
		Mat frameMat,normMat;
		cap.read(frameMat); 
		frameMat.convertTo(normMat, CV_32FC3); normMat *= 1.0 / 255.0;
		cvtColor(normMat, normMat, CV_BGR2YCrCb);
		if (i == 0)
		{
			previousDescriptor = ToMat(GetMomentDescriptor(normMat));
		}
		else
		{
			currentDescriptor = ToMat(GetMomentDescriptor(normMat));

			double _distance   = CalcEuclidianDistance(previousDescriptor,currentDescriptor);

			KeyFrame candidate;
			candidate.frameID = i;
			candidate.distCurrentNext = _distance;
			_listKeyframeCandidate.push_back(candidate);

			_totalDistance += _distance;

			//Exchange info and free up memory
			previousDescriptor = currentDescriptor;
		}
	}

	//Calculate threshold and pick the key-frames when distance calculated is greater than threshold
	if (_listKeyframeCandidate.size() != 0)
	{
		double _threshold = _totalDistance / (double)_listKeyframeCandidate.size();
		//double _sd		= GetSDOfDistance(_listKeyframeCandidate, _mean);
		//double _threshold = _mean + _sd/4; 
		cout << "Threshold = " << _threshold << endl;

		int numFrame = (int)_listKeyframeCandidate.size();
		for (int i = 0; i < numFrame; i++)
		{
			if (_listKeyframeCandidate[i].distCurrentNext > _threshold)
			{
				cout << "Selected frame " << _listKeyframeCandidate[i].frameID << endl;
				keyFrames.push_back(_listKeyframeCandidate[i].frameID);
			}
		}

		if (keyFrames.size() == 0)
		{
			keyFrames.push_back(numFrame/2);
			cout << "No key frames is found. Get first frame. ";
		}
	}

	return keyFrames;
}
Ejemplo n.º 2
0
vector<Point> Camera::Follow() //prima void
{
    //float* contour=new float[height*width]();
    float* output=new float[height*width]();
    vector<float> temp = ToArray(Mat::zeros(height, width, CV_8UC1 ));
    output = &temp[0];
    cout << "[START] Active Contour " << endl;
    
    // Follow the camera
    cout << "Following the camera ...";
    cout << flush;
    Point center(-1,-1); Vec3b hsv; Mat mask, gray, HSV; Scalar lowerb, upperb;
    int erosion_size = 2, dilation_size = 10;
    Mat erodeElement = getStructuringElement(MORPH_RECT, Size(2 * erosion_size + 1, 2 * erosion_size + 1), Point(erosion_size, erosion_size) );
    Mat dilateElement = getStructuringElement(MORPH_RECT, Size(2 * dilation_size + 1, 2 * dilation_size + 1), Point(dilation_size, dilation_size) );
    vector<float> frameArray, maskArray;
    Mat ROI = Mat::zeros( height, width, CV_8UC1 );
    int count = 0; double sum = 0; 
    
    //while(waitKey(1) == -1) {//da togliere
        /*if (capture.read(frame) == NULL) {
            cout << "[ERROR] frame not read" << endl;
            return;
        }*/ //frame già settato
        clock_t startTime = clock(); // compute the time
        cvtColor(frame, gray, COLOR_RGB2GRAY);        
        cvtColor(frame, HSV, COLOR_RGB2HSV);
        
        setMouseCallback("Frame", onMouse);
        
        if( drawing_box ) 
            draw_box(&frame, roi);
        
        if(clicked) {
            // Init mask
            if(!haveMask) {
                // Take hsv from mouse
                center = initCenter;
                hsv = HSV.at<Vec3b>(center.y,center.x);
                haveMask = true;
                //cout << "HSV: " << hsv << endl;
                lowerb = Scalar(hsv.val[0] - 30, hsv.val[1] - 50, hsv.val[2] - 50);
                upperb = Scalar(hsv.val[0] + 30, hsv.val[1] + 50, hsv.val[2] + 50);
                //cout << "lowerb: " << lowerb << endl;
                //cout << "upperb: " << upperb << endl;  
                ROI = Mat::zeros( height, width, CV_8UC1 );
                rectangle( ROI, roi.tl(), roi.br(), Scalar(255), -1);
                
                sum = 0; count = 0; //benchmark
                
            }
            
            // Create the mask
            
            inRange(HSV, lowerb , upperb, mask);
            dilate(mask, mask, dilateElement);
            mask = mask.mul(ROI);
            
            //imshow("mask", mask);
            
            frameArray = ToArray(gray);
            maskArray = ToArray(mask);
            ActiveContour(&frameArray[0], output, contour, &maskArray[0], width, height, roi.br().y);  
            
            Mat OUT = ToMat(output, height, width);
            OUT.convertTo(OUT, CV_8UC1);
            //imshow("Output", OUT);
            
            vector<vector<Point> > contours;
            vector<Vec4i> hierarchy;
            findContours(OUT, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
            
            vector<Rect> boundRect( contours.size() );
            
            for( int i = 0; i < contours.size(); i++ )
            { 
                boundRect[i] = boundingRect( Mat(contours[i]) );
            }
            
            /// Draw polygonal contour + bonding rects + circles
            Mat drawing = Mat::zeros( height, width, CV_8UC3 );
            circle(frame, center, 5, Scalar(0,0,255), 5);
            
            for( int i = 0; i< contours.size(); i++ )
            {
                
                if(boundRect[i].contains(center)) {
                    
                    drawContours( frame, contours, i, Scalar(255,255,255), 1, 8, vector<Vec4i>(), 0, Point() );
                    rectangle( frame, boundRect[i].tl(), boundRect[i].br(), Scalar(0,255,0), 2, 8, 0 );
                    
                    // Center
                    center.x = boundRect[i].tl().x + boundRect[i].size().width/2;
                    center.y = boundRect[i].tl().y + boundRect[i].size().height/2;
                    
                    int x = boundRect[i].size().width;
                    int y = boundRect[i].size().height;
                    int v = (int)(sqrt((x/(y+EPS))*area));
                    int h = (int)(area/v);
                    int deltax = (int)((h-y)/2);
                    int deltay = (int)((v-x)/2);
                    int tlx = boundRect[i].tl().x -deltax;
                    int tly = boundRect[i].tl().y -deltay;
                    int brx = boundRect[i].br().x +deltax;
                    int bry = boundRect[i].br().y +deltay;
                    tlx = (tlx < 0) ? 0 : tlx;
                    brx = (brx > width) ? width : brx;
                    tly = (tly < 0) ? 0 : tly;
                    bry = (bry > height) ? height : bry;                   
                    roi = Rect(Point(tlx,tly),Point(brx,bry));
                    ROI = Mat::zeros( height, width, CV_8UC1 );
                    rectangle( ROI, roi.tl(), roi.br(), Scalar(255), -1);
                    rectangle( frame, roi.tl(), roi.br(), Scalar(0,0,255), 2, 8, 0 );
                    //imshow("ROI", ROI);
                    break;
                }
            }
        }
        imshow("Frame", frame);
        sum += double( clock() - startTime ) / (double)CLOCKS_PER_SEC;
        count++;
        
//  }
    cout << sum / count << endl << flush;
    return contours.front();
}