//-------------自动打击函数-----------------------------------------
//-------------自动打击   函数  全局变量----------------------------------
//-------------自动打击   函数  全局变量----------------------------------
//------------------------自动打击  全局变量----------------------
#define color 1//1red 0blue
#define pi 3.14
#define match_num 5
#define height_threshold 0
#define distance_single_value 10
#define distance_multiple_value 10
#define drift_angle 18
#define a_r_final 3.3
#define a_r_b_max 5.5
#define a_r_b_min 4.1
#define a_r_s_max 3.5
#define a_r_s_min 1.3
#define o_r_max 2
#define o_r_min 0.5
#define x_multiple 2.2
#define y_multiple 3.5
#define r_r_max 2
#define r_r_min 0.5
#define similar_degree 0.85
#define area_value_min 50//40 2.3m 50 2.0m 70 1.7m
#define color_threshold 160
#define blueratio 0.2
#define blueratio2 0.2
#define redratio 0.3
#define redratio2 0.25
#define anglediff1 6
#define anglediff2 7
#define limit 1
#define horizontal_angle_thres 5

Mat model, element1, element2;
Point2f center, store_tem;  //center实时中心点,store_tem临时存放中心点。
Rect external_rect, rect1, rect2, rect3, rect4, rect5, rrr, rect6, rect7, rect8, rect9, box;
float distancee, area;
int flag = 0;
int detection_flag=0;

float Max, a_r, o_r, r_r, angle_first, angle_second;
float horizontal_angle;
vector<Point> points1, points2, points3, points4, points5;

Mat Matrix=(Mat_<double>(3,3)<<501.9406,0.0,330.2514,0.0,502.2422,234.5579,0.0,0.0,1.0);
Mat coefficients=(Mat_<double>(5,1)<<0.0266,-0.0613,0.0,0.0,-0.0015);
// int stateNum = 2;
// int measureNum = 1;
// KalmanFilter KF(stateNum, measureNum, 0);
// //Mat processNoise(stateNum, 1, CV_32F);
// Mat measurement = Mat::zeros(measureNum, 1, CV_32F);
// //KF.transitionMatrix = (Mat_<float>(stateNum, stateNum) << 1, 0, 1, 0,//A 状态转移矩阵
// //        0, 1, 0, 1,
// //        0, 0, 1, 0,
// //        0, 0, 0, 1);
// KF.transitionMatrix = (Mat_<float>(stateNum, stateNum) << 1, 1, 0, 1);
// //这里没有设置控制矩阵B,默认为零
// setIdentity(KF.measurementMatrix);//H=[1,0,0,0;0,1,0,0] 测量矩阵
// setIdentity(KF.processNoiseCov, Scalar::all(1e-5));//Q高斯白噪声,单位阵
// setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));//R高斯白噪声,单位阵
// setIdentity(KF.errorCovPost, Scalar::all(1));//P后验误差估计协方差矩阵,初始化为单位阵
// randn(KF.statePost, Scalar::all(0), Scalar::all(0.1));

