基于协方差矩阵的车辆检测(Matlab实现)

一、算法原理

协方差描述子(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 运行步骤

  1. 准备样本图像 :在car_samples/truck_samples/目录中放入正负样本
  2. 运行主程序 :执行main.m
  3. 查看结果:程序会显示检测结果和置信度分布

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 优化建议

  1. 积分图像加速:使用积分图像加速特征计算
  2. GPU加速:使用MATLAB的GPU计算功能
  3. 特征降维:使用PCA减少特征维度
  4. 级联分类器:先用简单特征快速过滤

五、总结

基于协方差矩阵的车辆检测方法具有以下特点:

优势:

  • 对光照变化和部分遮挡具有鲁棒性
  • 特征表示紧凑,计算效率高
  • 无需复杂训练过程
  • 适用于实时应用

局限性:

  • 对尺度变化敏感
  • 需要合适的候选区域生成
  • 检测精度不如深度学习方法

适用场景:

  • 嵌入式系统实现
  • 实时视频流处理
  • 资源受限环境
  • 作为深度学习模型的补充特征
相关推荐
Evand J2 小时前
【MATLAB程序】基于RSSI的RFID二维轨迹定位仿真介绍,EKF滤波增加轨迹定位精度。附下载链接
开发语言·matlab·平面·滤波·定位·导航
guygg882 小时前
MATLAB实现Bouc-Wen模型动力响应计算
开发语言·matlab
aini_lovee2 小时前
基于MATLAB实现行人检测
开发语言·matlab
郝YH是人间理想2 小时前
考研数学二图鉴——矩阵
线性代数·考研·矩阵
六bring个六2 小时前
opencv读取图片和视频
opencv·计算机视觉
格林威2 小时前
面阵相机 vs 线阵相机:堡盟与海康相机选型差异全解析 附C# 实战演示
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
️是782 小时前
信息奥赛一本通—编程启蒙(3380:练65.3 螺旋矩阵)
线性代数·算法·矩阵
格林威2 小时前
面阵相机 vs 线阵相机:堡盟与海康相机选型差异全解析+python实战演示
开发语言·人工智能·python·数码相机·计算机视觉·视觉检测·工业相机
格林威3 小时前
面阵相机 vs 线阵相机:堡盟与Basler选型差异全解析 +C++ 实战演示
开发语言·c++·人工智能·数码相机·计算机视觉·视觉检测·工业相机