所以就有了用matlab来批量提取图像特征向量,并保存,方便后续使用。
批量提取函数 extractAndSaveFeatures.m:
% 函数返回参数
% 分类列向量Categorys, 和 特征向量矩阵Features, 也会自动将两个变量保存在 saveMatName 文件内
% 使用示例
% 提取 train训练集特征和分类
% [Categorys,Features]=extractAndSaveFeatures('train.mat', sourceFolderPath, saveMatPath)
% load('train.mat', '-mat');
% p_Trains_Categorys =Categorys ; %取分类 1列向量
% p_Trains_Features =Features ; %取特征 一行对应一张图全部特征,一列对应一类特征
% 提取 test测试集特征和分类
% [Categorys,Features]=extractAndSaveFeatures('test.mat', sourceFolderPath, saveMatPath)
% load('test.mat', '-mat');
% p_Test_Categorys =Categorys ; %取分类 1列向量
% p_Test_Features =Features ; %取特征 一行对应一张图全部特征,一列对应一类特征
function [ Categorys, Features ]=extractAndSaveFeatures(saveMatName, sourceFolderPath, saveMatPath)
addRootSonDir( ); % 确保依赖函数 已经添加到目录
if nargin < 3 saveMatPath = ''; end %应该是存放在工作区目录下
% 函数输入参数
% saveMatName % 保存的最后结果文件名 mat类型文件名如 train.mat
% sourceFolderPath % 原始文件路径 绝对路径 如 J:/test
% savePath % 保存mat文件变量路径 绝对路径
% 函数返回参数
% 分类列向量Categorys, 和 特征向量矩阵Features, 也会自动将两个变量保存在 saveMatName 文件内
%% 参数设置
sizeA = 96;
sizeB = 96; % 每一张图都为这么大统一处理 长宽调整为a*b
%% 处理开始,获取全部文件列表
fileList = dir(fullfile(sourceFolderPath, '*.png'));% 获取文件夹中所有文件的列表
%% 先单张读取,确定特征长度; 先单张读取,确定特征长度; 先单张读取,确定特征长度;
fileName = fileList(1).name;
[~, name, ~] = fileparts(fileName);
path = fullfile(sourceFolderPath, fileName);
img = imread(path); img = imresize(img, [sizeA, sizeB]);
HogFeatures = extractHOGFeatures(img); %执行HOG特征提取 确保批量提取和这里一致,
RGBFeatures = GetColorHist(img); %执行RBG特征提取
HogLength = size(HogFeatures, 2); %下面用到 这张图片特征向量长度 作为每个张的长度
RGBLength = size(RGBFeatures, 2);
fprintf('提取%s开始\n',saveMatName);
fprintf(' 1.保存文件:%s\n',fullfile(saveMatPath, saveMatName));
fprintf(' 2.提取文件的源目录:%s\n',sourceFolderPath);
fprintf(' 3.批量处理图片的大小:长*宽= %d × %d\n', sizeA, sizeB);
fprintf(' 4.每张图特征向量的长度: Hog:%d RGB:%d\n', HogLength, RGBLength);
%% 批量提取 批量提取 批量提取 批量提取 批量提取 批量提取 批量提取
% 初始化存储数据的向量矩阵
fileNums = length(fileList);
Categorys = zeros(fileNums, 1);
Features = zeros(fileNums, HogLength+RGBLength);
dispStr = sprintf('进度:%6d/%6d', 0, 0);
clearStr= [repmat('\b', 1, numel(dispStr)), '%s'];
fprintf(dispStr);
for i = 1:fileNums
if mod(i, 150) == 0
fprintf(clearStr);fprintf('进度:%6d/%6d', i, fileNums);
end
fileName = fileList(i).name;
[~, name, ~] = fileparts(fileName);%每张图片的文件名字类似于 12_65_100_图片.png
NameFirts_Part = strsplit(name, '_');%切割出文件名第一段数字作为分类编号
Categorys(i, 1) = str2double(NameFirts_Part{1});% 收集分类 本张图片
img = imread(fullfile(sourceFolderPath, fileName));
img = imresize(img, [sizeA, sizeB]); % 读取图片并调整大小为512x512
HogFeatures = extractHOGFeatures(img); % 执行HOG特征提取
RGBFeatures = GetColorHist(img); % 执行RBG特征提取
for j = 1:HogLength % 收集HOG特征向量
Features(i, j) = HogFeatures(:, j);%添加
end
for j = 1:RGBLength % 收集RGB特征向量
Features(i, HogLength+j) = RGBFeatures(:, j);%添加
end
end % for循环处理每张图 end
fprintf(clearStr);fprintf('进度:%6d/%6d, 完成99%%。\n', i, fileNums);
save(fullfile(saveMatPath, saveMatName), 'Features', 'Categorys');% 保存数据为 文件, 在其他.m文件中直接 加载这个可调用变量
fprintf('本轮提取完成,%s保存成功\n------\n',saveMatName);
end
% 如果导入的多个文件中存在同名的变量,会导致冲突。
% 当使用load函数加载多个文件时,如果文件中存在同名的变量,
% 后面加载的文件会覆盖前面加载的文件中的同名变量。
%
% 为了避免变量名冲突,可以在加载文件时使用不同的变量名来存储不同的变量。
% 例如,假设有两个文件data1.mat和data2.mat,它们都包含一个名为x的变量。
% 可以使用以下代码来加载这两个文件,并将它们分别存储在变量x1和x2中:
%
% load('data1.mat', '-mat');
% x1 = x;
%
% load('data2.mat', '-mat');
% x2 = x;
%
% 这样,变量x1和x2分别存储了data1.mat和data2.mat中的x变量,避免了变量名冲突。
function color_hist = GetColorHist(img)
gray_img = rgb2gray(img);
color_hist = imhist(gray_img) / numel(gray_img);
color_hist = color_hist';
end
function addRootSonDir(rootDir) % 将输入的根目录+子目录 全都自动添加入环境变量
if nargin < 1 || isempty(rootDir) % 如果参数为空,将调用本函数的文件所处目录作为rootDir,添加环境变量
stack = dbstack('-completenames');
callingScript = stack(2).file ; % 1-脚本函数自身目录,2-调用所处目录
[scriptDir, ~, ~] = fileparts(callingScript);
rootDir = scriptDir;
end
subDirs = dir(rootDir);
% disp(rootDir);
subDirs = subDirs([subDirs.isdir]);
subDirPath = fullfile(rootDir, subDirs(1).name);
addpath(subDirPath);
for i = 3:length(subDirs) % 从3开始, 因为 1 \. ; 2 \..; 3 子目录第一个;
subDirPath = fullfile(rootDir, subDirs(i).name);
addpath(subDirPath);
end
% disp('---||所有已添加的用户库目录(不包含软件默认的系统库目录):');
% paths = strsplit(path, ';');
% for i = 1:length(paths)
% if ~contains(paths{i}, '\Program Files\MATLAB\') && ~contains(paths{i}, '\AppData\Local\Temp\')
% disp(paths{i});
% end
% end
% disp('---||用户库目录管理操作完成。');
end
主要提取了
下面是如何提取特征示例( main.m ?):
clc,clear;
%添加库文件目录
% ............ extractAndSaveFeatures.m 用到的特征提取函数
% HogFeatures = extractHOGFeatures(img); % 执行HOG特征提取
% RGBFeatures = GetColorHist(img); % 执行RBG特征提取
%% 请分节运行 避免卡死机 ; 选中节段 ,快捷键 ctrl+enter运行节
%%
saveNameT = 'Train.mat'; % 训练集
FolderPathT = '源图片文件路径';
savePathT = '保存路径';
[P_trainTypes,P_trainFeatures]=extractAndSaveFeatures(saveNameT,FolderPathT,savePathT);
%%
saveNameE = 'Test.mat'; % 测试集
FolderPathE = '源图片文件路径';
savePathE = '保存路径';
[P_testTypes,P__testFeatures]=extractAndSaveFeatures(saveNameE,FolderPathE,savePathE);
%% 如何在matlab中调用保存好的.mat 内的变量
% 提取 train训练集特征和分类
% [Categorys,Features]=extractAndSaveFeatures('train.mat', sourceFolderPath, saveMatPath)
% load('train.mat', '-mat');
% p_Trains_Categorys =Categorys ; %取分类 1列向量
% p_Trains_Features =Features ; %取特征 一行对应一张图全部特征,一列对应一类特征
% 提取 test测试集特征和分类
% [Categorys,Features]=extractAndSaveFeatures('test.mat', sourceFolderPath, saveMatPath)
% load('test.mat', '-mat');
% p_Test_Categorys =Categorys ; %取分类 1列向量
% p_Test_Features =Features ; %取特征 一行对应一张图全部特征,一列对应一类特征
还有一些小建议
在MATLAB中,可以使用file.file1 = load('file1')
的方式来解决导入多个文件中存在同名变量的问题。具体操作如下:
load
函数加载第一个文件,并将其保存到一个变量中。例如,加载名为file1.m
的文件:file1 = load('file1.m');
file.file1
的方式将第一个文件的变量赋值给当前工作空间中的同名变量。例如,将file1.m
中的变量myvar
赋值给当前工作空间中的myvar
:file.file1.myvar = file1.myvar;
load
函数加载第二个文件,并将其保存到另一个变量中。例如,加载名为file2.m
的文件:file2 = load('file2.m');
file.file2
的方式将第二个文件的变量赋值给当前工作空间中的同名变量。例如,将file2.m
中的变量myvar
赋值给当前工作空间中的myvar
:file.file2.myvar = file2.myvar;
通过这种方式,即使两个文件中存在同名变量,它们也会被添加到当前工作空间,而不是覆盖彼此。
当然了,在MATLAB中,如果你想要直接加载一个文件并将结果存储在一个结构体中,你可以使用以下语法:
file.file2 = load('file2.m');
这样,file2.m
文件中的所有变量都会被存储在名为file
的结构体中的file2
字段下。如果file2.m
中有与当前工作空间中同名的变量,它们不会被覆盖。相反,你可以通过file.file2.variableName
的方式来访问这些变量。
例如,如果file2.m
中有一个变量myvar
,你可以通过以下方式访问它:
value = file.file2.myvar;