//两点距离
float juli(Point aa, Point bb)
{
    double sd;
    sd = sqrt((aa.x - bb.x)*(aa.x - bb.x) + (aa.y - bb.y)*(aa.y - bb.y));
    return sd;
}
//判断是否为红色
double colorRatioR(Mat pic1, Mat pic2)
{
    double sum1 = 0, sum2 = 0;
    double ratio;
    /*-------遍历两张图片中间一列的红色分量-------*/
    for (int t = 0; t < pic1.rows; t++)//逐行遍历
    {
        sum1 = sum1 + pic1.at<Vec3b>(t, pic1.cols/2)[2] / 255;  //每一行中点的像素红色分量除以255的比值
    }
    for (int t = 0; t < pic2.rows; t++)//逐行遍历
    {
        sum2 = sum2 + pic2.at<Vec3b>(t, pic2.cols/2)[2] / 255;  //每一行中点的像素红色分量除以255的比值
    }
    /*-------遍历两张图片中间一列的红色分量-------*/
    ratio = (sum1 / (pic1.rows) + sum2 / (pic2.rows) ) / 2;//ratio:取值范围0~1
    return ratio;
}
//判断是否为蓝色
double colorRatioB(Mat pic1, Mat pic2)
{
    double sum1 = 0, sum2 = 0;
    double ratio;
     /*-------遍历两张图片中间一列的蓝色分量-------*/
    for (int t = 0; t < pic1.rows; t++)
    {
        sum1 = sum1 + pic1.at<Vec3b>(t, pic1.cols/2)[0] / 255;//每一行中点的像素蓝色分量除以255的比值
    }
    for (int t = 0; t < pic2.rows; t++)
    {
        sum2 = sum2 + pic2.at<Vec3b>(t, pic2.cols/2)[0] / 255;//每一行中点的像素蓝色分量除以255的比值
    }
     /*-------遍历两张图片中间一列的蓝色分量-------*/
    ratio = (sum1 / (pic1.rows) + sum2 / (pic2.rows)) / 2;//ratio:取值范围0~1
    return ratio;
}

double colorRatioHSV(Mat pic1, Mat pic2)    //瘦高矩形内核
{
    Mat element = getStructuringElement(MORPH_RECT, Size(1,7));
    erode(pic1,pic1,element);
    erode(pic2,pic2,element);
    cvtColor(pic1,pic1,CV_BGR2HSV);
    cvtColor(pic2,pic2,CV_BGR2HSV);
    double sum1 = 0, sum2 = 0;
    double ratio;
    for (int t = 0; t < pic1.rows; t++)
    {
        for (int tt = 0; tt < pic1.cols; tt++)
        {
            sum1 = sum1 + pic1.at<Vec3b>(t, tt)[0]; //蓝色
        }
    }
    for (int t = 0; t < pic2.rows; t++)
    {
        for (int tt = 0; tt < pic2.cols; tt++)
        {
            sum2 = sum2 + pic2.at<Vec3b>(t, tt)[0];
        }
    }
    ratio = (sum1 / (pic1.rows*pic1.cols) + sum2 / (pic2.rows*pic2.cols) ) / 2;
    return ratio;
}

double colorRatioHSV_S(Mat pic1, Mat pic2)  //正方形内核
{
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
    erode(pic1, pic1, element);
    erode(pic2, pic2, element);
    cvtColor(pic1, pic1, CV_BGR2HSV);
    cvtColor(pic2, pic2, CV_BGR2HSV);
    double sum1 = 0, sum2 = 0;
    double ratio;
    for (int t = 0; t < pic1.rows; t++)
    {
        for (int tt = 0; tt < pic1.cols; tt++)
        {
            sum1 = sum1 + pic1.at<Vec3b>(t, tt)[1]; //绿色
        }
    }
    for (int t = 0; t < pic2.rows; t++)
    {
        for (int tt = 0; tt < pic2.cols; tt++)
        {
            sum2 = sum2 + pic2.at<Vec3b>(t, tt)[1];
        }
    }
    ratio = (sum1 / (pic1.rows*pic1.cols) + sum2 / (pic2.rows*pic2.cols)) / 2;
    return ratio;
}

Mat pretreat(Mat picture)
{
    Mat out;
    cvtColor(picture, out, CV_BGR2GRAY);
    Mat element1, element2;
    threshold(out, out, color_threshold, 255, CV_THRESH_BINARY);
    element1 = getStructuringElement(MORPH_RECT, Size(1, 5));
    erode(out, out, element1);
    element2 = getStructuringElement(MORPH_RECT, Size(3, 7));
    dilate(out, out, element2);
    //imshow("out",out);
    return out;
}

