zoukankan      html  css  js  c++  java
  • 图像跟踪(1) CSK

     依赖OPENCV

    1功能

    1. 鼠标选取目标  S按键取消重新选择
    2. 共享内存目标框 中心 X Y 边框W H

    /////////////////////////////////////////////////////////////////////////
    // Author:      Zhongze Hu
    // Subject:     Circulant Structure of Tracking-by-detection with Kernels
    // Algorithm:   ECCV12, Jo~ao F. Henriques, Exploiting the Circulant 
    //			    Structure of Tracking-by-detection with Kernels
    // Matlab code: http://home.isr.uc.pt/~henriques/circulant/index.html
    // Date:        01/13/2015
    
    /////////////////////////////////////////////////////////////////////////
    
    
    
    #include "CSK_Tracker.h"
    #include <iostream>
    #include <fstream>
    
    
    using namespace std;
    
    bool tracking_flag = false;
    cv::Mat org, dst, img, tmp;
    int Wid, Hei, X, Y;
    void on_mouse(int event, int x, int y, int flags, void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号  
    {
    	
    	static cv::Point pre_pt = (-1, -1);//初始坐标  
    	static cv::Point cur_pt = (-1, -1);//实时坐标  
    	char temp[16];
    
    	if (!tracking_flag) {
    		
    		if (event == CV_EVENT_LBUTTONDOWN)//左键按下,读取初始坐标,并在图像上该点处划圆  
    		{
    			//org.copyTo(img);//将原始图片复制到img中  
    			org = img.clone();
    			sprintf(temp, "(%d,%d)", x, y);
    			pre_pt = cv::Point(x, y);
    			putText(img, temp, pre_pt, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 255), 1, 8);//在窗口上显示坐标  
    			circle(img, pre_pt, 2, cv::Scalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);//划圆  
    			imshow("img", img);
    		}
    		else if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))//左键没有按下的情况下鼠标移动的处理函数  
    		{
    			img.copyTo(tmp);//将img复制到临时图像tmp上,用于显示实时坐标  
    			sprintf(temp, "(%d,%d)", x, y);
    			cur_pt = cv::Point(x, y);
    			putText(tmp, temp, cur_pt, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 255));//只是实时显示鼠标移动的坐标  
    			imshow("img", tmp);
    		}
    		else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//左键按下时,鼠标移动,则在图像上划矩形  
    		{
    			img.copyTo(tmp);
    			sprintf(temp, "(%d,%d)", x, y);
    			cur_pt = cv::Point(x, y);
    			putText(tmp, temp, cur_pt, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 255));
    			rectangle(tmp, pre_pt, cur_pt, cv::Scalar(0, 255, 0, 0), 1, 8, 0);//在临时图像上实时显示鼠标拖动时形成的矩形  
    			imshow("img", tmp);
    		}
    		else if (event == CV_EVENT_LBUTTONUP)//左键松开,将在图像上划矩形  
    		{
    			//org.copyTo(img);
    			img.copyTo(tmp);
    			sprintf(temp, "(%d,%d)", x, y);
    			cur_pt = cv::Point(x, y);
    			putText(img, temp, cur_pt, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 255));
    			circle(img, pre_pt, 2, cv::Scalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);
    			rectangle(img, pre_pt, cur_pt, cv::Scalar(0, 255, 0, 0), 1, 8, 0);//根据初始点和结束点,将矩形画到img上  
    			imshow("img", img);
    			img.copyTo(tmp);
    			//截取矩形包围的图像,并保存到dst中  
    			int width = abs(pre_pt.x - cur_pt.x);
    			int height = abs(pre_pt.y - cur_pt.y);
    			if (width == 0 || height == 0)
    			{
    				printf("width == 0 || height == 0");
    				return;
    			}
    			Wid = width;
    			Hei = height;
    			X = pre_pt.x + width / 2;
    			Y = pre_pt.y + height / 2;
    			tracking_flag = true;
    			//dst = org(Rect(min(cur_pt.x, pre_pt.x), min(cur_pt.y, pre_pt.y), width, height));
    			//namedWindow("dst");
    			//imshow("dst", dst);
    			//waitKey(0);
    		}
    
    	}
    	
    }
    
    
    void main()
    {
    	TCHAR szName[] = TEXT("Local\FHY_SYSTEM_0");
    	TrackBox BOX;
    	hMapFile = CreateFileMapping(
    		INVALID_HANDLE_VALUE,    // use paging file
    		NULL,                    // default security
    		PAGE_READWRITE,          // read/write access
    		0,                       // maximum object size (high-order DWORD)
    		BUF_SIZE,                // maximum object size (low-order DWORD)
    		szName);                 // name of mapping object
    
    	if (hMapFile == NULL)
    	{
    		/*printf(TEXT("Could not create file mapping object (%d).
    "),
    			GetLastError());*/
    		return;
    	}
    
    	pBuffer = (LPTSTR)MapViewOfFile(hMapFile,   // handle to map object
    		FILE_MAP_ALL_ACCESS, // read/write permission
    		0,
    		0,
    		BUF_SIZE);
    
    	if (pBuffer == NULL)
    	{
    		/*printf(TEXT("Could not map view of file (%d).
    "),
    			GetLastError());*/
    
    		CloseHandle(hMapFile);
    
    		return;
    	}
    
    	BOX.x = 0;
    	BOX.y = 0;
    	BOX.flag = tracking_flag;
    	
    
    	CSK_Tracker my_tracker;
    	string file_name;
    	ifstream infile("input/Dudek/Name.txt");
    	//getline(infile,file_name);
    	//my_tracker.run_tracker("..\..\data\tiger.avi",Point(16 + 36/2,28 + 36/2),36);
    	//my_tracker.run_tracker("..\..\data\boy.avi",Point(374+68/2, 77+68/2),68);
    	//my_tracker.run_tracker("..\..\CSK\data\oldman.avi",Point(186+50/2, 118+50/2),50);
    
    	//VideoCapture capture("input/bike1.avi");
    	//Mat frame = imread(file_name);
    	////if (!capture.isOpened())
    	//if(frame.empty())
    	//{
    	//	cout << "open video failed!" << endl;
    	//	return;
    	//}
    	//int frame_count = int(capture.get(CV_CAP_PROP_FRAME_COUNT));
    	int frame_count = 1490;
    	//double rate = capture.get(CV_CAP_PROP_FPS);
    	//int width = capture.get(CV_CAP_PROP_FRAME_WIDTH);
    	//int height = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
    	int width = 320;
    	int height = 240;
    	cv::Mat frame;
    	cv::Mat frame_last;
    	cv::Mat alphaf;
    	
    	cv::VideoCapture capture(0);
    	capture.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
    	capture.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
    	
    	while (true)
    	{
    		if (!tracking_flag) 
    		{
    			capture.read(img);
    			cv::namedWindow("img");//定义一个img窗口  
    			cv::setMouseCallback("img", on_mouse, 0);//调用回调函数  
    			imshow("img", img);
    			memcpy(BOX_DATA, &BOX, sizeof(TrackBox));
    			char key = cvWaitKey(10);
    			if (key == 'q') break;
    		}	
    		else
    		{
    			cv::Point pos_first = cv::Point(X, Y);
    			int target_sz[2] = { Hei,Wid };
    			my_tracker.tracke_one(pos_first,target_sz, capture, tracking_flag);
    			
    		}
    		
    	}
    }
    

      

    //#ifdef _CSK_TRACKER_H_
    //#define  _CSK_TRACKER_H_
    
    #include "opencv2/core/core.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <iostream>
    #include <fstream>
    #include <Windows.h>
    
    #define FRAME_SIZE 1920*1080
    #define BUF_SIZE  FRAME_SIZE*60
    
    typedef struct
    {
    	int x;
    	int y;
    	/*int zx;
    	int zy;*/
    	int width;
    	int height;
    
    
    	int flag = 0;
    
    }TrackBox; //目标检测的上下顶点;
    
    typedef struct
    {
    	int width;
    	int height;
    	int type;
    }imgInfHead;
    
    
    #define BUF_SIZE FRAME_SIZE*10 
    #define FRAME_SIZE 1920*1080
    
    extern HANDLE hMapFile;
    extern LPCTSTR pBuffer;
    
    #define BOX_DATA      (char*)pBuffer+FRAME_SIZE*0  //
    
    #define SEND_IMG00_HEAD (char*)pBuffer+FRAME_SIZE*1 //图像头信息首地址
    #define SEND_IMG00_DATA (char*)pBuffer+FRAME_SIZE*2  //图像数据区首地址
    
    //using namespace cv;
    using namespace std;
    
    class CSK_Tracker
    {
    	
    public:
    	CSK_Tracker();
    	~CSK_Tracker();
    
    	TrackBox BOX;
    
    	void hann2d(cv::Mat& m);
    	cv::Mat dense_guess_kernel(double digma, cv::Mat x, cv::Mat y);
    	cv::Mat dense_guess_kernel(double digma, cv::Mat x);
    	cv::Mat get_subwindow(cv::Mat im, cv::Point pos, int* sz, cv::Mat cos_window);
    	//void run_tracker(string video_name, Point pos, int target_sz);
    	//void tracke_one(ifstream &infile, cv::Point pos_first, int frame_count, int* target_sz, cv::VideoCapture capture);
    	void tracke_one(cv::Point pos_first, int* target_sz, cv::VideoCapture capture, bool &tracking_flag);
    	void tracke_one(ifstream &infile, cv::Point pos_first, int frame_count, int* target_sz, cv::VideoCapture capture);
    	cv::Mat conj(cv::Mat a);
    	cv::Mat c_div(cv::Mat a, cv::Mat b);//a./b
    	cv::Mat c_mul(cv::Mat a, cv::Mat b);//a.*b
    	cv::Mat fft2d(cv::Mat src);
    
    	void print_mat(cv::Mat a, string file_name);//打印矩阵,debug用
    	void print_img(cv::Mat a, string file_name);//打印图片灰度值
    
    private:
    	static const double padding;
    	static const double output_sigma_factor;
    	static const double sigma;
    	static const double lambda;
    	static const double interp_factor;
    
    	static const string test_file;
    
    	
    	
    	
    };
    
    
    
    //#endif
    

      

    #include "CSK_Tracker.h"
    
    using namespace std;
    
    const double CSK_Tracker::padding = 1;
    const double CSK_Tracker::output_sigma_factor = 1.0/16;
    const double CSK_Tracker::sigma = 0.2;
    const double CSK_Tracker::lambda = 0.01;
    const double CSK_Tracker::interp_factor = 0.075;
    const string CSK_Tracker::test_file = "H:\CV\CSK\data\result_c.txt";
    
    HANDLE hMapFile;
    LPCTSTR pBuffer;
    
    CSK_Tracker::CSK_Tracker()
    {
    	
    }
    
    CSK_Tracker::~CSK_Tracker()
    {
    }
    
    void CSK_Tracker::hann2d(cv::Mat& m)
    {
    	cv::Mat a(m.rows,1,CV_32FC1);
    	cv::Mat b(m.cols,1,CV_32FC1);
    	for (int i = 0; i < m.rows; i++)
    	{
    		float t = 0.5 * (1 - cos(2*CV_PI*i/(m.rows - 1)));
    		a.at<float>(i,0) = t;
    	}
    	for (int i = 0; i < m.cols; i++)
    	{
    		float t = 0.5 * (1 - cos(2*CV_PI*i/(m.cols - 1)));
    		b.at<float>(i,0) = t;
    	}
    	m = a * b.t();
    }
    
    cv::Mat CSK_Tracker::dense_guess_kernel(double sigma, cv::Mat x, cv::Mat y)
    {
    	//xf = fft2(x)
    	cv::Mat xf = fft2d(x);
    	vector<cv::Mat> xf_ri(xf.channels());
    	cv::split(xf,xf_ri);
    	
    	//xx = x(:)' * x(:);
    	double xx = 0;
    	cv::Scalar sum_x = cv::sum(x.mul(x));
    	for (int i = 0; i < sum_x.cols; i++)
    	{
    		xx += sum_x[i];
    	}
    
    	//yf = fft2(y)
    	cv::Mat yf = fft2d(y);
    	vector<cv::Mat> yf_ri(yf.channels());
    	cv::split(yf,yf_ri);
    
    	//yy = y(:)' * y(:);
    	double yy = 0;
    	cv::Scalar sum_y = sum(y.mul(y));
    	for (int i = 0; i < sum_y.cols; i++)
    	{
    		yy += sum_y[i];
    	}
    
    	//xyf = xf. * conj(yf) 
    	cv::Mat xyf = c_mul(xf,conj(yf));
    
    	//xy = real(circshift(ifft2(xyf), floor(size(x)/2)));
    	idft(xyf,xyf);
    	xyf = xyf/(xyf.rows*xyf.cols);
    
    	vector<cv::Mat> xy_ri(xyf.channels());
    	cv::split(xyf,xy_ri);
    	cv::Mat xy = xy_ri[0];
    
    	int cx = xy.cols/2;
    	int cy = xy.rows/2;
    	cv::Mat q0(xy, cv::Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant 
    	cv::Mat q1(xy, cv::Rect(cx, 0, cx, cy));  // Top-Right
    	cv::Mat q2(xy, cv::Rect(0, cy, cx, cy));  // Bottom-Left
    	cv::Mat q3(xy, cv::Rect(cx, cy, cx, cy)); // Bottom-Right
    	cv::Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
    	q0.copyTo(tmp);
    	q3.copyTo(q0);
    	tmp.copyTo(q3);
    	q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
    	q2.copyTo(q1);
    	tmp.copyTo(q2);
    
    	int numel_x = x.rows*x.cols;
    	cv::Mat k;
    	exp((-1/pow(sigma,2))*(cv::max)((xx+yy-2*xy)/numel_x,0),k);
    
    	return k;
    }
    
    cv::Mat CSK_Tracker::dense_guess_kernel(double sigma, cv::Mat x)
    {
    	//xf = fft2(x)
    	cv::Mat xf = fft2d(x);
    	vector<cv::Mat> xf_ri(xf.channels());
    	cv::split(xf,xf_ri);
    
    	//xx = x(:)' * x(:);
    	double xx = 0;
    	cv::Scalar sum_x = sum(x.mul(x));
    	for (int i = 0; i < sum_x.cols; i++)
    	{
    		xx += sum_x[i];
    	}
    
    	//yf = xf
    	//yy = xx
    	cv::Mat yf;
    	xf.copyTo(yf);
    	double yy = xx;
    	vector<cv::Mat> yf_ri(yf.channels());
    	cv::split(yf,yf_ri);
    
    	//xyf = xf. * conj(yf) 
    	cv::Mat xyf = c_mul(xf,conj(yf));
    
    	//xy = real(circshift(ifft2(xyf), floor(size(x)/2)));
    	idft(xyf,xyf);
    	xyf = xyf/(xyf.rows*xyf.cols);
    
    	vector<cv::Mat> xy_ri(xyf.channels());
    	cv::split(xyf,xy_ri);
    	cv::Mat xy = xy_ri[0];
    	//print_mat(xy,"xyf.txt");
    
    	int cx = xy.cols/2;
    	int cy = xy.rows/2;
    	cv::Mat q0(xy, cv::Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant 
    	cv::Mat q1(xy, cv::Rect(cx, 0, cx, cy));  // Top-Right
    	cv::Mat q2(xy, cv::Rect(0, cy, cx, cy));  // Bottom-Left
    	cv::Mat q3(xy, cv::Rect(cx, cy, cx, cy)); // Bottom-Right
    	cv::Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
    	q0.copyTo(tmp);
    	q3.copyTo(q0);
    	tmp.copyTo(q3);
    	q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
    	q2.copyTo(q1);
    	tmp.copyTo(q2);
    
    	int numel_x = x.rows*x.cols;
    	cv::Mat k;
    	exp((-1/pow(sigma,2))*(cv::max)((xx+yy-2*xy)/numel_x,0),k);
    
    	return k;
    }
    
    cv::Mat CSK_Tracker::get_subwindow(cv::Mat im, cv::Point pos, int* sz, cv::Mat cos_window)
    {
    	//xs = floor(pos(2)) + (1:sz(2)) - floor(sz(2)/2);
    	//ys = floor(pos(1)) + (1:sz(1)) - floor(sz(1)/2);
    	vector<int> xs(sz[1]);
    	vector<int> ys(sz[0]);
    	for (int i = 0; i < sz[1]; i++)
    	{
    		xs[i] = floor(pos.x) + i - floor(sz[1]/2);
    		xs[i] = (cv::max)((cv::min)(xs[i],im.cols - 1),0);
    	}
    	for (int i = 0; i < sz[0]; i++){
    		ys[i] = floor(pos.y) + i - floor(sz[0]/2);
    		ys[i] = (cv::max)((cv::min)(ys[i],im.rows - ,0);
    	}
    
    	//cout << xs[0]<<" "<< xs[1]<< " "<<xs[2]<<'
    ';
    	//cout << ys[0]<<" "<< ys[1]<< " "<<ys[2];
        //xs(xs < 1) = 1;
        //ys(ys < 1) = 1;
        //xs(xs > size(im,2)) = size(im,2);
        //ys(ys > size(im,1)) = size(im,1);
    	/*for (int i = 0; i < sz[0]; i++)
    	{
    		xs[i] = max(min(xs[i],im.cols - 1),0);
    		ys[i] = max(min(ys[i],im.cols - 1),0);
    	}*/
    
    	cv::Mat out(sz[0],sz[1],CV_32FC1);
    	for (int i = 0; i < sz[0]; i++)
    	{
    		for (int j = 0; j < sz[1]; j++)
    		{
    			out.at<float>(i,j) = float(im.at<uchar>(ys[i],xs[j]))/255 - 0.5;
    		}
    	}
    	//print_mat(out,"out.txt");
    	out = cos_window.mul(out);
    	//print_mat(out,"out.txt");
    	return out;
    }
    
    
    void CSK_Tracker::tracke_one(cv::Point pos_first, int* target_sz, cv::VideoCapture capture, bool &tracking_flag)
    {
    
    
    
    	//%window size, taking padding into account
    	int sz[2] = { floor(target_sz[0] * (1 + padding)),floor(target_sz[1] * (1 + padding)) };
    
    	//%desired output (gaussian shaped), bandwidth proportional to target size
    	double output_sigma = sqrt(target_sz[0] * target_sz[1])*output_sigma_factor;
    	cv::Mat rs(sz[0], sz[1], CV_32FC1);
    	cv::Mat cs(sz[0], sz[1], CV_32FC1);
    	for (int i = 0; i < sz[0]; i++)
    	{
    		for (int j = 0; j < sz[1]; j++)
    		{
    			rs.at<float>(i, j) = i - sz[0] / 2 + 1;
    			cs.at<float>(i, j) = j - sz[1] / 2 + 1;
    		}
    	}
    	//print_mat(rs,"rs.txt");
    	//print_mat(cs,"cs.txt");
    
    	cv::Mat y;
    	exp((-0.5 / pow(output_sigma, 2))*(rs.mul(rs) + cs.mul(cs)), y);
    	//print_mat(y,"y.txt");
    
    
    	//yf = fft2(y)
    	cv::Mat yf;
    	//IplImage *y_temp = &IplImage(y);
    	yf = fft2d(y);
    	vector<cv::Mat> yf_ri(yf.channels());
    	cv::split(yf, yf_ri);
    
    
    	//%store pre-computed cosine window
    	cv::Mat cos_window(sz[0], sz[1], CV_32FC1);
    	hann2d(cos_window);
    	//print_mat(cos_window,"cos_window.txt");
    
    
    	cv::Mat frame;
    	cv::Mat org;
    	cv::Mat x;
    	cv::Mat k;
    	cv::Mat z;
    	cv::Mat alphaf;
    	cv::Mat new_alphaf;
    
    	cv::Point pos = pos_first;
    
    	//VideoCapture capture(0);
    	cv::namedWindow("img");
    	string file_name;
    	int i = 0;
    	while (tracking_flag)
    	{
    		
    		capture.read(org);
    
    
    		if (org.empty())
    		{
    			cout << "fail to open frame" << i << endl;
    			break;
    		}
    
    		if (org.channels() > 1)
    		{
    			cvtColor(org, frame, CV_BGR2GRAY);
    		}
    		//%extract and pre-process subwindow
    		/*ofstream F("frame.txt");
    		for(int p = 0;p < frame.rows;p ++){
    		for(int q = 0;q < frame.cols;q++){
    		F << int(frame.at<uchar>(p,q)) << " ";
    		}
    		F << '
    ';
    		}*/
    		//cout<<frame.rows<<" "<<frame.cols<<endl;
    		//imshow("track_frame",frame);
    		//cvWaitKey(10);
    		//cout<< int(frame.at<float>(239,10)) << int(frame.at<float>(239,20))<< endl; 
    		//imwrite("frame.jpg",frame);
    		//print_img(frame,"frame.txt");
    		x = get_subwindow(frame, pos, sz, cos_window);
    		//print_mat(x,"x.txt");
    
    
    		if (i > 0)
    		{
    			k = dense_guess_kernel(sigma, x, z);
    			//print_mat(k,"k.txt");
    
    			//kf = fft2(k)
    			//IplImage* k_temp = &IplImage(k);
    			cv::Mat kf = fft2d(k);
    			vector<cv::Mat> kf_ri(kf.channels());
    			cv::split(kf, kf_ri);
    			//print_mat(kf_ri[0],"kf.txt");
    
    			//response = real(ifft2(alphaf .* fft2(k)));   %(Eq. 9)
    
    			vector<cv::Mat> response_ri(2);
    			cv::Mat response = c_mul(alphaf, kf);
    			idft(response, response);
    			response = response / (response.rows*response.cols);
    			cv::split(response, response_ri);
    			//print_mat(response_ri[0],"response.txt");
    
    			//%target location is at the maximum response
    			int max_row, max_col;
    			double max_response = 0;
    			for (int j = 0; j < response_ri[0].rows; j++)
    			{
    				for (int k = 0; k < response_ri[0].cols; k++)
    				{
    					if (response_ri[0].at<float>(j, k) > max_response)
    					{
    						max_response = response_ri[0].at<float>(j, k);
    						max_row = j;
    						max_col = k;
    					}
    				}
    			}
    			pos = pos - cv::Point(floor(sz[1] / 2), floor(sz[0] / 2)) + cv::Point(max_col + 1, max_row + 1);
    		}
    
    		x = get_subwindow(frame, pos, sz, cos_window);
    		//print_mat(x,"x.txt");
    		k = dense_guess_kernel(sigma, x);
    		//print_mat(k,"k.txt");
    		//new_alphaf = yf ./ (fft2(k) + lambda);   %(Eq. 7)
    		//IplImage *k_t = &IplImage(k);
    
    		new_alphaf = c_div(yf, (fft2d(k) + lambda));
    		vector<cv::Mat> new_alphaf_ri(2);
    		cv::split(new_alphaf, new_alphaf_ri);
    		//print_mat(new_alphaf_ri[0],"new_alphaf.txt");
    
    		cv::Mat new_z = x;
    
    		if (i == 0)
    		{
    			alphaf = new_alphaf;
    			z = x;
    		}
    		else
    		{
    			alphaf = (1 - interp_factor) * alphaf + interp_factor*new_alphaf;
    			z = (1 - interp_factor) * z + interp_factor * new_z;
    		}
    
    		i++;
    
    		cv::Mat frame_print;
    		org.copyTo(frame_print);
    		rectangle(frame_print, cv::Point(pos.x - target_sz[1] / 2, pos.y - target_sz[0] / 2), cv::Point(pos.x + target_sz[1] / 2, pos.y + target_sz[0] / 2), CV_RGB(255, 255, 255), 1);
    		circle(frame_print, cv::Point(pos.x, pos.y), 2, cvScalar(255, 0, 0));
    
    		//rectangle(frame_print, cv::Point(frame_print.cols/2 - 30, frame_print.rows/2 - 30), cv::Point(frame_print.cols / 2 + 30, frame_print.rows / 2 + 30), CV_RGB(0, 255, 0), 1);
    		circle(frame_print, cv::Point(frame_print.cols/2, frame_print.rows/2), 15, cvScalar(255, 0, 255));
    
    
    		imshow("img", frame_print);
    
    
    		BOX.x = pos.x;
    		BOX.y = pos.y;
    		BOX.width = target_sz[1];
    		BOX.height = target_sz[0];
    		BOX.flag = tracking_flag;
    		memcpy(BOX_DATA, &BOX, sizeof(TrackBox));
    
    		imgInfHead img_inf_head;
    		img_inf_head.width = org.cols;
    		img_inf_head.height = org.rows;
    		img_inf_head.type = org.type();
    		int channels = org.channels();
    
    		memcpy(SEND_IMG00_HEAD, &img_inf_head, sizeof(imgInfHead));
    		memcpy(SEND_IMG00_DATA, org.data, org.cols*org.rows*channels);
    
    		if (cvWaitKey(10) == 's')
    		{
    			tracking_flag = false;
    		}
    
    	}
    
    	return;
    }
    
    
    void CSK_Tracker::tracke_one(ifstream &infile, cv::Point pos_first, int frame_count, int* target_sz, cv::VideoCapture capture)
    {
    
    	//%window size, taking padding into account
    	int sz[2] = { floor(target_sz[0] * (1 + padding)),floor(target_sz[1] * (1 + padding)) };
    
    	//%desired output (gaussian shaped), bandwidth proportional to target size
    	double output_sigma = sqrt(target_sz[0] * target_sz[1])*output_sigma_factor;
    	cv::Mat rs(sz[0], sz[1], CV_32FC1);
    	cv::Mat cs(sz[0], sz[1], CV_32FC1);
    	for (int i = 0; i < sz[0]; i++)
    	{
    		for (int j = 0; j < sz[1]; j++)
    		{
    			rs.at<float>(i, j) = i - sz[0] / 2 + 1;
    			cs.at<float>(i, j) = j - sz[1] / 2 + 1;
    		}
    	}
    	//print_mat(rs,"rs.txt");
    	//print_mat(cs,"cs.txt");
    
    	cv::Mat y;
    	exp((-0.5 / pow(output_sigma, 2))*(rs.mul(rs) + cs.mul(cs)), y);
    	//print_mat(y,"y.txt");
    
    
    	//yf = fft2(y)
    	cv::Mat yf;
    	//IplImage *y_temp = &IplImage(y);
    	yf = fft2d(y);
    	vector<cv::Mat> yf_ri(yf.channels());
    	cv::split(yf, yf_ri);
    
    
    	//%store pre-computed cosine window
    	cv::Mat cos_window(sz[0], sz[1], CV_32FC1);
    	hann2d(cos_window);
    	//print_mat(cos_window,"cos_window.txt");
    
    
    	cv::Mat frame;
    	cv::Mat x;
    	cv::Mat k;
    	cv::Mat z;
    	cv::Mat alphaf;
    	cv::Mat new_alphaf;
    
    	cv::Point pos = pos_first;
    
    	cv::namedWindow("haha");
    	string file_name;
    	
    	for (int i = 0; i < frame_count; ++i) {
    		
    		double totaltime;
    		
    
    		if (!capture.read(frame))
    		{
    			cout << "读取视频失败" << endl;
    			return;
    		}
    
    		/*getline(infile,file_name);
    		frame = imread(file_name);*/
    
    		if (frame.empty())
    		{
    			cout << "fail to open frame" << i << endl;
    			break;
    		}
    
    		if (frame.channels() > 1)
    		{
    			cvtColor(frame, frame, CV_BGR2GRAY);
    		}
    		//%extract and pre-process subwindow
    		/*ofstream F("frame.txt");
    		for(int p = 0;p < frame.rows;p ++){
    		for(int q = 0;q < frame.cols;q++){
    		F << int(frame.at<uchar>(p,q)) << " ";
    		}
    		F << '
    ';
    		}*/
    		//cout<<frame.rows<<" "<<frame.cols<<endl;
    		//imshow("track_frame",frame);
    		//cvWaitKey(10);
    		//cout<< int(frame.at<float>(239,10)) << int(frame.at<float>(239,20))<< endl; 
    		//imwrite("frame.jpg",frame);
    		//print_img(frame,"frame.txt");
    		x = get_subwindow(frame, pos, sz, cos_window);
    		//print_mat(x,"x.txt");
    
    
    		if (i > 0)
    		{
    			k = dense_guess_kernel(sigma, x, z);
    			//print_mat(k,"k.txt");
    
    			//kf = fft2(k)
    			//IplImage* k_temp = &IplImage(k);
    			cv::Mat kf = fft2d(k);
    			vector<cv::Mat> kf_ri(kf.channels());
    			cv::split(kf, kf_ri);
    			//print_mat(kf_ri[0],"kf.txt");
    
    			//response = real(ifft2(alphaf .* fft2(k)));   %(Eq. 9)
    
    			vector<cv::Mat> response_ri(2);
    			cv::Mat response = c_mul(alphaf, kf);
    			idft(response, response);
    			response = response / (response.rows*response.cols);
    			cv::split(response, response_ri);
    			//print_mat(response_ri[0],"response.txt");
    
    			//%target location is at the maximum response
    			int max_row, max_col;
    			double max_response = 0;
    			for (int j = 0; j < response_ri[0].rows; j++)
    			{
    				for (int k = 0; k < response_ri[0].cols; k++)
    				{
    					if (response_ri[0].at<float>(j, k) > max_response)
    					{
    						max_response = response_ri[0].at<float>(j, k);
    						max_row = j;
    						max_col = k;
    					}
    				}
    			}
    			pos = pos - cv::Point(floor(sz[1] / 2), floor(sz[0] / 2)) + cv::Point(max_col + 1, max_row + 1);
    		}
    
    		x = get_subwindow(frame, pos, sz, cos_window);
    		//print_mat(x,"x.txt");
    		k = dense_guess_kernel(sigma, x);
    		//print_mat(k,"k.txt");
    		//new_alphaf = yf ./ (fft2(k) + lambda);   %(Eq. 7)
    		//IplImage *k_t = &IplImage(k);
    
    		new_alphaf = c_div(yf, (fft2d(k) + lambda));
    		vector<cv::Mat> new_alphaf_ri(2);
    		cv::split(new_alphaf, new_alphaf_ri);
    		//print_mat(new_alphaf_ri[0],"new_alphaf.txt");
    
    		cv::Mat new_z = x;
    
    		if (i == 0)
    		{
    			alphaf = new_alphaf;
    			z = x;
    		}
    		else
    		{
    			alphaf = (1 - interp_factor) * alphaf + interp_factor*new_alphaf;
    			z = (1 - interp_factor) * z + interp_factor * new_z;
    		}
    
    
    		//draw
    		// 		rectangle(frame,Point(pos.x - target_sz/2,pos.y - target_sz/2),Point(pos.x + target_sz/2,pos.y + target_sz/2),CV_RGB(255,255,255),2);
    		// 		imshow("haha",frame);
    		// 		uchar key;
    		// 		key = waitKey(10);
    		// 		if (key == 'q')
    		// 		{
    		// 			break;
    		// 		}
    
    		cv::Mat frame_print;
    		frame.copyTo(frame_print);
    		cv::rectangle(frame_print, cv::Point(pos.x - target_sz[1] / 2, pos.y - target_sz[0] / 2), cv::Point(pos.x + target_sz[1] / 2, pos.y + target_sz[0] / 2), CV_RGB(255, 255, 255), 1);
    		cv::circle(frame_print, cv::Point(pos.x, pos.y), 2, cvScalar(255, 0, 0));
    		
    		/*totaltime = (double)(finish - start) / CLOCKS_PER_SEC;*/
    		//cout << "
    此程序的运行时间为" << totaltime * 1000 << "ms!" << endl;
    		imshow("haha", frame_print);
    		cvWaitKey(10);
    
    	}
    
    	return;
    }
    
    
    //void CSK_Tracker::run_tracker(string video_name, Point pos, int target_sz)
    //{
    //	
    //	VideoCapture capture(video_name);
    //	if (!capture.isOpened())
    //	{
    //		cout << "Fail to open video " << video_name << endl;
    //		return;
    //	}
    //	int frame_count = int(capture.get(CV_CAP_PROP_FRAME_COUNT));
    //	double rate = capture.get(CV_CAP_PROP_FPS);
    //	int width = capture.get(CV_CAP_PROP_FRAME_WIDTH);
    //	int height = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
    //
    //	//%window size, taking padding into account
    //	int sz = floor(target_sz * (1 + padding));
    //
    //	//%desired output (gaussian shaped), bandwidth proportional to target size
    //	double output_sigma = target_sz*output_sigma_factor;
    //	Mat rs(sz,sz,CV_32FC1);
    //	Mat cs(sz,sz,CV_32FC1);
    //	for (int i = 0; i < sz; i++)
    //	{
    //		for (int j = 0; j < sz; j++)
    //		{
    //			rs.at<float>(i,j) = i - sz/2 +1;
    //			cs.at<float>(i,j) = j - sz/2 +1;
    //		}
    //	}
    //
    //	Mat y;
    //	exp((-0.5/pow(output_sigma,2))*(rs.mul(rs) + cs.mul(cs)),y);
    //
    //	//yf = fft2(y)
    //	Mat yf;
    //	yf = fft2d(y);
    //	vector<Mat> yf_ri(yf.channels());
    //	cv::split(yf,yf_ri);
    //
    //
    //	//%store pre-computed cosine window
    //	Mat cos_window(sz,sz,CV_32FC1);
    //	hann2d(cos_window);
    //
    //	vector<Point> position(frame_count);
    //
    //	Mat frame;
    //	Mat x;
    //	Mat k;
    //	Mat z;
    //	Mat alphaf;
    //	Mat new_alphaf;
    //
    //	namedWindow("haha");
    //
    //	for (int i = 0; i < frame_count; i++)
    //	{
    //		if (!capture.read(frame))
    //		{
    //			cout << "read frame failed!" << endl;
    //		}
    //		if (frame.channels() > 1)
    //		{
    //			cvtColor(frame,frame,CV_BGR2GRAY);
    //		}
    //
    //		//%extract and pre-process subwindow
    //		
    //		x = get_subwindow(frame, pos, sz, cos_window);
    //		
    //
    //		if (i > 0)
    //		{
    //			k = dense_guess_kernel(sigma,x,z);
    //
    //			//kf = fft2(k)
    //			Mat kf = fft2d(k);
    //			vector<Mat> kf_ri(kf.channels());
    //			cv::split(kf,kf_ri);
    //
    //			//response = real(ifft2(alphaf .* fft2(k)));   %(Eq. 9)
    //
    //			vector<Mat> response_ri(2);
    //			Mat response = c_mul(alphaf,kf);
    //			idft(response,response);
    //			response = response/(response.rows*response.cols);
    //			cv::split(response,response_ri);
    //
    //			//%target location is at the maximum response
    //			int max_row, max_col;
    //			double max_response = 0;
    //			for (int j = 0; j < response_ri[0].rows; j++)
    //			{
    //				for (int k = 0; k < response_ri[0].cols; k++)
    //				{
    //					if (response_ri[0].at<float>(j,k) > max_response)
    //					{
    //						max_response = response_ri[0].at<float>(j,k);
    //						max_row = j;
    //						max_col = k;
    //					}
    //				}
    //			}
    //			pos = pos - Point(floor(sz/2),floor(sz/2)) + Point(max_col,max_row);
    //		}
    //
    //		x = get_subwindow(frame,pos,sz,cos_window);
    //		k = dense_guess_kernel(sigma,x);
    //		//new_alphaf = yf ./ (fft2(k) + lambda);   %(Eq. 7)
    //		new_alphaf = c_div(yf,(fft2d(k) + lambda));
    //		vector<Mat> new_alphaf_ri(2);
    //		cv::split(new_alphaf,new_alphaf_ri);
    //
    //		Mat new_z = x;
    //
    //		if (i == 0)
    //		{
    //			alphaf = new_alphaf;
    //			z = x;
    //		}
    //		else
    //		{
    //			alphaf = (1 - interp_factor) * alphaf +interp_factor*new_alphaf;
    //			z = (1 - interp_factor) * z + interp_factor * new_z;
    //		}
    //
    //		position[i] = pos;
    //
    //		//draw
    //		rectangle(frame,Point(pos.x - target_sz/2,pos.y - target_sz/2),Point(pos.x + target_sz/2,pos.y + target_sz/2),CV_RGB(255,255,255),2);
    //		imshow("haha",frame);
    //		uchar key;
    //		key = waitKey(10);
    //		if (key == 'q')
    //		{
    //			break;
    //		}
    //	}
    //}
    
    cv::Mat CSK_Tracker::conj(cv::Mat a)
    {
    	cv::Mat b;
    	a.copyTo(b);
    	vector<cv::Mat> b_ri(2);
    	cv::split(b,b_ri);
    	b_ri[1] = -b_ri[1];
    	merge(b_ri,b);
    	return b;
    }
    
    cv::Mat CSK_Tracker::c_mul(cv::Mat a, cv::Mat b)
    {
    	if (!(a.channels() == 2 || b.channels() == 2))
    	{
    		cout << "c_mul error!" << endl;
    	}
    	vector<cv::Mat> a_ri(2);
    	vector<cv::Mat> b_ri(2);
    	cv::split(a,a_ri);
    	cv::split(b,b_ri);
    	vector<cv::Mat> c_ri(2);
    	c_ri[0] = a_ri[0].mul(b_ri[0]) - a_ri[1].mul(b_ri[1]);
    	c_ri[1] = a_ri[0].mul(b_ri[1]) + a_ri[1].mul(b_ri[0]);
    	cv::Mat c;
    	merge(c_ri,c);
    	return c;
    }
    cv::Mat CSK_Tracker::c_div(cv::Mat a, cv::Mat b)
    {
    	cv::Mat c;
    	c = c_mul(a,conj(b));
    	vector<cv::Mat> c_ri(2);
    	cv::split(c,c_ri);
    	vector<cv::Mat> mag_b_ri(2);
    	cv::Mat mag_b = c_mul(b,conj(b));
    	cv::split(mag_b,mag_b_ri);
    	c_ri[0] = c_ri[0]/mag_b_ri[0];
    	c_ri[1] = c_ri[1]/mag_b_ri[0];
    	merge(c_ri,c);
    	return c;
    }
    
    cv::Mat CSK_Tracker::fft2d(cv::Mat a)
    {
    	cv::Mat padded_a;
    	//int m_a = getOptimalDFTSize(a.rows);
    	//int n_a = getOptimalDFTSize(a.cols);
    	int m_a = a.rows;
    	int n_a = a.cols;
    	copyMakeBorder(a, padded_a, 0, m_a - a.rows, 0, n_a - a.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    	cv::Mat planes_a[] = { cv::Mat_<float>(padded_a), cv::Mat::zeros(padded_a.size(),CV_32F)};
    	cv::Mat af;
    	merge(planes_a, 2, af);
    	dft(af,af);
    	return af;
    }
    
    
    
    //Mat CSK_Tracker::fft2d(IplImage *src)  
    //{   //实部、虚部  
    //    IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0; 
    //	IplImage *D;
    //    //   int i, j;  
    //    image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  //实部  
    //    //Imaginary part  
    //    image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  //虚部  
    //    //2 channels (image_Re, image_Im)  
    //    Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);  
    //    // Real part conversion from u8 to 64f (double)  
    //    cvConvertScale(src, image_Re);  
    //    // Imaginary part (zeros)  
    //    cvZero(image_Im);  
    //    // Join real and imaginary parts and stock them in Fourier image  
    //    cvMerge(image_Re, image_Im, 0, 0, Fourier);  
    //  
    //    // Application of the forward Fourier transform  
    //    cvDFT(Fourier, D, CV_DXT_FORWARD);  
    //    cvReleaseImage(&image_Re);  
    //    cvReleaseImage(&image_Im);  
    //    cvReleaseImage(&Fourier);  
    //	Mat dst = Mat(D);
    //	return dst;
    //} 
    
    void CSK_Tracker::print_mat(cv::Mat a, string file_name)
    {
    	ofstream fout(file_name);
    	int col = a.cols;
    	int row = a.rows;
    	for(int i = 0; i< row; i++){
    		for(int j = 0; j < col; j++){
    			fout << a.at<float>(i,j) << " ";
    		}
    		fout << '
    ';
    	}
    	fout.close();
    }
    
    void CSK_Tracker::print_img(cv::Mat a, string file_name)
    {
    	ofstream fout(file_name);
    	int col = a.cols;
    	int row = a.rows;
    	for(int i = 0; i< row; i++){
    		for(int j = 0; j < col; j++){
    			fout << float(a.at<uchar>(i,j)) << " ";
    		}
    		fout << endl;
    	}
    	fout.close();
    }
    

      

  • 相关阅读:
    linux下使用kermi续
    关于vhdl中integer消耗资源的一些讨论
    linux时间编程
    Linux下C编程文件编程
    C语言I博客作业04
    C语言I博客作业02
    C语言I博客作业02
    第一周作业
    php 面向对象
    php 面向对象封装和继承
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/8353357.html
Copyright © 2011-2022 走看看