参考链接
考虑:matconvnet官方给出的神经网络分类器imagenet-googleNet-dag.mat已经具备了较强的识别能力,能识别1000种标签。利用它再编写一个滑动窗口函数,即可实现对大图像的内容搜索。(如现在我们想在一颗果树上寻找果子)
分析:
图像中目标对象的大小往往不同,所以采用多个不同尺寸的滑动窗口对图像进行处理。处理时,窗口由左向右,由上到下按照一定的步长逐次移动。每次移动,将框内的图像输入神经网络进行处理,然后通过得到的结果做出相应的处理。
在这里,若分类的标签号大于900(考虑到干扰,只需要分类结果满足为水果),且置信度大于0.9,则记录该窗口的位置,在原图上用黑框将这个位置标出。
首先是编写窗口尺寸不变的滑动窗函数:slide.m
function [ out_image,n ] = slide( image, rows, cols, step,net )
%窗口尺寸不变的滑动窗函数
% 参数:图像变量矩阵,窗口行数,列数,步长,神经网络对象 输出为符合要求的窗口的左上角的位置和个数
win = zeros(rows, cols, 3);
out_image = zeros(1,2);
n = 0;
for i = 1:step:(size(image,1)-rows) %垂直滑动
for j = 1:step:(size(image,2)-cols) %水平滑动
win = image(i:i+rows-1,j:j+cols-1,:); %提取窗口
imshow(win);
im_ = single(win) ; % note: 0-255 range
im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
im_ = bsxfun(@minus, im_, net.meta.normalization.averageImage) ;
% run the CNN
net.eval({'data', im_}) ;
% obtain the CNN otuput
scores = net.vars(net.getVarIndex('prob')).value ;
scores = squeeze(gather(scores)) ;
% show the classification results
[bestScore, best] = max(scores) ;
if(best>940 && bestScore>0.80) %识别并判断
n=n+1;
out_image(n,:)=[i,j]; %存储位置 [行数,列数]
%pause;
end
end
end
end
接下来利用上面的函数,完成多尺度窗口,并且返回带有黑框标记的图像,以及黑框的数量。
function [ out_image,sum ] = var_slide( image, mrows, mcols, lrows, lcols,net )
%返回具有黑框标记的图像,及黑框个数
% 输入参数:图像矩阵,滑动窗的最小行数,最小列数,最大行数,最大列数,神经网络
out_image = image;
sum = 0;
winn = 1;
if(winn==1)
dr=0;dc=0;
else
dr = round((lrows-mrows)/(winn-1));
dc = round((lcols-mcols)/(winn-1));
end
for i = 0:winn-1;
[ locat, n ] = slide( image, mrows+dr*i, mcols+dc*i, round((mrows+dr*i)/2) ,net);
sum = sum + n ;
for k=1:n
out_image(locat(k,1):(locat(k,1)-1+mrows+dr*i),locat(k,2),:)=0;
out_image(locat(k,1):(locat(k,1)-1+mrows+dr*i),(locat(k,2)-1+mcols+dc*i),:)=0;
out_image(locat(k,1),locat(k,2):(locat(k,2)-1+mcols+dc*i),:)=0;
out_image((locat(k,1)-1+mrows+dr*i),locat(k,2):(locat(k,2)-1+mcols+dc*i),:)=0;
end
end
主程序:test_slide.m
% setup MatConvNet
run matlab/vl_setupnn
% load the pre-trained CNN
net = dagnn.DagNN.loadobj(load('imagenet-googlenet-dag.mat')) ;
net.mode = 'test' ;
a = zeros(1,1);
a = input('Please input the pngs name.\n','s');
a = ['photos/',a];
% load and preprocess an image
im = imread(a);
addpath test;
[ out_image,n ] = var_slide( im, 100, 100, 100, 100, net );figure;imshow(out_image);
saveas(gcf,'myfig.jpg');