• 用Camshift算法对指定目标进行跟踪


    原理

    Camshift算法是Continuously Adaptive Mean Shift algorithm的简称。

    它是一个基于MeanSift的改进算法。它首次由Gary R.Bradski等人提出和应用在人脸的跟踪上,并取得了不错的效果。因为它是利用颜色的概率信息进行的跟踪。使得它的执行效率比較高。 Camshift算法的过程由以下步骤组成:

    (1)确定初始目标及其区域;

    (2)计算出目标的色度(Hue)分量的直方图;

    (3)利用直方图计算输入图像的反向投影图(后面做进一步的解释);

    (4)利用MeanShift算法在反向投影图中迭代收索,直到其收敛或达到最大迭代次数。并保存零次矩。

    (5)从第(4)步中获得收索窗体的中心位置和计算出新的窗体大小。以此为參数,进入到下一幀的目标跟踪。(即跳转到第(2)步);

    代码

    #include "stdafx.h"
    #include "opencv2/video/tracking.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    
    #include <iostream>
    #include <ctype.h>
    
    using namespace cv;
    using namespace std;
    
    Mat image;
    
    bool backprojMode = false;
    bool selectObject = false;
    int trackObject = 0;
    bool showHist = true;
    Point origin;
    Rect selection(0,0,50,50);
    
    
    static void onMouse( int event, int x, int y, int, void* )
    {
    	switch( event )
    	{
    	case CV_EVENT_LBUTTONDOWN:
    		origin = Point(x,y);
    		selection = Rect(x,y,0,0);
    		selectObject = true;
    		break;
    	case CV_EVENT_LBUTTONUP:
    		selectObject = false;
    		if( selection.width > 0 && selection.height > 0 )
    			trackObject = -1;
    		break;
    	}
    	if( selectObject )
    	{
    		selection.x = MIN(x, origin.x);
    		selection.y = MIN(y, origin.y);
    		selection.width = std::abs(x - origin.x);
    		selection.height = std::abs(y - origin.y);
    	}
    }
    
    int main( int argc, const char** argv )
    {
    	cv::VideoCapture capture(0);
    	capture.set( CV_CAP_PROP_FRAME_WIDTH,640);
    	capture.set( CV_CAP_PROP_FRAME_HEIGHT,480 );
    	if(!capture.isOpened())
    		return -1;
    	double rate = capture.get(CV_CAP_PROP_FPS);		//获取帧率
    	int delay = 1000 / rate;	//计算帧间延迟;
    	Mat frame,image,hsv,mask,hue;
    
    	namedWindow("test",CV_WINDOW_AUTOSIZE);
    	setMouseCallback("test",onMouse,0);
    	while (1)
    	{
    		capture>>frame;
    		if(trackObject == -1){ //设置完检測的对象后開始跟踪
    			frame.copyTo(image);
    			cv::cvtColor(image,hsv,CV_RGB2HSV); 
    			cv::inRange(hsv,Scalar(0,130,50),Scalar(180,256,256),mask);	//去掉低饱和度的点
    			vector<cv::Mat> v;
    			cv::split(hsv,v);			//hsv的三个通道分开
    			hue = v[1];
    			cv::Mat ROI = hue(selection);	//选择感兴趣的区域
    			cv::Mat maskROI = mask(selection);
    
    			cv::MatND hist;
    			int histsize[1];
    			histsize[0]= 16;
    
    			float hranges[2];
    			hranges[0] = 0;
    			hranges[1] = 180;
    
    			const float *ranges[1];
    			ranges[0] = hranges;
    			cv::calcHist(&ROI,1,0,maskROI,hist,1,histsize,ranges);//感兴趣区域的直方图。从參数太多
    			cv::normalize(hist,hist,0,180,CV_MINMAX);		//对直方图进行归一化处理;
    
    			cv::Mat backpro;
    			cv::calcBackProject(&hue,1,0,hist,backpro,ranges); //对h通道的进行反投影放入backpro中
    			backpro &= mask;
    
    			cv::RotatedRect trackBox = cv::CamShift(backpro,selection,
    					TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER,10,1));//使用均值秒一算法找出RECT;
    			cv::ellipse(frame,trackBox,cv::Scalar(0,0,255),2,CV_AA);
    		}
    		cv::imshow("test",frame);
    		if(waitKey(30) >= 0)
    			break;
    	}
    	capture.release();
    	return 0;
    }

    效果


    用摄像头获取视频

    直接读取视频

    总结:

    效果不是太好。可能是没有预处理或者參数设置的不好。
    刚開始学习的人。期待大婶知道!


  • 相关阅读:
    DJANGO-天天生鲜项目从0到1-011-订单-订单提交和创建
    DJANGO-天天生鲜项目从0到1-010-购物车-购物车操作页面(勾选+删改)
    DJANGO-天天生鲜项目从0到1-009-购物车-Ajax实现添加至购物车功能
    DJANGO-天天生鲜项目从0到1-009-搜索功能实现(django-haystack+whoosh+jieba)
    DJANGO-天天生鲜项目从0到1-008-列表页
    lombok 注解
    java 枚举
    Java反射的理解(六)-- 通过反射了解集合泛型的本质
    Java反射理解(五)-- 方法反射的基本操作
    Java反射理解(四)-- 获取成员变量构造函数信息
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7238037.html
Copyright © 2020-2023  润新知