//水平角
double hor_angle(Point p1, Point p2)
{
    int a, b;
    double rad, angle;
    a = abs(p1.x - p2.x);
    b = abs(p1.y - p2.y);
    if (a != 0) //a==0除法会炸
    {
        rad = atan(b / a);  //坡角,单位为rad
        angle = rad * 180 / pi; //坡度
    }
    else
        angle = 90;
    return angle;
};

int auto_shot(Mat frame)
{
    Mat temp_frame = frame.clone();
    Mat src=pretreat(frame);
    vector<vector<Point> > contours;
    findContours(src, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    vector<RotatedRect> ellipsee(contours.size());
    int array1[1000];
    int count1 = 0;
    for (int i0 = 0; i0 < contours.size(); i0++)
    {
        if (contours[i0].size() < 5)
            continue;
        ellipsee[i0] = fitEllipse(contours[i0]);
        external_rect = ellipsee[i0].boundingRect();
        area = external_rect.area();
        if (area>30 && external_rect.height > height_threshold && (double)external_rect.height / (double)external_rect.width>1.8 && (ellipsee[i0].angle<drift_angle || ellipsee[i0].angle>(180 - drift_angle)))
        {
            points1.push_back(Point(ellipsee[i0].center));
            array1[count1] = i0;
            count1++;
        if(count1>999)
        {break;}
        }
    }
    int count2 = 0;
    int array2[2000];
    for (int i1 = 0; i1 < count1; i1++)
    {
        for (int j1 = i1 + 1; j1 < count1; j1++)
        {
            horizontal_angle = hor_angle(points1[i1], points1[j1]);
            if (horizontal_angle < horizontal_angle_thres)
            {
                points2.push_back(points1[i1]);
                points2.push_back(points1[j1]);
                array2[2 * count2] = array1[i1];
                array2[2 * count2 + 1] = array1[j1];
                count2++;
                if(count2>999)
                    {break;}
            }
        }
        if(count2>999)
            {break;}
    }
    int array3[1000];
    int count3 = 0;
    for (int i2 = 0; i2 < count2; i2++)
    {
        int label = 0;
        rect1 = boundingRect(contours[array2[i2 * 2]]);
        rect2 = boundingRect(contours[array2[i2 * 2 + 1]]);
        rect3 = rect1 | rect2;  //求两个矩形的并集
        for (int ii = 0; ii < points1.size(); ii++)
            label = label + rect3.contains(points1[ii]);
        if (label == 2)
        {
            points3.push_back(points2[i2 * 2]);
            points3.push_back(points2[i2 * 2 + 1]);
            array3[count3 * 2] = array2[i2 * 2];
            array3[count3 * 2 + 1] = array2[i2 * 2 + 1];
            count3++;
            if(count3>499)
            {break;}
        }
        else
            label = 0;
    }
    int array4[1000];
    int count4 = 0;
    for (int i3 = 0; i3 < count3; i3++)
    {
        rect4 = boundingRect(contours[array3[i3 * 2]]);
        rect5 = boundingRect(contours[array3[i3 * 2 + 1]]);
        rrr = rect4 | rect5;

        Max = max((double)rect4.height, (double)rect5.height);
        a_r = rrr.width / Max;  //即使正对,装甲板相对地面必定是倾斜的,灯条也就会倾斜一点,所以包围的矩形rrr比两者最大值会大一点
        o_r = (double)rect4.height / (double)rect5.height;  //两个灯条宽度比,上一步进行限制后可以看成是两个灯条大小比
        r_r = ((double)rect4.height / (double)rect4.width) / ((double)rect5.height / (double)rect5.width);  //两个灯条长宽比例
        angle_first = ellipsee[array3[i3 * 2]].angle;   //偏转角度
        angle_second = ellipsee[array3[i3 * 2 + 1]].angle;  //偏转角度
        //rectangle(frame, rrr, 255, 1, 1);

        double s = colorRatioHSV_S(frame(rect4), frame(rect5));     //用3*3腐蚀+hsv绿色找出蓝色分量
        //double hsv = colorRatioHSV(frame(rect4), frame(rect5));   //用1*7腐蚀+hsv蓝色分量。。。然后不成功?

        double red = colorRatioR(temp_frame(rect4), temp_frame(rect5));
        double blue = colorRatioB(temp_frame(rect4), temp_frame(rect5));
        if (color == 1 && s>43)
        {
            if (a_r < a_r_s_max && a_r > a_r_s_min)
            {
                if (red > blue && red > redratio && blue < limit && (abs(angle_first - angle_second) < anglediff1 || abs(angle_first - angle_second) > (180 - anglediff1))
                    && rrr.height > height_threshold && o_r < o_r_max && o_r > o_r_min && r_r < r_r_max && r_r > r_r_min && (rect4.area()>area_value_min || rect5.area()>area_value_min))
                {
                    //cout << a_r <<"  1"<<endl;
                    //cout<<red<<"  "<<blue<<"  "<<white<<endl;
                    points4.push_back(points3[i3 * 2]);
                    points4.push_back(points3[i3 * 2 + 1]);
                    array4[2 * count4] = array3[i3 * 2];
                    array4[2 * count4 + 1] = array3[i3 * 2 + 1];
                    count4++;
                }
            }
            if (a_r > a_r_b_min && a_r < a_r_b_max)
            {
                if (red > blue && red > redratio2 && blue < limit && (abs(angle_first - angle_second) < anglediff2 || abs(angle_first - angle_second) > (180 - anglediff2))
                    && rrr.height > height_threshold && o_r < o_r_max && o_r > o_r_min && r_r < r_r_max && r_r > r_r_min)
                {
                    //cout << a_r << "  2" << endl;
                    //cout<<red<<"  "<<blue<<"  "<<white<<endl;
                    points4.push_back(points3[i3 * 2]);
                    points4.push_back(points3[i3 * 2 + 1]);
                    array4[2 * count4] = array3[i3 * 2];
                    array4[2 * count4 + 1] = array3[i3 * 2 + 1];
                    count4++;
                }
            }
        }
        if (color == 0)
        {
            //cout << a_r << endl;
            if (a_r < a_r_s_max && a_r > a_r_s_min)
            {
                if (((red < blue && blue > blueratio) || (red == blue)) && (abs(angle_first - angle_second) < anglediff1 || abs(angle_first - angle_second) > (180 - anglediff1))
                    && rrr.height > height_threshold && o_r < o_r_max && o_r > o_r_min && r_r < r_r_max && r_r > r_r_min && (rect4.area()>area_value_min || rect5.area()>area_value_min))
                {
                    //cout<<red<<"  "<<blue<<"  "<<white<<endl;
                    points4.push_back(points3[i3 * 2]);
                    points4.push_back(points3[i3 * 2 + 1]);
                    array4[2 * count4] = array3[i3 * 2];
                    array4[2 * count4 + 1] = array3[i3 * 2 + 1];
                    count4++;
                }
            }
            if (a_r > a_r_s_max && a_r < a_r_b_max)
            {
                if (red < blue && blue > blueratio2 && (abs(angle_first - angle_second) < anglediff2 || abs(angle_first - angle_second) > (180 - anglediff2))
                    && rrr.height > height_threshold && o_r < o_r_max && o_r > o_r_min && r_r < r_r_max && r_r > r_r_min)
                {
                    //cout<<red<<"  "<<blue<<"  "<<white<<endl;
                    points4.push_back(points3[i3 * 2]);
                    points4.push_back(points3[i3 * 2 + 1]);
                    array4[2 * count4] = array3[i3 * 2];
                    array4[2 * count4 + 1] = array3[i3 * 2 + 1];
                    count4++;
                }
            }
        }
    }

    int sizer = 3;//1big 0small
    int mark = 1;
    int markk = 1;
    Point point_temp1, point_temp2, temp;

    Mat trans = (Mat_<float>(3, 1));
    Mat r;
    Mat_<float> zuo;
    vector<cv::Point3f> point3d_da;
    vector<cv::Point2f> point2d_da;
    Point3f daji_3d;
    point3d_da.push_back(Point3f(-6.5, 3, 0));
    point3d_da.push_back(Point3f(6.5, 3, 0));
    point3d_da.push_back(Point3f(6.5, -3, 0));
    point3d_da.push_back(Point3f(-6.5, -3, 0));     //

    Point zs, ys, yx, zx;
    if (count4 > 1)     //识别装甲板数量大于1块
    {
        int aa, bb;     //aa,bb保存本次修改的索引
        int cc = 100, dd = 100;     //cc,dd备份装甲板灯条在总轮廓中的索引。赋值100是为了下面cc*dd》9999的条件
        if (flag == 1)  //是否能发弹标志
        {
            for (int i4 = 0; i4 < points4.size() / 2; i4++)
            {
                point_temp1.x = points4[2 * i4].x;
                point_temp2.x = points4[2 * i4 + 1].x;
                point_temp1.y = points4[2 * i4].y;
                point_temp2.y = points4[2 * i4 + 1].y;
                temp.x = (point_temp1.x + point_temp2.x) / 2;   //本次装甲板中心x
                temp.y = (point_temp1.y + point_temp2.y) / 2;   //本次装甲板中心y

                distancee = juli(store_tem, temp);  //计算storetem和本次装甲板中心的距离
                if (distancee < distance_multiple_value)    //如果两个装甲板的距离不超过distance_multiple_value,说明移动幅度不大,继续更新
                {    //把本次的值保存到aa,bb,cc,dd
                    aa = i4 * 2;
                    bb = i4 * 2 + 1;
                    cc = array4[i4 * 2];
                    dd = array4[i4 * 2 + 1];
                }
            }
            if (cc*dd<9999) //大于10000则是初始化的情况
            {
                rect6 = boundingRect(contours[cc]);
                rect7 = boundingRect(contours[dd]);
                rect8 = rect6 | rect7;
//将装甲板四个顶点保存到point2d-da里
                zs = rect8.tl();
                yx = rect8.br();
                ys = zs + Point(rect8.width,0);
                zx = zs + Point(0,rect8.height);
                point2d_da.push_back(zs);
                point2d_da.push_back(ys);
                point2d_da.push_back(yx);
                point2d_da.push_back(zx);
            //姿态解算,利用平面已知四点坐标确定摄像头相对世界坐标系的平移和旋转
            //coefficients相机外参畸变系数
            //Matrix相机内参
            //point3d和point2d:2d-3d匹配点
                solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
                trans.convertTo(zuo, CV_32F);
                daji_3d.z = zuo.at<float>(0, 2);
//rect9:装甲板除去灯条的矩形,应该是想做数字识别
                rect9.x = rect8.x - ((x_multiple - 1) / 2)*rect8.width;
                rect9.y = rect8.y - ((y_multiple - 1) / 2)*rect8.height;
                rect9.width = rect8.width * x_multiple;
                rect9.height = rect8.height * y_multiple;
                if (rect8.height>height_threshold && rect8.x > 0 && rect8.x + rect8.width < 640 && rect8.y > 0 && rect8.y + rect8.height < 480)
                    model = src(rect8);
                center.x = (points4[aa].x + points4[bb].x) / 2;
                center.y = (points4[aa].y + points4[bb].y) / 2;
                  //顺便算出中心坐标
                flag = 1;
                mark = 1;
                //判断大小装甲
                if(rect8.width/rect8.height>a_r_final)
                    {sizer = 1;}
                if(rect8.width/rect8.height<a_r_final)
                    {sizer = 0;}
            }
            if (cc*dd>9999 && rect9.area() != 0 && rect8.area() != 0 && rect9.x > 0 && rect9.x + rect9.width<640 && rect9.y>0 && rect9.y + rect9.height < 480)
            {
                Mat similarity;
                matchTemplate(src(rect9), model, similarity, match_num);  //模板识别数字
                double mag_r;
                Point point;
                minMaxLoc(similarity, 0, &mag_r, 0, &point);   //找出极大值为mag-r的匹配的矩形的左上点,保存为point
                if (model.cols > height_threshold && mag_r > similar_degree)
                {
                    box.x = point.x + rect9.x;
                    box.y = point.y + rect9.y;
                    box.width = rect8.width;
                    box.height = rect8.height;
                    center.x = box.x + box.width / 2;
                    center.y = box.y + box.height / 2;
                    //rectangle(frame, box, Scalar(0, 0, 255), 2);
                    //进一步更新装甲板中心坐标
                    model = src(box);
                    rect9.x = box.x - ((x_multiple - 1) / 2)*box.width;
                    rect9.y = box.y - ((y_multiple - 1) / 2)*box.height;
                    rect9.width = box.width * x_multiple;
                    rect9.height = box.height * y_multiple;
                    flag = 1;
                    mark = 1;

                    zs = box.tl();
                    yx = box.br();
                    ys = zs + Point(box.width, 0);
                    zx = zs + Point(0, box.height);
                    point2d_da.push_back(zs);
                    point2d_da.push_back(ys);
                    point2d_da.push_back(yx);
                    point2d_da.push_back(zx);
                    solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
                    trans.convertTo(zuo, CV_32F);
                    daji_3d.z = zuo.at<float>(0, 2);
                        if(box.width/box.height>a_r_final)
                        {sizer = 1;}
                    if(box.width/box.height<a_r_final)
                        {sizer = 0;}
                }
                if (mag_r < similar_degree)
                {
                    flag = 0;
                    mark = 0;
                }
            }
        }
        if (flag == 0 && mark == 1)
        {
            rect6 = boundingRect(contours[array4[0]]);
            rect7 = boundingRect(contours[array4[1]]);
            rect8 = rect6 | rect7;

            zs = rect8.tl();
            yx = rect8.br();
            ys = zs + Point(rect8.width, 0);
            zx = zs + Point(0, rect8.height);
            point2d_da.push_back(zs);
            point2d_da.push_back(ys);
            point2d_da.push_back(yx);
            point2d_da.push_back(zx);
            solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
            trans.convertTo(zuo, CV_32F);
            daji_3d.z = zuo.at<float>(0, 2);

            rect9.x = rect8.x - ((x_multiple - 1) / 2)*rect8.width;
            rect9.y = rect8.y - ((y_multiple - 1) / 2)*rect8.height;
            rect9.width = rect8.width * x_multiple;
            rect9.height = rect8.height * y_multiple;
            if (rect8.height > height_threshold && rect8.x > 0 && rect8.x + rect8.width < 640 && rect8.y > 0 && rect8.y + rect8.height < 480)
                model = src(rect8);
            center.x = (points4[0].x + points4[1].x) / 2;
            center.y = (points4[0].y + points4[1].y) / 2;
              if(rect8.width/rect8.height>a_r_final)
                {sizer = 1;}
            if(rect8.width/rect8.height<a_r_final)
                {sizer = 0;}
            flag = 1;
        }
    }
    if (count4 == 1)
    {
        if (flag == 1)
        {
            center.x = (points4[0].x + points4[1].x) / 2;
            center.y = (points4[0].y + points4[1].y) / 2;
            distancee = juli(center, store_tem);
            if (distancee < distance_single_value)
            {
                rect6 = boundingRect(contours[array4[0]]);
                rect7 = boundingRect(contours[array4[1]]);
                rect8 = rect6 | rect7;

                zs = rect8.tl();
                yx = rect8.br();
                ys = zs + Point(rect8.width, 0);
                zx = zs + Point(0, rect8.height);
                point2d_da.push_back(zs);
                point2d_da.push_back(ys);
                point2d_da.push_back(yx);
                point2d_da.push_back(zx);
                solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
                trans.convertTo(zuo, CV_32F);
                daji_3d.z = zuo.at<float>(0, 2);

                rect9.x = rect8.x - ((x_multiple - 1) / 2)*rect8.width;
                rect9.y = rect8.y - ((y_multiple - 1) / 2)*rect8.height;
                rect9.width = rect8.width * x_multiple;
                rect9.height = rect8.height * y_multiple;
                if (rect8.height > height_threshold && rect8.x > 0 && rect8.x + rect8.width < 640 && rect8.y > 0 && rect8.y + rect8.height < 480)
                    model = src(rect8);
                    if(rect8.width/rect8.height>a_r_final)
                    {sizer = 1;}
                if(rect8.width/rect8.height<a_r_final)
                    {sizer = 0;}
                flag = 1;
                markk = 1;
            }
            if (distancee > distance_single_value)
            {
                if (rect9.area() != 0 && rect8.area() != 0 && rect9.x > 0 && rect9.x + rect9.width<640 && rect9.y>0 && rect9.y + rect9.height < 480)
                {
                    Mat similarity;
                    matchTemplate(src(rect9), model, similarity, match_num);
                    double mag_r;
                    Point point;
                    minMaxLoc(similarity, 0, &mag_r, 0, &point);
                    if (model.cols > height_threshold && mag_r > similar_degree)
                    {
                        box.x = point.x + rect9.x;
                        box.y = point.y + rect9.y;
                        box.width = rect8.width;
                        box.height = rect8.height;
                        center.x = box.x + box.width / 2;
                        center.y = box.y + box.height / 2;
                        rectangle(frame, box, Scalar(0, 0, 255), 2);
                        model = src(box);
                        rect9.x = box.x - ((x_multiple - 1) / 2)*box.width;
                        rect9.y = box.y - ((y_multiple - 1) / 2)*box.height;
                        rect9.width = box.width * x_multiple;
                        rect9.height = box.height * y_multiple;
                        flag = 1;
                        markk = 1;

                        zs = box.tl();
                        yx = box.br();
                        ys = zs + Point(box.width, 0);
                        zx = zs + Point(0, box.height);
                        point2d_da.push_back(zs);
                        point2d_da.push_back(ys);
                        point2d_da.push_back(yx);
                        point2d_da.push_back(zx);
                        solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
                        trans.convertTo(zuo, CV_32F);
                        daji_3d.z = zuo.at<float>(0, 2);
                              if(box.width/box.height>a_r_final)
                            {sizer = 1;}
                        if(box.width/box.height<a_r_final)
                            {sizer = 0;}
                    }
                    if (mag_r < similar_degree)
                    {
                        flag = 0;
                        markk = 0;
                    }
                }
            }
        }
        if (flag == 0 && markk == 1)
        {
            //自动补充
            rect6 = boundingRect(contours[array4[0]]);
            rect7 = boundingRect(contours[array4[1]]);
            rect8 = rect6 | rect7;

            zs = rect8.tl();
            yx = rect8.br();
            ys = zs + Point(rect8.width, 0);
            zx = zs + Point(0, rect8.height);
            point2d_da.push_back(zs);
            point2d_da.push_back(ys);
            point2d_da.push_back(yx);
            point2d_da.push_back(zx);
            solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
            trans.convertTo(zuo, CV_32F);
            daji_3d.z = zuo.at<float>(0, 2);

            rect9.x = rect8.x - ((x_multiple - 1) / 2)*rect8.width;
            rect9.y = rect8.y - ((y_multiple - 1) / 2)*rect8.height;
            rect9.width = rect8.width * x_multiple;
            rect9.height = rect8.height * y_multiple;
            if (rect8.height > height_threshold && rect8.x > 0 && rect8.x + rect8.width < 640 && rect8.y > 0 && rect8.y + rect8.height < 480)
                model = src(rect8);
            center.x = (points4[0].x + points4[1].x) / 2;
            center.y = (points4[0].y + points4[1].y) / 2;
            if(rect8.width/rect8.height>a_r_final)
                {sizer = 1;}
            if(rect8.width/rect8.height<a_r_final)
                {sizer = 0;}
            flag = 1;
        }
    }
    if (count4 < 1)
    {
        if (rect9.area() != 0 && rect8.area() != 0 && rect9.x > 0 && rect9.x + rect9.width<640 && rect9.y>0 && rect9.y + rect9.height < 480)
        {
            Mat similarity;
            matchTemplate(src(rect9), model, similarity, match_num);
            double mag_r;
            Point point;
            minMaxLoc(similarity, 0, &mag_r, 0, &point);
            if (model.cols > height_threshold && mag_r > similar_degree)
            {
                box.x = point.x + rect9.x;
                box.y = point.y + rect9.y;
                box.width = rect8.width;
                box.height = rect8.height;
                center.x = box.x + box.width / 2;
                center.y = box.y + box.height / 2;
                rectangle(frame, box, Scalar(0, 0, 255), 2);
                model = src(box);
                rect9.x = box.x - ((x_multiple - 1) / 2)*box.width;
                rect9.y = box.y - ((y_multiple - 1) / 2)*box.height;
                rect9.width = box.width * x_multiple;
                rect9.height = box.height * y_multiple;
                flag = 1;

                zs = box.tl();
                yx = box.br();
                ys = zs + Point(box.width, 0);
                zx = zs + Point(0, box.height);
                point2d_da.push_back(zs);
                point2d_da.push_back(ys);
                point2d_da.push_back(yx);
                point2d_da.push_back(zx);
                solvePnP(point3d_da, point2d_da, Matrix, coefficients, r, trans);
                trans.convertTo(zuo, CV_32F);
                daji_3d.z = zuo.at<float>(0, 2);
                if(box.width/box.height>a_r_final)
                {
                   sizer = 1;
                }
                if(box.width/box.height<a_r_final)
                    {sizer = 0;}
            }
            if (mag_r < similar_degree)
                flag = 0;
        }
    }

//一开始设置size=3
    if (center.x*center.y != 0 && sizer < 2)
    {
        flag = 1;
        circle(frame, center, 2, Scalar(255, 255, 255), 2, 2);

        if(sizer == 1)
            {daji_3d.z = daji_3d.z * 2;}
        if(sizer == 0)
            {daji_3d.z = daji_3d.z * 1.2;}
        enemy_msg.enemy_dist = daji_3d.z;
        enemy_msg.enemy_yaw = center.x-320;    //320为摄像头中心x坐标
        enemy_msg.enemy_pitch = center.y-240;    //同上
    cout << center.x << "    " << center.y << endl;
    ROS_INFO("write[%d]",center.x);   //发送数据
    detection_flag=1;
        //enemy_msg.mode=sizer;
    }
    else
    {
      flag = 0;
      center.x=1000;
      center.y=1000;
      daji_3d.z=1000;
      sizer=2;
      enemy_msg.enemy_dist = daji_3d.z;
      enemy_msg.enemy_yaw = center.x-320;
      enemy_msg.enemy_pitch = center.y-240;
      detection_flag=0;
      //enemy_msg.mode=sizer;
    }
    if_send=true;
    imshow("1", frame);
    waitKey(1);
    store_tem.x = center.x;
    store_tem.y = center.y;
    center.x = 0;
    center.y = 0;
    mark = 1;
    markk = 1;
    points1.clear();
    points2.clear();
    points3.clear();
    points4.clear();
    points5.clear();
    return 0;
}
//------------------------------------------------------------