bool Num_Extract::A_encloses_B(RotatedRect A, RotatedRect B){ Point2f ptsA[4]; Point2f ptsB[4]; A.points(ptsA); B.points(ptsB); bool encloses = true; Point2f p1,p2,p3,p4; double m = 0; double indicator = 0; double test_val = 0; for(int i = 0 ; i < 4 ; i++){ p1 = ptsA[i]; p2 = ptsA[(i+1)%4]; p3 = ptsA[(i+2)%4]; m = (p2.y-p1.y)/(p2.x-p1.x); indicator = (p3.y-p1.y)-m*(p3.x-p1.x); for(int j = 0 ; j<4 ; j++){ p4 = ptsB[j]; test_val = (p4.y-p1.y)-m*(p4.x-p1.x); if(test_val*indicator<0){ encloses = false; break; } } if(!encloses) break; } return encloses; }

void checkRotatedRectangle() { RNG rng(getTickCount()); Mat filledRect = Mat::zeros(sz, CV_8UC1); Point center(rng.uniform(sz.width/4, sz.width*3/4), rng.uniform(sz.height/4, sz.height*3/4)); Size rect_size(rng.uniform(sz.width/8, sz.width/6), rng.uniform(sz.height/8, sz.height/6)); float angle = rng.uniform(0, 360); Point2f vertices[4]; RotatedRect rRect = RotatedRect(center, rect_size, angle); rRect.points(vertices); for (int i = 0; i < 4; i++) { line(filledRect, vertices[i], vertices[(i + 1) % 4], Scalar(255), 3); } vector<Vec4i> lines; Ptr<LineSegmentDetector> ls = createLineSegmentDetectorPtr(LSD_REFINE_ADV); ls->detect(filledRect, lines); Mat drawnLines = Mat::zeros(filledRect.size(), CV_8UC1); ls->drawSegments(drawnLines, lines); imshow("checkRotatedRectangle", drawnLines); std::cout << "Check Rectangle- Number of lines: " << lines.size() << " - >= 4 Wanted." << std::endl; }

void Brushstroke::draw(Mat& alphaMap, Mat& mask, double spacing, double jitter) { Point2d normal = Point2d(cos(angle), sin(angle)); Point2d point1 = normal * length1; Point2d point2 = normal * -length2; point1 += anchor; point2 += anchor; Point2d texCenter; RotatedRect maskRect; double texAngle; Size_<double> maskSize = mask.size(); double ratio = (width + 2.0) / maskSize.width; Mat scaledMask; resize(mask, scaledMask, Size(), ratio, ratio, INTER_CUBIC); maskSize = scaledMask.size(); RNG rng(0xFFFFFFFF); for(double dist = -length2; dist < length1; dist += spacing) { texCenter = anchor + normal * dist; texAngle = angle + jitter * rng.uniform(-1.0, 1.0); maskRect = RotatedRect(texCenter, maskSize, texAngle); Rect2d boundingRect = maskRect.boundingRect(); renderTexture(alphaMap, scaledMask, maskRect); } }

// Define trackbar callback functon. This function find contours, // draw it and approximate it by ellipses. void processImage(int /*h*/, void*) { vector<vector<Point> > contours; Mat bimage = image >= sliderPos; findContours(bimage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); Mat cimage = Mat::zeros(bimage.size(), CV_8UC3); for(size_t i = 0; i < contours.size(); i++) { size_t count = contours[i].size(); if( count < 6 ) continue; Mat pointsf; Mat(contours[i]).convertTo(pointsf, CV_32F); RotatedRect box = fitEllipse(pointsf); if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 ) continue; drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8); ellipse(cimage, box, Scalar(0,0,255), 1, CV_AA); ellipse(cimage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(0,255,255), 1, CV_AA); Point2f vtx[4]; box.points(vtx); for( int j = 0; j < 4; j++ ) line(cimage, vtx[j], vtx[(j+1)%4], Scalar(0,255,0), 1, CV_AA); } imshow("result", cimage); }

