//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; }
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(); }