搜档网
当前位置:搜档网 › camshift跟踪算法MATLAB源代码注释

camshift跟踪算法MATLAB源代码注释

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%顶层函数camshift%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Adam Kukucka
% Zach Clay
% Marcelo Molina
% CSE 486 Project 3
function [ trackmov probmov centers ] = camshift
%用camshift算法跟踪运动物体,跟踪目标须手动选定
% ******************************************************************
% initialize vari ables
% ******************************************************************
rmin = 0; %min row value for search window
rmax = 0; %max row value for search window
cmin = 0; %min col value for search window
cmax = 0; %max col value for search window
numofframes = 0; %number of frames in the avi
threshold = 1; %threshold for convergence
centerold = [0 0]; %for convergence... previous center of window
centernew = [0 0]; %for convergence... new center of window
% ******************************************************************
% Pre code... load movie and select initial frame
% ******************************************************************
% prompt user for avi file name
%user_entry = input('Please enter an avi filename: ','s');
% load the avi file... handle is M
%从电脑里读取一个avi视频文件
M = aviread('G:\test.avi');
% get number of frames
%获取该视频文件的总帧数numberofframes
[dontneed numberofframes] = size(M);
% initialize matrix to hold center coordinates
%创建矩阵imagecenters,用于存放每一帧的图像质心坐标
imagecenters = zeros(numberofframes, 2);
% extract the first frame from the avi
%把视频文件的第一帧转化成图像Image1
Frame1 = M(1,1);
Image1 = frame2im(Frame1);
%%% ********** images(:, :, numberofframes) = G(:,:);
% get search window for first frame
%调用自定义的目标选定函数select(),得到目标矩形左上角右下角坐标(取整的)
[ cmin, cmax, rmin, rmax ] = select( Image1 );
cmin = round(cmin);
cmax = round(cmax);
rmin = round(rmin);
rmax = round(rmax);
%计算目标的尺寸wsize:长与高
wsize(1) = abs(rmax - rmin);
wsize(2) = abs(cmax - cmin);
% create histogram
% translate to hsv
%把源图像转成hsv格式,取出需要的h通道,赋给huenorm
hsvimage = rgb2hsv(Image1);
% pull out the h
huenorm = hsvimage(:,:,1);
% scale to 0 to 255
%把h通道的数据大小从0-1调为0-255,并转化成uint8格式
hue = huenorm*255;
% set unit type
hue=uint8(hue);
% Getting Histogram of Image:
histogram = zeros(256);
% 计算目标矩形内的色调直方图histogram
for i=rmin:rmax
for j=cmin:cmax
index = uint8(hue(i,j)+1);
%count number of each pixel
histogram(index) = histogram(index) + 1;
end
end
% ******************************************************************
% Algorithm from pdf
% ******************************************************************
%新建两个avi视频文件
aviobj1 = avifile('example3.avi');
aviobj2 = avifile('example4.avi');
% for each frame
%对avi视频文件的前200帧进行camshift跟踪
for i = 1:200
%将每一帧转

成图像进行处理
disp('Processing frame');
disp(i);
Frame = M(1, i);
I = frame2im(Frame);
%图像转成hsv格式,并抽取其中的h通道,存于huenorm
% translate to hsv
hsvimage = rgb2hsv(I);
% pull out the h
huenorm = hsvimage(:,:,1);
%0-1的double转成0-255的uint8格式
% scale to 0 to 255
hue = huenorm*255;
% set unit type
hue=uint8(hue);
%获取整一帧图像的分辨率:rows*cols
[rows cols] = size(hue);

% choose initial search window
% the search window is (cmin, rmin) to (cmax, rmax)
% create a probability map
probmap = zeros(rows, cols);
for r=1:rows
for c=1:cols
if(hue(r,c) ~= 0)
%histogram 是自定义矩阵,对应位置存放了这点的颜色出现的个数,实际上就是反向投影图back_project(prob)
%为什么hue==0时不考虑呢?这样不就丢失了hue==0这种颜色了吗?
%因为probmap初始化就是0,没必要重新赋0吗?不是,是因为矩阵()里不能等于0
probmap(r,c)= histogram(hue(r,c));
end
end
end
%将直方图的反向投影图归一化到256(这样做是当目标较大(如100*100)时,可能有些矩阵元素会很大,这么处理能方便后面的计算)
probmap = probmap/max(max(probmap));%用了两次max()是因为矩阵是二维的
probmap = probmap*255;

count = 0;

%把待检测的一帧的目标中心定在原点(0,0)
rowcenter = 0; % any number just so it runs through at least twice
colcenter = 0;
rowcenterold = 30;
colcenterold = 30;
% Mean Shift for 15 iterations or until convergence(the center doesnt
% change)
%目标中心误差≤2时,或者检测次数超过15次时,介绍循环
while (((abs(rowcenter - rowcenterold) > 2) && (abs(colcenter - colcenterold) > 2)) || (count < 15) )
%for j = 1:5
%disp('meanshift');
% disp(j);
%先扩大待检测矩形,这时搜索窗为15*15,然后调用meanshift算法得到目标中心,再得到原来大小的目标矩形
rmin = rmin - 7; %increase window size and check for center
rmax = rmax + 7; %增大搜索窗的大小为15*15
cmin = cmin - 7;
cmax = cmax + 7;

rowcenterold = rowcenter; %save old center for convergence check
colcenterold = colcenter;

%调用meanshift函数获得质心坐标
[ rowcenter colcenter M00 ] = meanshift(I, rmin, rmax, cmin, cmax, probmap);
% given image (I), search window(rmin rmax cmin cmax)
% returns new center (colcenter, rowcenter) for window and
% zeroth moment (Moo)

