精华内容
下载资源
问答
  • 带你入门多目标跟踪(三)匈牙利算法&KM算法

    万次阅读 多人点赞 2019-07-02 19:30:41
    匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)是做多目标跟踪的小伙伴很容易在论文中见到的两种算法。他们都是用来解决多目标跟踪中的数据关联问题。 对理论没有兴趣的小伙伴可以先跳过...

    匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)是做多目标跟踪的小伙伴很容易在论文中见到的两种算法。他们都是用来解决多目标跟踪中的数据关联问题。

    对理论没有兴趣的小伙伴可以先跳过本文,进行下一篇的学习,把匈牙利算法这些先当作一个黑箱来用,等需要了再回过头来学习理论。但个人建议,至少要明白这些算法的目的与大致流程。

    如果大家用这两种算法的名字在搜索引擎上搜索,一定会首先看到这个名词:二分图(二部图)。匈牙利算法与KM算法都是为了求解二分图的最大匹配问题

     

    二分图(二部图)

    有一种很特别的图,就做二分图,那什么是二分图呢?就是能分成两组,U,V。其中,U上的点不能相互连通,只能连去V中的点,同理,V中的点不能相互连通,只能连去U中的点。这样,就叫做二分图。

    读者可以把二分图理解为视频中连续两帧中的所有检测框,第一帧所有检测框的集合称为U,第二帧所有检测框的集合称为V。同一帧的不同检测框不会为同一个目标,所以不需要互相关联,相邻两帧的检测框需要相互联通,最终将相邻两帧的检测框尽量完美地两两匹配起来。而求解这个问题的最优解就要用到匈牙利算法或者KM算法。

    1. 匈牙利算法(Hungarian Algorithm)

    先介绍匈牙利算法,引用百度百科的说法,匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,并推动了后来的原始对偶方法。美国数学家哈罗德·库恩于1955年提出该算法。此算法之所以被称作匈牙利算法,是因为算法很大一部分是基于以前匈牙利数学家Dénes Kőnig和Jenő Egerváry的工作之上创建起来的。

    https://blog.csdn.net/dark_scope/article/details/8880547#commentBox

    这篇博文对匈牙利算法进行了非常简单清晰的解释,我这里引用它来说明一下匈牙利算法的流程。

    以上图为例,假设左边的四张图是我们在第N帧检测到的目标(U),右边四张图是我们在第N+1帧检测到的目标(V)。红线连起来的图,是我们的算法认为是同一行人可能性较大的目标。由于算法并不是绝对理想的,因此并不一定会保证每张图都有一对一的匹配,一对二甚至一对多,再甚至多对多的情况都时有发生。这时我们怎么获得最终的一对一跟踪结果呢?我们来看匈牙利算法是怎么做的。

    第一步.

    首先给左1进行匹配,发现第一个与其相连的右1还未匹配,将其配对,连上一条蓝线。

    第二步.

    接着匹配左2,发现与其相连的第一个目标右2还未匹配,将其配对。

    第三步.

    接下来是左3,发现最优先的目标右1已经匹配完成了,怎么办呢?

    我们给之前右1的匹配对象左1分配另一个对象。

    (黄色表示这条边被临时拆掉)

    可以与左1匹配的第二个目标是右2,但右2也已经有了匹配对象,怎么办呢?

    我们再给之前右2的匹配对象左2分配另一个对象(注意这个步骤和上面是一样的,这是一个递归的过程)。

    此时发现左2还能匹配右3,那么之前的问题迎刃而解了,回溯回去。

    左2对右3,左1对右2,左3对右1。

    所以第三步最后的结果就是:

    第四步.

    最后是左4,很遗憾,按照第三步的节奏我们没法给左4腾出来一个匹配对象,只能放弃对左4的匹配,匈牙利算法流程至此结束。蓝线就是我们最后的匹配结果。至此我们找到了这个二分图的一个最大匹配。

    再次感谢Dark_Scope的分享,我这里只是把其中的例子替换成了多目标跟踪的实际场景便于大家理解。

    最终的结果是我们匹配出了三对目标,由于候选的匹配目标中包含了许多错误的匹配红线(边),所以匹配准确率并不高。可见匈牙利算法对红线连接的准确率要求很高,也就是要求我们运动模型、外观模型等部件必须进行较为精准的预测,或者预设较高的阈值,只将置信度较高的边才送入匈牙利算法进行匹配,这样才能得到较好的结果。

    匈牙利算法的流程大家看到了,有一个很明显的问题相信大家也发现了,按这个思路找到的最大匹配往往不是我们心中的最优。匈牙利算法将每个匹配对象的地位视为相同,在这个前提下求解最大匹配。这个和我们研究的多目标跟踪问题有些不合,因为每个匹配对象不可能是同等地位的,总有一个真实目标是我们要找的最佳匹配,而这个真实目标应该拥有更高的权重,在此基础上匹配的结果才能更贴近真实情况。

    KM算法就能比较好地解决这个问题,我们下面来看看KM算法。

    2.KM算法(Kuhn-Munkres Algorithm)

    KM算法解决的是带权二分图的最优匹配问题。

    还是用上面的图来举例子,这次给每条连接关系加入了权重,也就是我们算法中其他模块给出的置信度分值。

    KM算法解决问题的步骤是这样的。

    第一步

    首先对每个顶点赋值,称为顶标,将左边的顶点赋值为与其相连的边的最大权重,右边的顶点赋值为0

    第二步,开始匹配

    匹配的原则是只和权重与左边分数(顶标)相同的边进行匹配,若找不到边匹配,对此条路径的所有左边顶点的顶标减d,所有右边顶点的顶标加d。参数d我们在这里取值为0.1。

    对于左1,与顶标分值相同的边先标蓝。

    然后是左2,与顶标分值相同的边标蓝。

    然后是左3,发现与右1已经与左1配对。首先想到让左3更换匹配对象,然而根据匹配原则,只有权值大于等于0.9+0=0.9(左顶标加右顶标)的边能满足要求。于是左3无法换边。那左1能不能换边呢?对于左1来说,只有权值大于等于0.8+0=0.8的边能满足要求,无法换边。此时根据KM算法,应对所有冲突的边的顶点做加减操作,令左边顶点值减0.1,右边顶点值加0.1。结果如下图所示。

    再进行匹配操作,发现左3多了一条可匹配的边,因为此时左3对右2的匹配要求只需权重大于等于0.8+0即可,所以左3与右2匹配!

    最后进行左4的匹配,由于左4唯一的匹配对象右3已被左2匹配,发生冲突。进行一轮加减d操作,再匹配,左四还是匹配失败。两轮以后左4期望值降为0,放弃匹配左4。

    至此KM算法流程结束,三对目标成功匹配,甚至在左三目标预测不够准确的情况下也进行了正确匹配。可见在引入了权重之后,匹配成功率大大提高。

    这篇文章可能信息量有点大,读起来略费脑。不过笔者力求排除复杂的理论推导,使用形象的例子来说明这两种算法。至于具体的理论,有兴趣的读者可以再去搜寻,网上有很多资料,相信有了感性的理解后,对理论的掌握会更加容易。

    最后还有一点值得注意,匈牙利算法得到的最大匹配并不是唯一的,预设匹配边、或者匹配顺序不同等,都可能会导致有多种最大匹配情况,所以有一种替代KM算法的想法是,我们只需要用匈牙利算法找到所有的最大匹配,比较每个最大匹配的权重,再选出最大权重的最优匹配即可得到更贴近真实情况的匹配结果。但这种方法时间复杂度较高,会随着目标数越来越多,消耗的时间大大增加,实际使用中并不推荐。

    展开全文
  • 匈牙利算法 卡尔曼滤波器多目标跟踪器实现
  • VS2015上C/C++实现目标检测和多目标跟踪多目标跟踪采用了匈牙利算法和卡尔曼滤波;你在VS2015新建工程,并配置好opencv的相关设置,就可直接使用;注意:如果你想获得更好的效果,目标检测可换成基于深度学习的,...
  • New videos!Vehicles speed calculation with YOLO v4 (Thanks Sam Blake for great idea!) Traffic counting with YOLO v3 First step to ADAS with YOLO v4 Multitarget (multiple objects) tracker1....

    New videos!

    Vehicles speed calculation with YOLO v4 (Thanks Sam Blake for great idea!)

    Traffic counting with YOLO v3

    First step to ADAS with YOLO v4

    Multitarget (multiple objects) tracker

    1. Objects detector can be created with function CreateDetector with different values of the detectorType:

    1.1. Based on background substraction: built-in Vibe (tracking::Motion_VIBE), SuBSENSE (tracking::Motion_SuBSENSE) and LOBSTER (tracking::Motion_LOBSTER); MOG2 (tracking::Motion_MOG2) from opencv; MOG (tracking::Motion_MOG), GMG (tracking::Motion_GMG) and CNT (tracking::Motion_CNT) from opencv_contrib. For foreground segmentation used contours from OpenCV with result as cv::RotatedRect

    1.2. Haar face detector from OpenCV (tracking::Face_HAAR)

    1.3. HOG pedestrian detector from OpenCV (tracking::Pedestrian_HOG) and C4 pedestrian detector from sturkmen72 (tracking::Pedestrian_C4)

    1.4. MobileNet SSD detector (tracking::SSD_MobileNet) with opencv_dnn inference and pretrained models from chuanqi305

    1.5. YOLO detector (tracking::Yolo_OCV) with opencv_dnn inference and pretrained models from pjreddie

    1.6. YOLO detector (tracking::Yolo_Darknet) with darknet inference from AlexeyAB and pretrained models from pjreddie

    1.7. YOLO detector (tracking::Yolo_TensorRT) with NVidia TensorRT inference from enazoe and pretrained models from pjreddie

    1.8. You can to use custom detector with bounding or rotated rectangle as output.

    2. Matching or solve an assignment problem:

    2.1. Hungrian algorithm (tracking::MatchHungrian) with cubic time O(N^3) where N is objects count

    2.2. Algorithm based on weighted bipartite graphs (tracking::MatchBipart) from rdmpage with time O(M * N^2) where N is objects count and M is connections count between detections on frame and tracking objects. It can be faster than Hungrian algorithm

    2.3. Distance from detections and objects: euclidean distance in pixels between centers (tracking::DistCenters), euclidean distance in pixels between rectangles (tracking::DistRects), Jaccard or IoU distance from 0 to 1 (tracking::DistJaccard)

    3.1. Linear Kalman filter from OpenCV (tracking::KalmanLinear)

    3.2. Unscented Kalman filter from OpenCV (tracking::KalmanUnscented) with constant velocity or constant acceleration models

    3.3. Kalman goal is only coordinates (tracking::FilterCenter) or coordinates and size (tracking::FilterRect)

    4. Advanced visual search for objects if they have not been detected:

    4.1. No search (tracking::TrackNone)

    4.2. Built-in DAT (tracking::TrackDAT) from foolwood, STAPLE (tracking::TrackSTAPLE) from xuduo35 or LDES (tracking::TrackLDES) from yfji; KCF (tracking::TrackKCF), MIL (tracking::TrackMIL), MedianFlow (tracking::TrackMedianFlow), GOTURN (tracking::TrackGOTURN), MOSSE (tracking::TrackMOSSE) or CSRT (tracking::TrackCSRT) from opencv_contrib

    With this option the tracking can work match slower but more accuracy.

    5. Pipeline

    get frame from capture device;

    decoding;

    objects detection (1);

    tracking (2-4);

    show result.

    This pipeline is good if all algorithms are fast and works faster than time between two frames (40 ms for device with 25 fps). Or it can be used if we have only 1 core for all (no parallelization).

    1th thread takes frame t and makes capture, decoding and objects detection;

    2th thread takes frame t-1, results from first thread and makes tracking and results presentation (this is the Main read).

    So we have a latency on 1 frame but on two free CPU cores we can increase performance on 2 times.

    5.3. Fully acynchronous pipeline can be used if the objects detector works with low fps and we have a free 2 CPU cores. In this case we use 4 threads:

    1th main thread is not busy and used for GUI and result presentation;

    2th thread makes capture and decoding, puts frames in threadsafe queue;

    3th thread is used for objects detection on the newest frame from the queue;

    4th thread is used for objects tracking: waits the frame with detection from 3th tread and used advanced visual search (4) in intermediate frames from queue until it ges a frame with detections.

    This pipeline can used with slow but accuracy DNN and track objects in intermediate frame in realtime without latency.

    Also you can read Wiki in Russian.

    Demo Videos

    MobileNet SSD and tracking for low resolution and low quality videos from car DVR:

    Mouse tracking:

    Motion Detection and tracking:

    Multiple Faces tracking:

    Simple Abandoned detector:

    Tested Platforms

    Ubuntu Linux 18.04 with x86 processors

    Ubuntu Linux 18.04 with Nvidia Jetson Nano (YOLO + darknet on GPU works!)

    Windows 10 (x64 and x32 builds)

    Build

    Download project sources

    Install CMake

    Configure project CmakeLists.txt, set OpenCV_DIR (-DOpenCV_DIR=/path/to/opencv/build).

    If opencv_contrib don't installed then disable options USE_OCV_BGFG=OFF, USE_OCV_KCF=OFF and USE_OCV_UKF=OFF

    If you want to use native darknet YOLO detector with CUDA + cuDNN then set BUILD_YOLO_LIB=ON (Install first CUDA and cuDNN libraries from Nvidia)

    If you want to use YOLO detector with TensorRT then set BUILD_YOLO_TENSORRT=ON (Install first TensorRT library from Nvidia)

    For building example with low fps detector (now native darknet YOLO detector) and Tracker worked on each frame: BUILD_ASYNC_DETECTOR=ON

    For building example with line crossing detection (cars counting): BUILD_CARS_COUNTING=ON

    Go to the build directory and run make

    Full build:

    git clone https://github.com/Smorodov/Multitarget-tracker.git

    cd Multitarget-tracker

    mkdir build

    cd build

    cmake . .. -DUSE_OCV_BGFG=ON -DUSE_OCV_KCF=ON -DUSE_OCV_UKF=ON -DBUILD_YOLO_LIB=ON -DBUILD_YOLO_TENSORRT=ON -DBUILD_ASYNC_DETECTOR=ON -DBUILD_CARS_COUNTING=ON

    make -j

    How to run cmake on Windows for Visual Studio 15 2017 Win64: example. You need to add directory with cmake.exe to PATH and change build params in cmake.bat

    Usage:

    Usage:

    ./MultitargetTracker [--example]= [--start_frame]= [--end_frame]= [--end_delay]= [--out]= [--show_logs]= [--gpu]= [--async]=

    ./MultitargetTracker ../data/atrium.avi -e=1 -o=../data/atrium_motion.avi

    Press:

    * 'm' key for change mode: play|pause. When video is paused you can press any key for get next frame.

    * Press Esc to exit from video

    Params:

    1. Movie file, for example ../data/atrium.avi

    2. [Optional] Number of example: 0 - MouseTracking, 1 - MotionDetector, 2 - FaceDetector, 3 - PedestrianDetector, 4 - MobileNet SSD detector, 5 - YOLO OpenCV detector, 6 - Yolo Darknet detector, 7 - YOLO TensorRT Detector

    -e=0 or --example=1

    3. [Optional] Frame number to start a video from this position

    -sf=0 or --start_frame==1500

    4. [Optional] Play a video to this position (if 0 then played to the end of file)

    -ef=0 or --end_frame==200

    5. [Optional] Delay in milliseconds after video ending

    -ed=0 or --end_delay=1000

    6. [Optional] Name of result video file

    -o=out.avi or --out=result.mp4

    7. [Optional] Show Trackers logs in terminal

    -sl=1 or --show_logs=0

    8. [Optional] Use built-in OpenCL

    -g=1 or --gpu=0

    9. [Optional] Use 2 threads for processing pipeline

    -a=1 or --async=0

    More details here: How to run examples.

    Thirdparty libraries

    License

    Project cititations

    Jeroen PROVOOST "Camera gebaseerde analysevan de verkeersstromen aaneen kruispunt", 2014 ( https://iiw.kuleuven.be/onderzoek/eavise/mastertheses/provoost.pdf )

    Wenda Qin, Tian Zhang, Junhe Chen "Traffic Monitoring By Video: Vehicles Tracking and Vehicle Data Analysing", 2016 ( http://cs-people.bu.edu/wdqin/FinalProject/CS585%20FinalProjectReport.html )

    Ipek BARIS "CLASSIFICATION AND TRACKING OF VEHICLES WITH HYBRID CAMERA SYSTEMS", 2016 ( http://cvrg.iyte.edu.tr/publications/IpekBaris_MScThesis.pdf )

    Cheng-Ta Lee, Albert Y. Chen, Cheng-Yi Chang "In-building Coverage of Automated External Defibrillators Considering Pedestrian Flow", 2016 ( http://www.see.eng.osaka-u.ac.jp/seeit/icccbe2016/Proceedings/Full_Papers/092-132.pdf )

    Omid Noorshams "Automated systems to assess weights and activity in grouphoused mice", 2017 ( https://pdfs.semanticscholar.org/e5ff/f04b4200c149fb39d56f171ba7056ab798d3.pdf )

    RADEK VOPÁLENSKÝ "DETECTION,TRACKING AND CLASSIFICATION OF VEHICLES", 2018 ( https://www.vutbr.cz/www_base/zav_prace_soubor_verejne.php?file_id=181063 )

    Márk Rátosi, Gyula Simon "Real-Time Localization and Tracking using Visible Light Communication", 2018 ( https://ieeexplore.ieee.org/abstract/document/8533800 )

    Thi Nha Ngo, Kung-Chin Wu, En-Cheng Yang, Ta-Te Lin "Areal-time imaging system for multiple honey bee tracking and activity monitoring", 2019 ( https://www.sciencedirect.com/science/article/pii/S0168169919301498 )

    展开全文
  • 匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)是做多目标跟踪的小伙伴很容易在论文中见到的两种算法。他们都是用来解决多目标跟踪中的数据关联问题。 二级目录 三级目录 ...

    一、匈牙利算法

    1、算法背景及思想

    匈牙利算法,是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,由匈牙利数学家Edmonds于1965年提出,因而得名。

    匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)做多目标跟踪很容易在论文中见到的两种算法。他们都是用来解决多目标跟踪中的数据关联问题。

    上述利用增广路找最大匹配的算法,就叫做匈牙利算法。

    2、最大匹配

    结合情侣配对问题,男生女生之间互生情愫的有很多,甚至有的人对多个人都有意向,因此潜在的情侣组合方式有很多种。所谓的“任意两条边都不依附于同一个顶点”,意思就是只要我们撮合的时候,不要给某个人安排两个对象就行。作为牵线人,我们可以撮合一对,也可以撮合两对,这样每一种撮合方式,都叫一个匹配。撮合成功的这些情侣就是所谓的子图M。

    按照上面的匹配方式,我们既不能把没有意向的两个人撮合在一起,有的人又对多个人有意向,因此可以花一点心思,尽可能地协调一下大家的意向,做到多撮合成功几对。这样,成功撮合的情侣最多的这种撮合方式,就叫最大匹配。

    3、最优匹配/完美匹配

    解释:如果非常幸运,在我们的安排下,每个人都找到了自己心仪的对象。这种撮合方式,叫做最优匹配或完美匹配。

    4、增广路径

    (非匹配边) (匹配边) (非匹配边)

    B--------------a----------------A-----------------c

    B和c都是没有被匹配过的点,而它又是这条交替路的起点和终点。这条交替路就是增广路。

    5、代码实现

    匈牙利算法有一个很明显的问题,按它的思路找到的最大匹配往往不是我们心中的最优。匈牙利算法将每个匹配对象的地位视为相同,在这个前提下求解最大匹配。这个和我们研究的多目标跟踪问题有些不合,因为每个匹配对象不可能是同等地位的,总有一个真实目标是我们要找的最佳匹配,而这个真实目标应该拥有更高的权重,在此基础上匹配的结果才能更贴近真实情况。

    bool find(int x){
    	int i,j;
    	for (j=1;j<=m;j++){    //扫描每个妹子
    		if (line[x][j]==true && used[j]==false)      
    		//如果有暧昧并且还没有标记过(这里标记的意思是这次查找曾试图改变过该妹子的归属问题,但是没有成功,所以就不用瞎费工夫了)
    		{
    			used[j]=1;
    			if (girl[j]==0 || find(girl[j])) { 
    				//名花无主或者能腾出个位置来,这里使用递归
    				girl[j]=x;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    class graph:
        def __init__(self,gi,bo): # 输入二部图两个顶点集合的数目,每个集合的顶点均用1, ... , n表示
            self.numg=gi # 女孩数量
            self.numb=bo # 男孩数量
            self.boy={i:[]for i in range(1,bo+1)} # 男孩的可连接对象,建图
            self.viag=[0 for i in range(gi+1)] # 记录当前匹配女孩的对象
            self.use=[0 for i in range(gi+1)] # 检查女孩是否被搜索过
        def add(self,u,v):
            self.boy[v].append(u)
        def find(self,j): # 寻找 j 男孩起始的增广路
            if j==0:
                return 1
            for i in self.boy[j]:
                if self.use[i]==0: # 女孩没有被搜索过
                    self.use[i]=1
                    if self.find(self.viag[i]): # 检查 j 匹配女孩后,女孩原男友是否有其它的女友,有则表示存在增广路
                        self.viag[i]=j
                        return 1
            return 0
        def Hungarian(self):
            sum=0
            for i in range(1,self.numb+1): # 检查每个男孩是否能找到女有
                self.use = [0 for i in range(self.numg + 1)] # 初始化为0
                if self.find(i):
                    sum+=1
            return sum,self.viag[1:]
    
    if __name__=="__main__":
        n,girlnum,boynum = map(int, input().split())
        dic = graph(girlnum,boynum)
        for i in range(n):
            a, b = map(int, input().split())
            dic.add(a,b)
        print(dic.Hungarian())
    

    6、匈牙利算法总结

    6.1、深度优先

    每个点从另一个集合里挑对象,没冲突的话就先安排上,要是冲突了就用增广路径重新匹配。重复上述思路,直到所有的点都找到对象,或者找不到对象也找不到增广路。

    上述是深度优先匈牙利算法。就是冲突了立刻用增广路来解决。

    6.2、 广度优先

    另外一种是广度优先匈牙利算法。思路是,冲突了就换一个心仪对象,看另一个心仪对象是不是也配对了,要是都配对了,再用增广路来解决

    广度优先的流程是这样的:

    (1)A和a连上。

    (2)B也想连a,但是a被连了,就找下一个心仪对象b

    (3)b没有被连上,B和b就连在一起。

    (4)轮到C的时候,C找心仪对象c。

    (5)c也没被连上,所以C和c连一起。

    二、KM算法思想及局限性

    KM算法解决的是带权二分图的最优匹配问题。

    匈牙利算法得到的最大匹配并不是唯一的,预设匹配边、或者匹配顺序不同等,都可能会导致有多种最大匹配情况,所以有一种替代KM算法的想法是,我们只需要用匈牙利算法找到所有的最大匹配,比较每个最大匹配的权重,再选出最大权重的最优匹配即可得到更贴近真实情况的匹配结果。但这种方法时间复杂度较高,会随着目标数越来越多,消耗的时间大大增加,实际使用中并不推荐。

    代码示例

    1、定义KM方法类

    import numpy as np
    
    class KM_Algorithm_4:
    
        def __init__(self, Bipartite_Graph):
    
            self.Bipartite_Graph = Bipartite_Graph
    
            # 左右结点数量记录
            self.left = self.Bipartite_Graph.shape[0]  # 以左边为主
            # print(self.Bipartite_Graph)
            # print(self.Bipartite_Graph[0])
            self.right_true = self.Bipartite_Graph.shape[1]
            self.right = self.Bipartite_Graph.shape[1] + self.left
    
            self.reshape_graph()
    
            # 初始化顶标
            self.label_left = np.max(self.Bipartite_Graph, axis=1)  # 设置左边顶标为权重最大值(每行的最大值)
    
            self.label_right = np.zeros(self.right)  # 右边集合的顶标设置为0
    
            # 初始化辅助变量——是否已匹配
            self.visit_left = np.zeros(self.left, dtype=bool)
            self.visit_right = np.zeros(self.right, dtype=bool)
    
            # 初始化右边的匹配结果.如果已匹配就会对应匹配结果
            self.match_right = np.empty(self.right) * np.nan
    
            # 用inc记录需要减去的权值d,不断取最小值故初始化为较大值。权值都为负数,应该不用很大也行
            self.inc = 1000*1000*1000
    
            self.fail_boy = list()  # 每次匹配重新创建一个二分图匹配对象,所以这个也不用手动重置了
    
        def reshape_graph(self):
            new = np.ones((self.left, self.left)) * 0
            self.Bipartite_Graph = np.column_stack((self.Bipartite_Graph, new))
            # print(self.Bipartite_Graph)
    
        def match(self, boy):
            # print("---------------我是boy%d----------------------" % boy)
            boy = int(boy)
            # 记录下这个boy已经被寻找
            self.visit_left[boy] = True
            for girl in range(self.right):
                # 如果这个女生还没访问过
                if not self.visit_right[girl] and self.Bipartite_Graph[boy][girl] >= 0:  # 女孩仍未匹配并且男女之间存在匹配的可能性(不可匹配的点设置为负数,取反后变正数,故正数不可取)
                    gap = self.label_left[boy] + self.label_right[girl] - self.Bipartite_Graph[boy][girl]  # gap也不会取到不能匹配的那条边
                    if gap == 0:   # 差值为0,是可行的替换。所以可以直接尝试替换。后面不行再去将这个一起减去gap。这个列表是记录希望匹配的
                        self.visit_right[girl] = True
                        # 女生未被匹配,或虽然已被匹配,但是已匹配对象(男生)有其他可选备胎。这里那些是否已访问的列表不需要重置,因为不改变前面的尝试匹配
                        if np.isnan(self.match_right[girl]) or self.match(self.match_right[girl]):
                            self.match_right[girl] = boy
                            # print(self.match_right)
                            # 递归匹配,匹配成功
                            return 1
    
                    # 找到权值最小的差距
                    elif self.inc > gap:
                        self.inc = gap  # 等于0的gap不会存在这,所以只要存在可能匹配的情况,gap就不会等于原来的inc
    
            return 0
    
        def Kuh_Munkras(self):
    
            self.match_right = np.empty(self.right) * np.nan
            # 寻找最优匹配
            for man in range(self.left):
                while True:
                    self.inc = 1000*1000  # the minimum gap
                    self.reset()  # 每次寻找过的路径,所有要重置一下
    
                    # 可找到可行匹配
                    if self.match(man):
                        break
                    # 不能找到可行匹配
                    # (1)将所有在增广路中的boy方点的label全部减去最小常数
                    # (2)将所有在增广路中的girl方点的label全部加上最小常数
                    for k in range(self.left):
                        if self.visit_left[k]:
                            self.label_left[k] -= self.inc
                    for n in range(self.right):
                        if self.visit_right[n]:
                            self.label_right[n] += self.inc
    
            return self.fail_boy
    
        def calculateSum(self):
            sum = 0
            boys_girls = []
            self.fail_boy = [i for i in range(self.left)]
            for i in range(self.right_true):
                if not np.isnan(self.match_right[i]):
                    sum += self.Bipartite_Graph[int(self.match_right[i])][i]
                    boy_girl = (int(self.match_right[i]), i)
                    boys_girls.append(boy_girl)
                    self.fail_boy.remove(int(self.match_right[i]))
            print("最短路径:", sum)
    
            return boys_girls, self.fail_boy
    
        def getResult(self):
            return self.match_right
    
        def reset(self):
            self.visit_left = np.zeros(self.left, dtype=bool)
            self.visit_right = np.zeros(self.right, dtype=bool)
    

    2、定义权重数值,执行主函数

    # 定义权重数值
    def data():
        graph = [[8,6,-1,-1],
                [-1,3,9,-1],
                [9,8,-1,-1],
                [-1,-1,2,-1]]
        #print(graph)
        km = KM_Algorithm_4(np.array(graph))
    
        km.Kuh_Munkras()  # 匹配
    
        boys_girls, fail_boys = km.calculateSum()  # 匹配结果元组,以及失败的男孩们
    
        print("匹配男女列表", boys_girls)
        print("失败男孩列表", fail_boys)
    
    
    if __name__ == '__main__':
        data()
    

    参考文献

    https://blog.csdn.net/dark_scope/article/details/8880547
    https://zhuanlan.zhihu.com/p/208596378
    https://aistudio.baidu.com/aistudio/projectdetail/2040378

    展开全文
  • ZihaoZhao:带你入门多目标跟踪(三)匈牙利算法&KM算法
    展开全文
  • 匈牙利算法多目标分配中的应用 在多目标攻击决策中,根据Har。ld提出的目标优势幽数.分析r使所有目标机的总优势荫数为指派阃题,运用匈 牙利算法对一对“的最优目标分配指派问题进行求解,并把芭推广至“列垅的...
  • 多目标个对象)跟踪器 1.可以使用具有不同的detectorType值的功能创建对象检测器: 1.1。 根据背景扣除:内置Vibe(跟踪:: Motion_VIBE),SuBSENSE(跟踪:: Motion_SuBSENSE)和LOBSTER(跟踪:: Motion_...
  • SORT 多目标跟踪算法笔记

    万次阅读 多人点赞 2019-04-21 15:20:46
    sort 是一种简单的在线实时多目标跟踪算法。文章要点为: 以 IoU 作为前后帧间目标关系度量指标; 利用卡尔曼滤波器预测当前位置; 通过匈牙利算法关联检测框到目标; 应用试探期甄别虚检; 使用 Faster R-...
  • 匈牙利算法(KM算法):将前一帧中的跟踪框tracks与当前帧中的检测框detections进行关联,通过外观信息、马氏距离、或者IOU来计算代价矩阵 卡尔曼滤波:基于传感器的测量值(在目标跟踪中即目标检测器)与跟踪器的...
  • 多目标跟踪算法SORT

    2021-04-16 10:09:16
    目标跟踪简介三. 卡尔曼滤波器3.1 什么是卡尔曼滤波器3.2 具体计算过程3.3 换个角度看四. 匈牙利算法五. SORT 一. 目标检测简介 给定一张图像,找出我们需要的类别位置,并给定一个检测框,检测框一般包含位置坐标...
  • 匈牙利算法

    2020-05-08 00:30:40
    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow ...匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)是用来解决多目标跟踪中的数据关联问题,匈牙利算法与KM算法都是为了求解二...
  • 匈牙利算法步骤 匈牙利算法博客推荐 KM算法步骤 KM算法标杆(又名顶标)的引入 KM流程详解 KM算法博客推荐 贪心算法 英文注解 无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配...
  • 多目标跟踪算法解读

    千次阅读 2020-09-28 14:29:43
    一、多目标跟踪背景介绍 1.问题定义 2.难点 3.应用场景 二、相关方法 1.Model free 方法 2. Tracking by detection 方法 1)离线方法 2)在线方法 三、基准 多目标跟踪背景介绍 问题定义 多目标跟踪是将视频...
  • 利用匈牙利算法目标框和检测框进行关联 在这里我们对检测框和跟踪框进行匹配,整个流程是遍历检测框和跟踪框,并进行匹配,匹配成功的将其保留,未成功的将其删除。 def associate_detections_to_...
  • 多目标跟踪算法

    千次阅读 2020-02-09 15:37:45
    文章目录多目标跟踪算法一、多目标跟踪算法分类二、基于目标检测的多目标跟踪2.1 基于轨迹预测的目标跟踪算法2.2 基于目标特征建模 多目标跟踪算法 一、多目标跟踪算法分类 DBT(Detection Based Tracking)(如上图...
  • 目录目标跟踪、单目标跟踪多目标跟踪的概念欧氏距离、马氏距离、余弦距离欧氏距离马氏距离余弦距离SORT算法原理SORT算法中的匈牙利匹配算法指派问题中的匈牙利算法 目标跟踪、单目标跟踪多目标跟踪的概念 目标...
  • 多目标跟踪算法SOART

    2019-07-06 20:20:50
    本文对多目标检测方法SOART进行了翻译 论文地址:... ... 文章的重点是有效地处理帧与帧之间的关联。 ... 使用卡尔曼滤波器处理跟踪问题的运动预测 ... 使用匈牙利算法处理数据关联分量 文章只针对各种...
  • 目标跟踪就是在检测出某视频序列初始帧的目标位置后,预测后续帧中该目标的大小与位置。
  • DeepSORT 多目标跟踪算法笔记

    千次阅读 多人点赞 2019-05-11 16:54:58
    SORT 是一种实用的多目标跟踪算法,然而由于现实中目标运动多变且遮挡频繁,该算法的身份转换(Identity Switches)次数较高。DeepSORT 整合外观信息使得身份转换的数量减少了45%。所提方案为: 使用马氏距离和...
  • 前言 基于视觉的目标跟踪在智能监控、动作与行为分析、自动驾驶等领域都有重要的应用。例如,在自动驾驶系统中,目标跟踪算法要对运动的车、行人...Sort算法,是一种简单的在线实时多目标跟踪算法。它以“每个检测”与
  • 1、YOLOV3目标检测 关于yolov3的原理我在这里就不解释了,可谷歌学术自行阅读,说实话yolov3的效果着实不错,但是源码是C的,不依赖其他任何库,看的云里雾里,在这里我用的darknet训练的,利用tensorflow+keras...
  • 目标跟踪算法

    2020-05-06 11:44:47
    多目标跟踪算法简介 跟踪算法的重点 SORT 是一种的在线实时多目标跟踪算法。要点为: 以 IOU 作为前后图像目标关系度量指标; 利用卡尔曼滤波器预测当前位置; 通过匈牙利算法关联检测目标; 使用 YOLO3,...
  • 在讲将匈牙利算法解决任务分配问题之前,先分析几个具体实例。 以3个工作人员和3项任务为实例,下图为薪酬图表和根据薪酬图表所得的cost矩阵。   利用最简单的方法(全排列法)进行求解,计算出所有分配情况的总...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,828
精华内容 731
关键字:

匈牙利算法多目标跟踪