一、算法原理
协方差描述子(Covariance Descriptor)是一种有效的区域特征表示方法,通过计算图像区域的多维特征协方差矩阵来描述目标的外观和纹理特性。
1.1 特征向量构造
对于每个像素点 ( x , y ) (x, y) (x,y),构造特征向量:
F ( x , y ) = [ x , y , I ( x , y ) , ∣ ∇ I x ∣ , ∣ ∇ I y ∣ ] T F(x,y) = [x, y, I(x,y), |\nabla I_x|, |\nabla I_y|]^T F(x,y)=[x,y,I(x,y),∣∇Ix∣,∣∇Iy∣]T
其中:
- x , y x, y x,y:像素坐标
- I ( x , y ) I(x,y) I(x,y):灰度强度
- ∣ ∇ I x ∣ , ∣ ∇ I y ∣ |\nabla I_x|, |\nabla I_y| ∣∇Ix∣,∣∇Iy∣:x和y方向的梯度幅值
1.2 协方差矩阵计算
对于包含N个像素的区域R,协方差矩阵为:
C R = 1 N ∑ i = 1 N ( f i − μ ) ( f i − μ ) T C_R = \frac{1}{N}\sum_{i=1}^{N}(f_i - \mu)(f_i - \mu)^T CR=N1i=1∑N(fi−μ)(fi−μ)T
其中 μ \mu μ 是特征向量的均值。
1.3 距离度量
使用Förstner距离比较两个协方差矩阵:
d ( C 1 , C 2 ) = ∑ i = 1 d ln 2 λ i ( C 1 , C 2 ) d(C_1, C_2) = \sqrt{\sum_{i=1}^{d}\ln^2\lambda_i(C_1, C_2)} d(C1,C2)=i=1∑dln2λi(C1,C2)
其中 λ i \lambda_i λi 是广义特征值。
二、Matlab实现
2.1 主程序
matlab
%% 基于协方差矩阵的车辆检测系统
clear all; close all; clc;
% 读取测试图像
img = imread('test_image.jpg');
if size(img, 3) == 3
gray_img = rgb2gray(img);
else
gray_img = img;
end
% 显示原图
figure('Name', '协方差车辆检测系统', 'NumberTitle', 'off');
subplot(2,3,1); imshow(img); title('原始图像');
%% 步骤1:预处理和候选区域生成
% 使用背景差分或滑动窗口生成候选区域
candidate_regions = generate_candidates(gray_img);
%% 步骤2:加载预训练的模型
% 这里使用示例数据,实际应用中应加载预计算的车辆协方差模型
car_model = load('car_covariance_model.mat');
truck_model = load('truck_covariance_model.mat');
if ~isfield(car_model, 'cov_matrix')
% 如果没有预训练模型,使用示例图像训练
fprintf('未找到预训练模型,使用示例图像训练...\n');
car_model.cov_matrix = train_covariance_model('car_samples/', gray_img);
truck_model.cov_matrix = train_covariance_model('truck_samples/', gray_img);
end
%% 步骤3:检测每个候选区域
detections = [];
for i = 1:length(candidate_regions)
region = candidate_regions(i);
% 提取区域特征并计算协方差矩阵
cov_matrix = compute_covariance_descriptor(gray_img, region);
% 计算与车辆模型的距离
dist_to_car = covariance_distance(car_model.cov_matrix, cov_matrix);
dist_to_truck = covariance_distance(truck_model.cov_matrix, cov_matrix);
% 分类决策
if min(dist_to_car, dist_to_truck) < 0.5 % 距离阈值
if dist_to_car < dist_to_truck
class = 'Car';
confidence = 1 - dist_to_car;
else
class = 'Truck';
confidence = 1 - dist_to_truck;
end
detections = [detections; region.x, region.y, region.width, region.height, confidence, class];
end
end
%% 步骤4:非极大值抑制
final_detections = non_maximum_suppression(detections, 0.3);
%% 步骤5:显示结果
result_img = img;
for i = 1:size(final_detections, 1)
det = final_detections(i,:);
rect = [det(1), det(2), det(3), det(4)];
if strcmp(det(6), 'Car')
color = [0, 255, 0]; % 绿色表示小汽车
else
color = [255, 0, 0]; % 蓝色表示卡车
end
result_img = insertShape(result_img, 'Rectangle', rect, ...
'LineWidth', 3, 'Color', color);
% 添加标签
label = sprintf('%s: %.2f', det(6), det(5));
result_img = insertText(result_img, [det(1), det(2)-20], label, ...
'FontSize', 12, 'BoxOpacity', 0.8, 'TextColor', 'white');
end
subplot(2,3,2); imshow(result_img); title('检测结果');
% 显示置信度分布
subplot(2,3,3);
histogram([detections(:,5)], 20, 'FaceColor', 'blue', 'EdgeColor', 'black');
title('检测置信度分布'); xlabel('置信度'); ylabel('数量');
fprintf('检测完成!共检测到 %d 个车辆目标\n', size(final_detections, 1));
2.2 协方差描述子计算函数
matlab
function cov_matrix = compute_covariance_descriptor(img, region)
% 计算图像区域的协方差描述子
% 输入:
% img - 灰度图像
% region - 区域结构体,包含x,y,width,height字段
% 输出:
% cov_matrix - 5x5协方差矩阵
% 提取区域
x = region.x;
y = region.y;
w = region.width;
h = region.height;
% 边界检查
[h_img, w_img] = size(img);
x = max(1, min(x, w_img-w));
y = max(1, min(y, h_img-h));
w = min(w, w_img-x);
h = min(h, h_img-y);
roi = img(y:y+h-1, x:x+w-1);
% 计算梯度
[Gx, Gy] = imgradientxy(roi, 'sobel');
Gmag = imgradientmag(roi, 'sobel');
% 创建坐标网格
[X, Y] = meshgrid(1:w, 1:h);
% 构建特征向量矩阵 [x坐标, y坐标, 灰度值, x梯度, y梯度]
features = [X(:), Y(:), double(roi(:)), abs(Gx(:)), abs(Gy(:))];
% 计算协方差矩阵
cov_matrix = cov(features, 0); % 使用N-1归一化
% 确保协方差矩阵是正定的
cov_matrix = cov_matrix + eye(size(cov_matrix)) * 1e-6;
end
2.3 协方差距离计算函数
matlab
function distance = covariance_distance(C1, C2)
% 计算两个协方差矩阵之间的距离(Förstner距离)
% 输入:
% C1, C2 - 协方差矩阵
% 输出:
% distance - 两个矩阵之间的距离
% 使用广义特征值计算距离
try
% 计算广义特征值:C1*v = lambda*C2*v
[V, D] = eig(C1, C2);
eigenvalues = diag(D);
% 移除无效的特征值
eigenvalues = eigenvalues(eigenvalues > 0 & isfinite(eigenvalues));
if isempty(eigenvalues)
distance = inf;
return;
end
% 计算Förstner距离
log_vals = log(eigenvalues);
distance = sqrt(sum(log_vals.^2));
catch
% 如果出现数值问题,使用替代距离度量
distance = norm(C1 - C2, 'fro');
end
end
2.4 候选区域生成函数
matlab
function regions = generate_candidates(img)
% 生成候选区域(滑动窗口方法)
% 输入:
% img - 输入图像
% 输出:
% regions - 候选区域结构体数组
[h, w] = size(img);
% 定义多尺度窗口
scales = [0.5, 0.75, 1.0, 1.5];
base_sizes = [32, 64, 96, 128]; % 基础窗口大小
regions = [];
region_idx = 1;
for scale = scales
for base_size = base_sizes
win_size = round(base_size * scale);
% 确保窗口大小合理
if win_size < 20 || win_size > min(h, w)/2
continue;
end
% 滑动窗口
step = max(4, round(win_size/4));
for y = 1:step:h-win_size
for x = 1:step:w-win_size
regions(region_idx).x = x;
regions(region_idx).y = y;
regions(region_idx).width = win_size;
regions(region_idx).height = win_size;
region_idx = region_idx + 1;
end
end
end
end
fprintf('生成了 %d 个候选区域\n', length(regions));
end
2.5 训练函数
matlab
function model = train_covariance_model(sample_dir, template_img)
% 训练协方差模型
% 输入:
% sample_dir - 样本图像目录
% template_img - 模板图像(用于提取区域)
% 输出:
% model - 训练好的模型
% 如果没有真实样本,使用示例区域
if exist(sample_dir, 'dir')
files = dir(fullfile(sample_dir, '*.jpg'));
cov_matrices = [];
for i = 1:min(length(files), 10) % 最多使用10个样本
img_file = fullfile(sample_dir, files(i).name);
img = imread(img_file);
if size(img, 3) == 3
img = rgb2gray(img);
end
% 创建示例区域
region.x = 1;
region.y = 1;
region.width = size(img, 2);
region.height = size(img, 1);
% 计算协方差矩阵
cov_matrix = compute_covariance_descriptor(img, region);
cov_matrices(:,:,i) = cov_matrix;
end
% 计算平均协方差矩阵
model.cov_matrix = mean(cov_matrices, 3);
else
% 使用示例图像的中心区域作为模板
[h, w] = size(template_img);
region.x = round(w/4);
region.y = round(h/4);
region.width = round(w/2);
region.height = round(h/2);
model.cov_matrix = compute_covariance_descriptor(template_img, region);
end
end
2.6 非极大值抑制函数
matlab
function filtered_boxes = non_maximum_suppression(boxes, overlap_thresh)
% 非极大值抑制
% 输入:
% boxes - 检测框矩阵 [x,y,w,h,confidence,class]
% overlap_thresh - 重叠阈值
% 输出:
% filtered_boxes - 过滤后的检测框
if isempty(boxes)
filtered_boxes = [];
return;
end
% 按置信度排序
[~, idx] = sort(boxes(:,5), 'descend');
boxes = boxes(idx,:);
filtered_boxes = [];
while ~isempty(boxes)
% 保留置信度最高的框
filtered_boxes = [filtered_boxes; boxes(1,:)];
if size(boxes,1) == 1
break;
end
% 计算与其他框的重叠度
box1 = boxes(1,:);
overlaps = zeros(size(boxes,1)-1, 1);
for i = 2:size(boxes,1)
box2 = boxes(i,:);
% 计算交集区域
x1 = max(box1(1), box2(1));
y1 = max(box1(2), box2(2));
x2 = min(box1(1)+box1(3), box2(1)+box2(3));
y2 = min(box1(2)+box1(4), box2(2)+box2(4));
if x2 > x1 && y2 > y1
inter_area = (x2-x1) * (y2-y1);
box1_area = box1(3) * box1(4);
box2_area = box2(3) * box2(4);
union_area = box1_area + box2_area - inter_area;
overlaps(i-1) = inter_area / union_area;
else
overlaps(i-1) = 0;
end
end
% 保留重叠度小于阈值的框
keep_idx = find(overlaps < overlap_thresh) + 1;
boxes = boxes([1; keep_idx], :);
end
end
三、使用说明
3.1 文件结构
vehicle_detection/
├── main.m % 主程序
├── compute_covariance_descriptor.m % 协方差计算
├── covariance_distance.m % 距离计算
├── generate_candidates.m % 候选区域生成
├── train_covariance_model.m % 模型训练
├── non_maximum_suppression.m % 非极大值抑制
├── car_samples/ % 小汽车样本目录
├── truck_samples/ % 卡车样本目录
└── test_image.jpg % 测试图像
3.2 运行步骤
- 准备样本图像 :在
car_samples/和truck_samples/目录中放入正负样本 - 运行主程序 :执行
main.m - 查看结果:程序会显示检测结果和置信度分布
3.3 参数调优建议
| 参数 | 建议值 | 说明 |
|---|---|---|
overlap_thresh |
0.3~0.5 | 非极大值抑制阈值 |
distance_threshold |
0.3~0.7 | 距离分类阈值 |
scales |
[0.5, 0.75, 1.0, 1.5] | 多尺度检测 |
base_sizes |
[32, 64, 96, 128] | 基础窗口大小 |
参考代码 基于协方差检测图片中的汽车或者卡车 www.youwenfan.com/contentcst/122541.html
四、性能评估
4.1 算法复杂度分析
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| 协方差计算 | O(N×d²) | N为像素数,d为特征维数 |
| 距离计算 | O(d³) | 矩阵求逆和特征值分解 |
| 候选区域 | O((H×W)/(step²)×S) | S为尺度数 |
4.2 优化建议
- 积分图像加速:使用积分图像加速特征计算
- GPU加速:使用MATLAB的GPU计算功能
- 特征降维:使用PCA减少特征维度
- 级联分类器:先用简单特征快速过滤
五、总结
基于协方差矩阵的车辆检测方法具有以下特点:
优势:
- 对光照变化和部分遮挡具有鲁棒性
- 特征表示紧凑,计算效率高
- 无需复杂训练过程
- 适用于实时应用
局限性:
- 对尺度变化敏感
- 需要合适的候选区域生成
- 检测精度不如深度学习方法
适用场景:
- 嵌入式系统实现
- 实时视频流处理
- 资源受限环境
- 作为深度学习模型的补充特征