% redetermine window around new center
rmin = round(rowcenter - wsize(1)/2);
rmax = round(rowcenter + wsize(1)/2);
cmin = round(colcenter - wsize(2)/2);
cmax = roun

d(colcenter + wsize(2)/2);
wsize(1) = abs(rmax - rmin);
wsize(2) = abs(cmax - cmin);

count = count + 1;
end

% mark center on image

%save image
%把RGB格式的图像I转换成灰度图像trackim
G = .2989*I(:,:,1) + .5870*I(:,:,2) + .1140*I(:,:,3);
trackim=G;

%make box of current search window on saved image
%把trackim矩形的目标边框都赋值为255,即标出跟踪到的窗口的白色边框
for r= rmin:rmax
trackim(r, cmin) = 255;
trackim(r, cmax) = 255;
end
for c= cmin:cmax
trackim(rmin, c) = 255;
trackim(rmax, c) = 255;
end
%在新建的两个视频文件aviobj1,aviobj2里插入帧,一个是画出了方框的视频文件,另一个是反向投影图的视频文件
aviobj1 = addframe(aviobj1,trackim);
aviobj2 = addframe(aviobj2,probmap);

%create image movie, and probability map movie
%camshift函数的返回值,三维矩阵trackmov和probmov,即上面两个视频文件的矩阵形式
trackmov(:,:,i)= trackim(:,:);
probmov(:,:,i) = probmap(:,:);

% save center coordinates as an x, y by doing col, row
%camshift函数的返回值,每一帧跟踪目标的中心
centers(i,:) = [colcenter rowcenter];

%计算动态窗口的大小,当反向投影图的质量大时目标窗口也大,当它质量小时目标窗口也小
%以此实现了目标的缩放跟踪
%但是这种计算不知道是不是定量的计算,看起来貌似是定性的计算
%或者
%跟踪目标的反向投影图密度一定,根据质量=边长*边长*密度,即可得到边长
%但是,密度是多少呢?256?
% Set window size = 2 * (Moo/256)^1/2
windowsize = 2 * (M00/256)^.5;
% get side length ... window size is an area so sqrt(Area)=sidelength
sidelength = sqrt(windowsize);

% determine rmin, rmax, cmin, cmax
%根据meanshift计算到的质量和目标窗口尺寸重新调整窗口尺寸
rmin = round(rowcenter-sidelength/2);
rmax = round(rowcenter+sidelength/2);
cmin = round(colcenter-sidelength/2);
cmax = round(colcenter+sidelength/2);
wsize(1) = abs(rmax - rmin);
wsize(2) = abs(cmax - cmin);
end
% end for loop

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%子函数select%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Adam Kukucka
% Zach Clay
% Marcelo Molina
% CSE 486 Project 3
function [ cmin, cmax, rmin, rmax ] = select( I )
%用鼠标选择跟踪目标,返回其左上角与右下角坐标
% Detailed explanation goes here
% for array... x is cols, y is rows
image(I);
k = waitforbuttonpress;
point1 = get(gca,'CurrentPoint'); %mouse pressed
rectregion = rbbox;
point2 = get(gca,'CurrentPoint');
point1 = point1(1,1:2); % extract col/row min and maxs
point2 = point2(1,1:2);
lowerleft = min(point1, point2);
upperright = max(point1, point2);
%函数round()进行取整
cmin = round(lowerleft(1))

;
cmax = round(upperright(1));
rmin = round(lowerleft(2));
rmax = round(upperright(2));


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%子函数meanshift%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Adam Kukucka
% Zach Clay
% Marcelo Molina
% CSE 486 Project 3
function [ rowcenter colcenter M00 ] = meanshift(I, rmin, rmax, cmin, cmax, probmap)
%用meanshift算法跟踪矩形目标
%传入参数中I是源图像的hsv格式(貌似没用到),probmap跟踪目标的反向投影图(已从360归一化至256),其余为左上角右下角坐标
%函数返回值是跟踪目标反向投影图质心坐标,以及其投影图质量
%直方图的反向投影图的意义:出现概率大的点质量大,
%inputs
% rmin, rmax, cmin, cmax are the coordiantes of the window
% I is the image
%outputs
% colcenter rowcenter are the new center coordinates
% Moo is the zeroth mean
% **********************************************************************
% initialize
% **********************************************************************
M00 = 0; %zeroth mean 投影图质量
M10 = 0; %first moment for x 投影图质量*水平位矢
M01 = 0; %first moment for y 投影图质量*垂直位矢
%下面这三句话好像没作用,可以删去
%histdim = (0:1:255); % dimensions of histogram... 0 to 255, increment by 1
%[rows cols] = size(I);
%cols = cols/3; % **********************8
% **********************************************************************
% Main code
% **********************************************************************
%下面两个双重循环计算图像的0阶质心和1阶质心,并将结果相除,得到图像重心的位置
% determine zeroth moment
for c = cmin:cmax
for r = rmin:rmax
M00 = M00 + probmap(r, c);%计算投影图质量
end
end
% determine first moment for x(col) and y(row)
for c = cmin:cmax
for r = rmin:rmax
M10 = M10 + c*probmap(r,c);%计算投影图质量*水平位矢
M01 = M01 + r*probmap(r,c);%计算投影图质量*垂直位矢
end
end
% determine new centroid
% x is cols
colcenter = M10/M00;%计算投影图水平位矢
% y is rows
rowcenter = M01/M00;%计算投影图垂直位矢

相关主题