• 实验6.2


    对6.1进行了一些优化

    题外话:
    稍加观察思索就会发现,我只测试了一个视频场景,而且这个场景是特意选择的。
    背景十分干净,是白色的墙壁,没有过多的干扰。我这个是不可能在雪地里追踪到白色的兔子的。我在测试的时候还发现,当我把矩形框框得比较大的时候,也就是包含的墙壁比较多,它就很大概率会丢失目标,开始乱跑。
    我这个做法是只处理了矩形框,如果是追踪⚽️等圆形物体, 我觉得圆形区域去追踪会更好一点。所以为了展示良好的效果,拍摄的目标被我刻意选择为了标准的矩形。

    #include <bits/stdc++.h>
    #include "opencv2/core.hpp"
    #include "opencv2/imgproc.hpp"
    #include "opencv2/video.hpp"
    #include "opencv2/objdetect.hpp"
    #include "opencv2/imgcodecs.hpp"
    #include "opencv2/highgui.hpp"
    #include "opencv2/ml.hpp"
    #define p(a) putchar(a)
    #define For(i,a,b) for(int i=a;i<=b;++i)
    
    using namespace std;
    using namespace cv;
    
    int w,h,w0,h0,bc0,bc1,cnt;
    double fps,part,diff,val;
    bool lu_flag,flag;
    Point lu,rd,mid,st,ed,best_st,best_ed;
    Mat temp,image,IMAGE,tb;
    MatND hist;
    
    int channels[] = {0,1,2};
    int SIZE[] = {32,32,32};
    float R[] = {0,255};
    float G[] = {0,255};
    float B[] = {0,255};
    const float *ranges[] = {R, G ,B};
    
    const char * path = "/Users/war/Downloads/track0.mp4";
    
    void in(int &x){
        int y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(int x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    void onMouse(int event, int x, int y, int flags, void *ustc){
        if(event == EVENT_LBUTTONDOWN){
            lu_flag = 1;
            lu = Point(x,y);
        }
        if(event == EVENT_MOUSEMOVE && lu_flag){
            temp = image.clone();
            rd = Point(x,y);
            if(lu != rd) rectangle(temp, lu, rd, Scalar(255, 0, 0), 3);
            imshow("temp",temp);
        }
        if(event == EVENT_LBUTTONUP){
            lu_flag = 0;flag = 1;
            rd = Point(x,y);
            IMAGE = image(Rect(lu, rd));
        }
    }
    
    void init(){
        VideoCapture video(path);
        if(!video.isOpened()){
            cout<<"视频打开失败!"<<endl;
            return;
        }
        fps = video.get(CAP_PROP_FPS);
        part = 1000.0 / fps;
        namedWindow("temp");
        setMouseCallback("temp", onMouse);
        while(1){
            if(!lu_flag) video >> image;
            if(!image.data || waitKey(part) == 27) break;
            imshow("temp",image);
            if(flag){
                destroyWindow("temp");
                break;
            }
        }
        video.release();
    }
    
    double cal(){
        Mat temp0;
        calcHist(&temp, 1, channels, Mat(), temp0, 3, SIZE, ranges, true, false);
        normalize(temp0, temp0, 0, 1, NORM_MINMAX);
        return compareHist(hist, temp0, 3);
    }
    
    void tracking(){
        w = abs(lu.x - rd.x);
        h = abs(lu.y - rd.y);
        auto x0 = lu.x - w;
        auto x1 = rd.x + w;
        auto y0 = rd.y - h;
        auto y1 = lu.y + h;
        x0 = max(0, x0);
        x1 = min(x1, image.cols);
        y0 = max(0, y0);
        y1 = min(y1, image.rows);
        VideoCapture video(path);
        if(!video.isOpened()){
            cout<<"视频打开失败!"<<endl;
            return;
        }
        fps = video.get(CAP_PROP_FPS);
        part = 1000.0 / fps;
        namedWindow("tracking");
        while(1){
            video >> image;
            if(!image.data || waitKey(part) == 27) break;
            diff = 1.0; bc0 = max(1 ,IMAGE.rows / 7); bc1 =  max(1,IMAGE.cols / 7);
            for(int i = y0; i <= y1; i += bc0){
                for(st.x=x0,st.y=i; st.x <= x1; st.x += bc1){
                    ed.x = min(st.x + w, image.cols-1);
                    ed.y = min(st.y + h, image.rows-1);
                    temp = image(Rect(st,ed));
                    val = cal();
                    if(diff > val){
                        diff = val;
                        best_st = st;
                        best_ed = ed;
                        tb = temp;
                    }
                }
            }
            if(diff < 0.5){
                x0 = best_st.x - w;
                x1 = best_ed.x + w;
                y0 = best_st.y - h;
                y1 = best_ed.y + h;
                x0 = max(0, x0);
                x1 = min(x1, image.cols);
                y0 = max(0, y0);
                y1 = min(y1, image.rows);
                rectangle(image, best_st, best_ed, Scalar(0, 0, 255), 3);
                if((++cnt)%10==0){
                    calcHist(&tb, 1, channels, Mat(), hist, 3, SIZE, ranges, true, false);
                    normalize(hist, hist, 0, 1, NORM_MINMAX);
                }
            }
            imshow("tracking",image);
        }
        video.release();
    }
    
    signed main(){
        init();
        calcHist(&IMAGE, 1, channels, Mat(), hist, 3, SIZE, ranges, true, false);
        normalize(hist, hist, 0, 1, NORM_MINMAX);
        tracking();
        waitKey(0);
        return 0;
    }
  • 相关阅读:
    《.NET深入体验与实战精要》读书体会
    为什么周易中有64卦?
    16进制与8进制之间的快速转码
    3种夸克有多少组合?
    分辨率宽高和为整千?
    abt DVD
    为什么有20种氨基酸?
    HD与BD次时代之战!
    [转载]Java一些基础问题
    [转载]Java环境变量配置
  • 原文地址:https://www.cnblogs.com/war1111/p/13848858.html
Copyright © 2020-2023  润新知