double get_skew_angle(Mat img) { // Binarize threshold(img, img, 225, 255, THRESH_BINARY); // Invert colors bitwise_not(img, img); Mat element = getStructuringElement(MORPH_RECT, Size(5, 3)); erode(img, img, element); vector<Point> points; Mat_<uchar>::iterator it = img.begin<uchar>(); Mat_<uchar>::iterator end = img.end<uchar>(); for (; it != end; ++it) if (*it) points.push_back(it.pos()); RotatedRect box = minAreaRect(Mat(points)); double angle = box.angle; if (angle < -45.) angle += 90.; Point2f vertices[4]; box.points(vertices); for(int i = 0; i < 4; ++i) line(img, vertices[i], vertices[(i + 1) % 4], Scalar(255, 0, 0), 1, CV_AA); return angle; }

void camshift( Mat &frame, Mat &hue_roi, Mat &mask_roi, Mat &backproj, Mat &thresh_img, Point2i &resol, Point2i &shift, Rect &searchwin, struct intrinsics *intrins, struct pose *body, ofstream& file ) { Mat hsv, hue, mask; hue.create( resol.y, resol.x, CV_8UC1); mask.create(resol.y, resol.x, CV_8UC3); int ch[] = {0,0}; float theta; RotatedRect orient; Point2f vertices[4]; bool inframe = false; cvtColor( frame, hsv, COLOR_BGR2HSV ); //Ignore pixels in HSV space with too high/low saturation and a high value: hv_threshold( hsv, mask ); //Extract single channel Hue frames from HSV frames //Usage of ch[] means copying from channel 0 of source to channel 0 of destination mixChannels( &hsv, 1, &hue, 1, ch, 1 ); //Compute backprojected frames: backprojection( binsize, hue_roi, hue, backproj, mask_roi, thresh_img ); double res = 1; moment(thresh_img, res, searchwin, theta, inframe, shift); orient = RotatedRect(Point2f(searchwin.x, searchwin.y), Size2f(searchwin.width, searchwin.height), theta); orient.points(vertices); for (int i = 0; i < 4; i++){ line(frame, vertices[i], vertices[(i+1)%4], Scalar(0,255,0), 2); } Rect brect = orient.boundingRect(); rectangle( frame, brect, Scalar(0,0,255), 2 ); imshow( "Source Stream", frame ) ; if (inframe){ simulate(inframe, searchwin, intrins, file); } }

static void refineSegments(const Mat& img, Mat& mask, Mat& dst) { int niters = 3; vector<vector<Point> > contours; vector<Vec4i> hierarchy; Mat temp; dilate(mask, temp, Mat(), Point(-1,-1), niters); erode(temp, temp, Mat(), Point(-1,-1), niters*2); dilate(temp, temp, Mat(), Point(-1,-1), niters); findContours( temp, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE ); dst = Mat::zeros(img.size(), CV_8UC3); if( contours.size() == 0 ) { return; } // iterate through all the top-level contours, // draw each connected component with its own random color /* int idx = 0, largestComp = 0; double maxArea = 0; for( ; idx >= 0; idx = hierarchy[idx][0] ) { const vector<Point>& c = contours[idx]; double area = fabs(contourArea(Mat(c))); if( area > maxArea ) { maxArea = area; largestComp = idx; } } Scalar color( 255, 255, 255 ); drawContours( dst, contours, largestComp, color, FILLED, LINE_8, hierarchy ); //drawContours( img, contours, largestComp, color, FILLED, LINE_8, hierarchy ); */ RNG& rng = theRNG(); for (int x = 0; x < contours.size(); x++ ) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(dst, contours, x, color, FILLED, LINE_8, hierarchy, 0, Point()); } vector<Rect> boundRect(contours.size()); for (int x = 0; x < contours.size(); x++) { RotatedRect box = minAreaRect(contours[x]); Point2f vertex[4]; box.points(vertex); for (int y = 0; y < 4; y++) { line(img, vertex[y], vertex[(y+1)%4], Scalar(0, 255, 0), 2, LINE_AA); } } }

int main( ) { //改变console字体颜色 system("color 1F"); //显示帮助文字 ShowHelpText(); //初始化变量和随机值 Mat image(600, 600, CV_8UC3); RNG& rng = theRNG(); //循环，按下ESC,Q,q键程序退出，否则有键按下便一直更新 while(1) { //参数初始化 int count = rng.uniform(3, 103);//随机生成点的数量 vector<Point> points;//点值 //随机生成点坐标 for(int i = 0; i < count; i++ ) { Point point; point.x = rng.uniform(image.cols/4, image.cols*3/4); point.y = rng.uniform(image.rows/4, image.rows*3/4); points.push_back(point); } //对给定的 2D 点集，寻找最小面积的包围矩形 RotatedRect box = minAreaRect(Mat(points)); Point2f vertex[4]; box.points(vertex); //绘制出随机颜色的点 image = Scalar::all(0); for( int i = 0; i < count; i++ ) circle( image, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), CV_FILLED, CV_AA ); //绘制出最小面积的包围矩形 for( int i = 0; i < 4; i++ ) line(image, vertex[i], vertex[(i+1)%4], Scalar(100, 200, 211), 2, CV_AA); //显示窗口 imshow( "矩形包围示例", image ); //按下ESC,Q,或者q，程序退出 char key = (char)waitKey(); if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC' break; } return 0; }

int main(int argc, char** argv) { Mat media, variancia; Mat fundo, quadroAnterior; Mat rastro; VideoCapture vid(argv[1]); vector<Rastro> rastros; RotatedRect conjuntoDasVagas = RotatedRect(Point2f(550, 150), Size2f(200,70), 70); int cont = 0; MediaVariancia(1, argv[1], media, variancia); media.copyTo(rastro); Point2f vertices[4]; conjuntoDasVagas.points(vertices); for (int i = 0; i < 4; i++) line(rastro, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0)); while (vid.isOpened()) { Mat quadro; if (!vid.read(quadro)) { break; } else { Mat D; rectangle(quadro, Point2f(250, 140), Point2f(400, 500), Scalar(0, 0, 0), -1); if (!quadroAnterior.empty()) { D = Diferenca(quadro, quadroAnterior, 1, atoi(argv[2])); //Se os quadros não forem exatamente iguais atualiza o rastro if (contaZeros(D)>0) { Mat estrut; estrut = Mat::ones(6, 6, CV_8UC1); dilate(D, D, estrut, Point(-1, -1), 5); Mat dBranca = Branco3Canais(D); erode(dBranca, dBranca, Mat::ones(3, 3, CV_8UC1), Point(-1, -1), 1); Kalman(dBranca, rastro, rastros); } //imshow("Dilatada", D); imshow("rastro", rastro); imshow("Video", quadro); //imshow("Anterior", quadroAnterior); waitKey(1); } quadro.copyTo(quadroAnterior); } } return 0; }

static Rect fitEllipse_check( vector<Point> contour ) { Mat pointsf; Mat(contour).convertTo(pointsf, CV_32F); RotatedRect box = fitEllipse(pointsf); //cout << box.size << " " << box.size <<endl; return box.boundingRect(); if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*2 ) return Rect(-1,-1,0,0); else return box.boundingRect(); }

/******************************************************************************* * Function: thresholdByAreaRatioVar * Description: thresholds the FG targets by area, aspect ratio and variance * Arguments: minArea - minimum area to preserve maxArea - maximum area to preserve dilateSESize - structuring element size for dilation erodeSESize - structuring element size for erosion minAspRatio - minimum aspect ratio maxAspRatio - maximum aspect ratio varThresh - value of variance threshold * Returns: void * Comments: * Revision: *******************************************************************************/ void FGExtraction::thresholdByAreaRatioVar(double minArea, double maxArea, int dilateSESize, int erodeSESize, double minAspRatio, double maxAspRatio, int varThresh) { bool passArea, passRatio, passVar; vector<vector<Point> > contours; // connect separate parts before finding connected components Mat dilateSE = getStructuringElement(MORPH_ELLIPSE, Size(dilateSESize, dilateSESize)); Mat erodeSE = getStructuringElement(MORPH_ELLIPSE, Size(erodeSESize, erodeSESize)); dilate(_fgImg, _fgImg, dilateSE); erode(_fgImg, _fgImg, erodeSE); // extract contours of targets Mat tempImg = _fgImg.clone(); findContours(tempImg, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point()); tempImg.release(); for(size_t i = 0; i < contours.size(); ++i){ passArea = passRatio = passVar = false; double area = contourArea(contours[i]); // check if the area is within the desired range if (contours[i][0].y > 0.35*_fgImg.rows && contours[i][0].y < 0.68*_fgImg.rows && area > 0.1*minArea && area < maxArea || area > minArea && area < maxArea) passArea = true; // check if the aspect ratio is within the desired range RotatedRect orientedRect = orientedBoundingBox(contours[i]); Point2f rectPoints [4]; orientedRect.points(rectPoints); double rectWidth = norm(rectPoints[0] - rectPoints[1]); double rectHeight = norm(rectPoints[1] - rectPoints[2]); double aspRatio = max(rectWidth / rectHeight, rectHeight / rectWidth); if (aspRatio > minAspRatio && aspRatio < maxAspRatio) passRatio = true; // check if the variance of pixel exceeds the threshold // TODO ... passVar = true; // remove the target if any of the tests fails if(!passArea || !passRatio || !passVar){ //Rect uprightRect = boundingRect(Mat(contours[i])); //rectangle(_fgImg, uprightRect, Scalar(0), -1); drawContours(_fgImg, contours, i, Scalar(0), -1); } } /*namedWindow("fgImg", 0); imshow("fgImg", _fgImg); waitKey(0);*/ }

/** * This is a (modified) test program written by Michael Young * (https://github.com/ayoungprogrammer/WebcamCodeScanner). It was modified to * work with the Raspicam. */ int main(int argc, char* argv[]) { PiCamera cam; // open the video camera no. 0 ImageScanner scanner; scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1); namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo" while (1) { Mat frame = cam.Snap(); Mat grey; cvtColor(frame,grey,CV_BGR2GRAY); int width = frame.cols; int height = frame.rows; uchar *raw = (uchar *)grey.data; // wrap image data zbar::Image image(width, height, "Y800", raw, width * height); // scan the image for barcodes int n = scanner.scan(image); // extract results for(Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol) { vector<Point> vp; // do something useful with results cout << "decoded " << symbol->get_type_name() << " symbol \"" << symbol->get_data() << '"' <<" "<< endl; int n = symbol->get_location_size(); for(int i=0;i<n;i++){ vp.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i))); } RotatedRect r = minAreaRect(vp); Point2f pts[4]; r.points(pts); for(int i=0;i<4;i++){ line(frame,pts[i],pts[(i+1)%4],Scalar(255,0,0),3); } } imshow("MyVideo", frame); //show the frame in "MyVideo" window if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop { cout << "esc key is pressed by user" << endl; break; } } return 0; }

void get_min_box(vector<Point> r, RotatedRect box) { if ((box.size.width < 500) && (box.size.width < 500)) { if (min_rect.size() == 0) { // first rect min_rect.push_back(box); min_r.push_back(r); } else { // every other rect bool is_inside = true; for (int i = 0; i < int(min_rect.size()); ++i) { if (box.boundingRect().contains(min_rect[i].center)) { // if hierachical boxes break; else add box is_inside = true; break; } else { is_inside = false; } } if (is_inside == false) { min_rect.push_back(box); min_r.push_back(r); } } } }

bool contains(RotatedRect rect, Point pt) { Point2f vertices[4]; rect.points(vertices); bool chk = true; for (int i = 0; i < 4; ++i) { float m = (vertices[i].y - vertices[(i+1) % 4].y)/(vertices[i].x - vertices[(i+1) % 4].x); float c = vertices[i].y - m*vertices[i].x; float val_pt = pt.y - m*pt.x - c; float val_center = rect.center.y - m*rect.center.x - c; if (val_pt * val_center > 0) chk = true; else { chk = false; break; } } return chk; }

void drawRotatedRect(Mat* img, RotatedRect rect, Scalar color, int thickness) { Point2f rect_points[4]; rect.points( rect_points ); for( int j = 0; j < 4; j++ ) line( *img, rect_points[j], rect_points[(j+1)%4], color, thickness, 8 ); }

double xyVision::GetTarget::computeRotatedRect(const vector<Point>& contour, cv::Size sz, RotatedRect box, Mat& bi) { Point2f vertices[4]; box.points(vertices); Point points[4]; unsigned int i = 0; for (int i = 0; i < 4; ++i) { points[i] = Point((int)vertices[i].x, (int)vertices[i].y); } Mat tmp = Mat::zeros(sz, CV_8U); cv::fillConvexPoly(tmp, points, 4, Scalar(1)); Mat boxIdx; findNonZero(tmp, boxIdx); double n_pixels = (double)boxIdx.total(); double n_nonZero = 0; for (i = 0; i < boxIdx.total(); ++i) { Point _p = boxIdx.at<Point>(i); if (bi.at<unsigned char>(_p.y, _p.x) > 0) { n_nonZero = n_nonZero + 1; } } return n_nonZero / (n_pixels+1e-5); }

void dispRotatedRectangle(RotatedRect rect, Mat & frame) { Point2f vertices[4]; rect.points(vertices); for (int i = 0; i < 4; i++) line(frame, vertices[i], vertices[(i+1)%4], Scalar(0,255,0)); }

bool compareRects(RotatedRect a, RotatedRect b) { double areaa = 0.0; double areab = 0.0; Point2f ptsa[4]; Point2f ptsb[4]; a.points(ptsa); b.points(ptsb); areaa = (sqrt(pow(ptsa[0].x - ptsa[1].x,2) + pow(ptsa[0].y - ptsa[1].y,2) ) * sqrt(pow(ptsa[1].x - ptsa[2].x,2) + pow(ptsa[1].y - ptsa[2].y,2) ) ); areab = (sqrt(pow(ptsb[0].x - ptsb[1].x,2) + pow(ptsb[0].y - ptsb[1].y,2) ) * sqrt(pow(ptsb[1].x - ptsb[2].x,2) + pow(ptsb[1].y - ptsb[2].y,2) ) ); return (areaa > areab) ? true : false; }

Mat visionUtils::drawRotatedRect(Mat image, RotatedRect rRect, Scalar colourIn) { Point2f vertices[4]; rRect.points(vertices); for (int i = 0; i < 4; i++) line(image, vertices[i], vertices[(i+1)%4], colourIn, 3); //Scalar(0,255,0)); return image; }

//***** DRAW GRIPPER void Detection::drawGripper(Mat img, Point2i center, Rect rect, float angle) { RotatedRect rRect = RotatedRect(center, Size2f(rect.width, rect.height), angle); CString str; str.Format(_T("%d"), center.x); //AfxMessageBox(str); if (sample.size() < sampleSize && this->hasVision) { sample.push_back(Point2i(center.x, center.y)); CString str; str.Format(_T("%d"), sample[sample.size()-1]); //AfxMessageBox(str); } Point2f vertices[4]; rRect.points(vertices); for (int i = 0; i < 4; i++) line(img, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0)); }

int main( int argc, char** argv ) { Mat img(500, 500, CV_8UC3); RNG& rng = theRNG(); help(); for(;;) { int i, count = rng.uniform(1, 101); vector<Point> points; for( i = 0; i < count; i++ ) { Point pt; pt.x = rng.uniform(img.cols/4, img.cols*3/4); pt.y = rng.uniform(img.rows/4, img.rows*3/4); points.push_back(pt); } RotatedRect box = minAreaRect(Mat(points)); Point2f center, vtx[4]; float radius = 0; minEnclosingCircle(Mat(points), center, radius); box.points(vtx); img = Scalar::all(0); for( i = 0; i < count; i++ ) circle( img, points[i], 3, Scalar(0, 0, 255), CV_FILLED, CV_AA ); for( i = 0; i < 4; i++ ) line(img, vtx[i], vtx[(i+1)%4], Scalar(0, 255, 0), 1, CV_AA); //circle(img, center, cvRound(radius), Scalar(0, 255, 255), 1, CV_AA); imshow( "rect & circle", img ); char key = (char)cvWaitKey(); if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC' break; } return 0; }

geometry_msgs::Pose getFeature(Mat img, Mat dst, Scalar low, Scalar high, Scalar draw) { // Threshold image Mat bw, hsv; cv::cvtColor(img, hsv, CV_BGR2HSV); vector<vector<Point> > contours; inRange(hsv, low, high, bw); findContours(bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); for(size_t i=0; i < contours.size(); i++) { double area = contourArea(contours[i]); // Ensure minimum area and symmetry for circles if(area > 200){ RotatedRect minEllipse; minEllipse = fitEllipse(Mat(contours[i])); double eW = minEllipse.boundingRect().width; double eH = minEllipse.boundingRect().height; if(abs(eW-eH)<6){ ellipse(dst, minEllipse, draw, 2, 8); cv::imshow("Range window", dst); cv::imshow("HSV window", hsv); geometry_msgs::Point pt; geometry_msgs::Quaternion q; pt.x = minEllipse.center.y; pt.y = minEllipse.center.x; pt.z = 0.0; geometry_msgs::Pose p; p.position = pt; p.orientation = q; return p; } } } cv::imshow("Range window", dst); cv::imshow("HSV window", hsv); return geometry_msgs::Pose(); }

///////////////////////////////////////////////////////////////////// // showimgcontours() // Description: This function finds the largest contour in original // and draws the minimum bounding rectangle on the same image. As // you can see the original image is passed by reference so the // calling function receieves the modified image on which the // minimum area rectangle is drawn. //////////////////////////////////////////////////////////////////// void showimgcontours(Mat &threshedimg, Mat &original) { vector<vector<Point> > contours; RotatedRect rect; vector<Vec4i> hierarchy; Point2f rectPoints[4]; Scalar color = Scalar(255, 0, 0); double largest_area = 0; int largest_contour_index = 0; findContours(threshedimg, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); //this will find largest contour for (size_t i = 0; i< contours.size(); i++) // iterate through each contour. { double a = contourArea(contours[i], false); // Find the area of contour if (a>largest_area) { largest_area = a; largest_contour_index = i; //Store the index of largest contour } } //search for largest contour has end if (contours.size() > 0) { drawContours(original, contours, largest_contour_index, CV_RGB(0, 255, 0), 2, 8, hierarchy); //if want to show all contours use below one //drawContours(original,contours,-1, CV_RGB(0, 255, 0), 2, 8, hierarchy); // Find and add bounding rectangle rect = minAreaRect(contours[largest_contour_index]); rect.points(rectPoints); int j = 0; for (j; j < 4; j++) line(original, rectPoints[j], rectPoints[(j + 1) % 4], color, 1, 8); string strDim = "Min Area Rectangle Dimensions:\n" + to_string(rect.size.height) + " x " + to_string(rect.size.width); imshow("Largest Contour", original); ShowMessage(strDim); } }

Target getTarget(vector <Point> points) { convexHull(Mat(points), points); RotatedRect rect = minAreaRect(Mat(points)); Target t; t.x = rect.center.x; t.y = rect.center.y; t.width = ((rect.size.width>rect.size.height) ? rect.size.width : rect.size.height); t.height = ((rect.size.width>rect.size.height) ? rect.size.height : rect.size.width); t.angle = ((rect.size.width>rect.size.height) ? rect.angle : (rect.angle+90)); Point2f rectPoints[4]; rect.points(rectPoints); for (int i = 0; i < 4; i++) { t.pointsX[i] = rectPoints[i].x; t.pointsY[i] = rectPoints[i].y; } t.area = contourArea(points); t.ratio = t.width / (float)t.height; t.dist = 0; t.distError = 0; // Don't worry, I'm always right return t; }

int FeatureExtract(Mat &Input,Mat FeaturePoints,Mat &Output){ /*-----------------minAreaRect-----------------------*/ RotatedRect box = minAreaRect(FeaturePoints); Point2f vtx[4]; box.points(vtx);//get the vertices of rectangle for( int i = 0; i < 4; i++ ) { line(Input, vtx[i], vtx[(i+1)%4], Scalar(255), 1, CV_AA); } Output=Input; /*------------------Hu Moments----------------------*/ Moments h; double hu[7]; h=moments(Input,false); HuMoments(h,hu); /*-----------------------Area of Hand------------------*/ double HandArea=FeaturePoints.total(); /*-------------------Area of minRect--------------------*/ double leng=sqrt((vtx[0].x-vtx[1].x)*(vtx[0].x-vtx[1].x)+(vtx[0].y-vtx[1].y)*(vtx[0].y-vtx[1].y)); double width=sqrt((vtx[1].x-vtx[2].x)*(vtx[1].x-vtx[2].x)+(vtx[1].y-vtx[2].y)*(vtx[1].y-vtx[2].y)); double MinrectArea=leng*width; double ratio=HandArea/MinrectArea; double feature[5]={hu[0],hu[1],hu[2],hu[3],ratio}; /*----------------write into a txt file-------------------*/ WriteIntoTxt(feature); return 1; }

static bool is_right_lean(const RotatedRect &rotated_rect) { Point2f vertices[4]; rotated_rect.points(vertices); vector<Point2f> points; for(int i=0; i<4; ++i) { points.push_back(vertices[0]); } sort(points.begin(), points.end(), compare_y_func); return points[0].x + points[1].x > 2 * rotated_rect.center.x; }

/** Only keep the pixels of a image that lay inside a bounding rect @param src: A image with no type restrictions @param dst The src image after applying the mask @param boundingRect: The shape of the mask */ void applyRectangleMask(const cv::Mat& src, cv::Mat& dst, RotatedRect boundingRect) { Mat rectMask = Mat::zeros(src.size(), CV_8UC1); Point2f vertices2f[4]; Point vertices[4]; boundingRect.points(vertices2f); for (int i = 0; i < 4; i++) { vertices[i] = vertices2f[i]; line(rectMask, vertices2f[i], vertices2f[(i + 1) % 4], Scalar(255)); } cv::fillConvexPoly(rectMask, vertices, 4, cv::Scalar(255)); src.copyTo(dst, rectMask); }

Mat CControl::GetSubsetImg(RotatedRect n_rotatedrect) { // cout<<n_rotatedrect<<endl; //根据旋转矩形，从nimgraw中获得新图像。 //获得边界矩形。 Rect n_boundrect=n_rotatedrect.boundingRect(); //将边界在原图像上画出。 Point2f vertices[4]; n_rotatedrect.points(vertices); // Mat n_imgraw; // nImgRaw.copyTo(n_imgraw); // for (int i = 0; i < 4; i++) // line(n_imgraw, vertices[i], vertices[(i+1)%4], Scalar(0,255,0)); // imshow("raw",n_imgraw); //获得子图像。 Mat n_boundmatemp=nImgRaw(n_boundrect); Mat n_boundmat; n_boundmatemp.copyTo(n_boundmat); // imshow("prerotated",n_boundmat); //获得旋转变换参数矩阵 //这里的中心不再是原图像的中心，而是子图的中心。(原中心-左上角） Point2f n_pt1=n_rotatedrect.center; Point2f n_pt2=n_boundrect.tl(); Point2f n_ptcenter=n_pt1-n_pt2; Mat n_rotatematparam=getRotationMatrix2D(n_ptcenter,n_rotatedrect.angle,1.0); //进行仿射变换。 Mat n_rotatedMat; warpAffine(n_boundmat, n_rotatedMat,n_rotatematparam,n_boundmat.size(),INTER_CUBIC); //截取子图像。 Mat n_croppedmat; Size n_subsize(nControlOptions.nWidth,nControlOptions.nHeight); getRectSubPix(n_rotatedMat,n_subsize,n_ptcenter,n_croppedmat); // imshow("rotated",n_croppedmat); // waitKey(0); return n_croppedmat; }

int track(Mat &image,Rect &rect) { int status=0; cvtColor(image, hsv, CV_BGR2HSV_FULL); selection=rect; if(rect.width!=0&&rect.height!=0) { if(trackObject==false) buildHistogram (); if(trackObject==true) { Rect trackWindow=selection; Mat backproj=calcProbability (); RotatedRect trackBox = CamShift(backproj,trackWindow,TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); if( trackWindow.area() <= 1 ) { int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6; trackWindow = Rect(0,0,0,0); trackObject=false; } else { Point2f rect_points[4]; trackBox.points( rect_points ); for( int j = 0; j < 4; j++ ) line( image, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8 ); } } } else { trackObject=false; } status=1; return status; }

void CoreApplication::saveOldVideo(QString path) { emit processStatusChanged(CoreApplication::SAVE_VIDEO, true); VideoWriter record(path.toStdString(), videoFourCCCodec,25,originalVideo->getSize()); assert(record.isOpened()); for (int f = 0; f < originalVideo->getFrameCount(); f++) { emit processProgressChanged((float)f/originalVideo->getFrameCount()); const Frame* frame = originalVideo->getFrameAt(f); Mat image = frame->getOriginalData().clone(); const Rect_<int>& cropBox = originalVideo->getCropBox(); if (f == 0) { cv::rectangle(image, cropBox, Scalar(0,255,0), 3); } else { const Mat& update = frame->getUpdateTransform(); RotatedRect newCrop = Tools::transformRectangle(update, cropBox); Point2f verts[4]; newCrop.points(verts); for (int i = 0; i < 4; i++) { line(image, verts[i], verts[(i+1)%4], Scalar(0,255,0),3); } } record << image; } emit processStatusChanged(CoreApplication::SAVE_VIDEO, false); }