• 44 dlib鼠标指定目标跟踪


    dlib提供了dlib.correlation_tracker()类用于跟踪目标。
    官方文档入口:http://dlib.net/python/index.html#dlib.correlation_tracker
    不复杂,就不介绍了,后面会直接给出两个程序,有注释。

    # -*- coding: utf-8 -*-
    import sys
    import dlib
    import cv2
    
    tracker = dlib.correlation_tracker()   # 导入correlation_tracker()类
    cap = cv2.VideoCapture(0)   # OpenCV打开摄像头
    start_flag = True   # 标记,是否是第一帧,若在第一帧需要先初始化
    selection = None   # 实时跟踪鼠标的跟踪区域
    track_window = None   # 要检测的物体所在区域
    drag_start = None   # 标记,是否开始拖动鼠标
    
    # 鼠标点击事件回调函数
    def onMouseClicked(event, x, y, flags, param):
        global selection, track_window, drag_start  # 定义全局变量
        if event == cv2.EVENT_LBUTTONDOWN:  # 鼠标左键按下
            drag_start = (x, y)
            track_window = None
        if drag_start:   # 是否开始拖动鼠标,记录鼠标位置
            xMin = min(x, drag_start[0])
            yMin = min(y, drag_start[1])
            xMax = max(x, drag_start[0])
            yMax = max(y, drag_start[1])
            selection = (xMin, yMin, xMax, yMax)
        if event == cv2.EVENT_LBUTTONUP:   # 鼠标左键松开
            drag_start = None
            track_window = selection
            selection = None
    
    if __name__ == '__main__':
        cv2.namedWindow("image", cv2.WINDOW_AUTOSIZE)
        cv2.setMouseCallback("image", onMouseClicked)
    
        # opencv的bgr格式图片转换成rgb格式
        # b, g, r = cv2.split(frame)
        # frame2 = cv2.merge([r, g, b])
    
        while(1):
            ret, frame = cap.read()   # 从摄像头读入1帧
    
            if start_flag == True:   # 如果是第一帧,需要先初始化
                # 这里是初始化,窗口中会停在当前帧,用鼠标拖拽一个框来指定区域,随后会跟踪这个目标;我们需要先找到目标才能跟踪不是吗?
                while True:
                    img_first = frame.copy()   # 不改变原来的帧,拷贝一个新的出来
                    if track_window:  # 跟踪目标的窗口画出来了,就实时标出来
                        cv2.rectangle(img_first, (track_window[0], track_window[1]), (track_window[2], track_window[3]), (0,0,255), 1)
                    elif selection:   # 跟踪目标的窗口随鼠标拖动实时显示
                        cv2.rectangle(img_first, (selection[0], selection[1]), (selection[2], selection[3]), (0,0,255), 1)
                    cv2.imshow("image", img_first)
                    # 按下回车,退出循环
                    if cv2.waitKey(5) == 13:
                        break
                start_flag = False   # 初始化完毕,不再是第一帧了
                tracker.start_track(frame, dlib.rectangle(track_window[0], track_window[1], track_window[2], track_window[3]))   # 跟踪目标,目标就是选定目标窗口中的
            else:
                tracker.update(frame)  # 更新,实时跟踪
    
            box_predict = tracker.get_position()  # 得到目标的位置
            cv2.rectangle(frame,(int(box_predict.left()),int(box_predict.top())),(int(box_predict.right()),int(box_predict.bottom())),(0,255,255),1)  # 用矩形框标注出来
            cv2.imshow("image", frame)
            # 如果按下ESC键,就退出
            if cv2.waitKey(10) == 27:
                break
    
        cap.release()
        cv2.destroyAllWindows()
    

      

    注:如果程序卡了,就调一下cv2.waitKey()中的参数,也就是延时时间,调小即可。

    运行结果
    初始时,窗口中只会显示第一帧的图像;
    使用鼠标拖拽一个框,红框中目标后,按回车,设置框内为识别目标;
    实时识别,以橙框标出;
    按ESC键退出。

    (csdn只能上传2M的图片,真心难受)

    程序2
    由于前面那个程序,只是熟悉下函数写的,我觉得用起来蛋疼,所以又重新封装了一下。看起来舒服多了。

    # -*- coding: utf-8 -*-
    import sys
    import dlib
    import cv2
    
    class myCorrelationTracker(object):
        def __init__(self, windowName='default window', cameraNum=0):
            # 自定义几个状态标志
            self.STATUS_RUN_WITHOUT_TRACKER = 0     # 不跟踪目标,但是实时显示
            self.STATUS_RUN_WITH_TRACKER = 1    # 跟踪目标,实时显示
            self.STATUS_PAUSE = 2   # 暂停,卡在当前帧
            self.STATUS_BREAK = 3   # 退出
            self.status = self.STATUS_RUN_WITHOUT_TRACKER   # 指示状态的变量
    
            # 这几个跟前面程序1定义的变量一样
            self.track_window = None  # 实时跟踪鼠标的跟踪区域
            self.drag_start = None   # 要检测的物体所在区域
            self.start_flag = True   # 标记,是否开始拖动鼠标
    
            # 创建好显示窗口
            cv2.namedWindow(windowName, cv2.WINDOW_AUTOSIZE)
            cv2.setMouseCallback(windowName, self.onMouseClicked)
            self.windowName = windowName
    
            # 打开摄像头
            self.cap = cv2.VideoCapture(cameraNum)
    
            # correlation_tracker()类,跟踪器,跟程序1中一样
            self.tracker = dlib.correlation_tracker()
    
            # 当前帧
            self.frame = None
    
        # 按键处理函数
        def keyEventHandler(self):
            keyValue = cv2.waitKey(5)  # 每隔5ms读取一次按键的键值
            if keyValue == 27:  # ESC
                self.status = self.STATUS_BREAK
            if keyValue == 32:  # 空格
                if self.status != self.STATUS_PAUSE:    # 按下空格,暂停播放,可以选定跟踪的区域
                    #print self.status
                    self.status = self.STATUS_PAUSE
                    #print self.status
                else:   # 再按次空格,重新播放,但是不进行目标识别
                    if self.track_window:
                        self.status = self.STATUS_RUN_WITH_TRACKER
                        self.start_flag = True
                    else:
                        self.status = self.STATUS_RUN_WITHOUT_TRACKER
            if keyValue == 13:  # 回车
                #print '**'
                if self.status == self.STATUS_PAUSE:    # 按下空格之后
                    if self.track_window:   # 如果选定了区域,再按回车,表示确定选定区域为跟踪目标
                        self.status = self.STATUS_RUN_WITH_TRACKER
                        self.start_flag = True
    
        # 任务处理函数        
        def processHandler(self):
            # 不跟踪目标,但是实时显示
            if self.status == self.STATUS_RUN_WITHOUT_TRACKER:
                ret, self.frame = self.cap.read()
                cv2.imshow(self.windowName, self.frame)
            # 暂停,暂停时使用鼠标拖动红框,选择目标区域,与程序1类似
            elif self.status == self.STATUS_PAUSE:
                img_first = self.frame.copy()  # 不改变原来的帧,拷贝一个新的变量出来
                if self.track_window:   # 跟踪目标的窗口画出来了,就实时标出来
                    cv2.rectangle(img_first, (self.track_window[0], self.track_window[1]), (self.track_window[2], self.track_window[3]), (0,0,255), 1)
                elif self.selection:   # 跟踪目标的窗口随鼠标拖动实时显示
                    cv2.rectangle(img_first, (self.selection[0], self.selection[1]), (self.selection[2], self.selection[3]), (0,0,255), 1)
                cv2.imshow(self.windowName, img_first)
            # 退出
            elif self.status == self.STATUS_BREAK:
                self.cap.release()   # 释放摄像头
                cv2.destroyAllWindows()   # 释放窗口
                sys.exit()   # 退出程序
            # 跟踪目标,实时显示
            elif self.status == self.STATUS_RUN_WITH_TRACKER:
                ret, self.frame = self.cap.read()  # 从摄像头读取一帧
                if self.start_flag:   # 如果是第一帧,需要先初始化
                    self.tracker.start_track(self.frame, dlib.rectangle(self.track_window[0], self.track_window[1], self.track_window[2], self.track_window[3]))  # 开始跟踪目标
                    self.start_flag = False   # 不再是第一帧
                else:
                    self.tracker.update(self.frame)   # 更新
    
                    # 得到目标的位置,并显示
                    box_predict = self.tracker.get_position()   
                    cv2.rectangle(self.frame,(int(box_predict.left()),int(box_predict.top())),(int(box_predict.right()),int(box_predict.bottom())),(0,255,255),1)
                    cv2.imshow(self.windowName, self.frame)
    
        # 鼠标点击事件回调函数
        def onMouseClicked(self, event, x, y, flags, param):
            if event == cv2.EVENT_LBUTTONDOWN:  # 鼠标左键按下
                self.drag_start = (x, y)
                self.track_window = None
            if self.drag_start:   # 是否开始拖动鼠标,记录鼠标位置
                xMin = min(x, self.drag_start[0])
                yMin = min(y, self.drag_start[1])
                xMax = max(x, self.drag_start[0])
                yMax = max(y, self.drag_start[1])
                self.selection = (xMin, yMin, xMax, yMax)
            if event == cv2.EVENT_LBUTTONUP:   # 鼠标左键松开
                self.drag_start = None
                self.track_window = self.selection
                self.selection = None
    
        def run(self):
            while(1):
                self.keyEventHandler()
                self.processHandler()
    
    
    if __name__ == '__main__':
        testTracker = myCorrelationTracker(windowName='image', cameraNum=1)
        testTracker.run()
    

      

    运行结果

    操作有一些改变:
    初始时,会自动从摄像头采集图像显示;
    按下空格,暂停;此时若再按空格,恢复实时显示,但不进行目标跟踪;
    暂停时,拖动鼠标会显示红框,按下回车,将红框内物体视为目标进行识别;
    随后实时识别,以橙框标出;
    按ESC键退出。

    dlib这个库的确很方便,能够很轻松地让我们实现一些基础的识别任务,比如人脸识别。但是如果想要在各种识别任务中有更好的效果,肯定是不能只用他给的模型的。那也就是说需要自己训练了,看到官方文档中也提供了一些训练以及自己构建神经网络等的api接口,

  • 相关阅读:
    51 nod 1181 质数中的质数(质数筛法)
    Just oj 2018 C语言程序设计竞赛(高级组)F:Star(结构体排序+最小生成树)
    欧拉函数+费马小定理拓展
    ZOJ 3785 What day is that day?(数论:费马小定理)
    Just oj 2018 C语言程序设计竞赛(高级组)H: CBT?
    树链剖分(入门学习)
    bitset用法
    链式前向星
    Nearest Common Ancestors(LCA板子)
    LCA(最近公共祖先)
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/11986855.html
Copyright © 2020-2023  润新知