完成图像处理的算法:
1、读入文件
通过matlab读取图像文件。
2、获取蒙版
对图像进行逐点扫描,当点的三个通道值至少有一个小于阈值时让这个点变为纯黑色。如图,可见此时的蒙版中心有空缺,且边缘有噪声而且有粘连小块。为了消除这些噪声和小块,我们对图像的蒙版进行腐蚀和扩张操作。
3、对蒙版进行腐蚀
应用matlab的腐蚀函数,选择腐蚀的结构元素为11*11的全1矩阵,对图像进行腐蚀操作,腐蚀后,图像缩小,边缘变得平滑。腐蚀后效果如图:
4、对图像进行扩张操作
将图像复原到原始蒙版,该扩张或丢失边缘信息,正好删除掉噪声和多余的小块。进行扩张所用的结构元素和腐蚀所用的结构元素相同。可以明显看到边缘得到改善。扩张后效果如图:
5、用蒙版遮罩生成图像
利用蒙版的遮罩方式,通过原图生成新的图像。能明显看出边沿的噪声和多余小块被去除。产生的图像如下图:
6、调整图像大小
首先通过getFrame函数得到图像的边框,该函数的原理是从上下左右四个方向对图像进行逼近,记录四个边缘的位置,以便计算缩放的大小。原理如下图:
在获得了边框后,将框内的图像进行一个缩放,使该子图像的长或宽和原图一致,再用空白补齐另外一个方向。最后达到缩放后的图像如下:
附matlab程序:
附1:main.m
inputFilePrefix = 'datacache\\';
outFilePrefix = 'output\\';
fileNamePrefix = 'dst_';
picNum = 79;
pxmin = 10000000;
pdxmax = 0;
pymin = 10000000;
pdymax = 0;
for p = 0:picNum-1
if(p<10)fileName = sprintf('%s0%d.jpg',fileNamePrefix,p);
else fileName = sprintf('%s%d.jpg',fileNamePrefix,p);end;
inputFilePath = [inputFilePrefix fileName];
outputFilePath = [outFilePrefix fileName];
BW = imread(inputFilePath);
[BW1 mask] = getSmoothImage(BW,230);
[px py pdx pdy] = getFrame(mask);
pxmin = min(pxmin,px);
pdxmax = max(pdxmax,pdx);
pymin = min(pymin,py);
pdymax = max(pdymax,pdy);
imwrite(BW1,outputFilePath,'jpg');
p
end
%重新调整大小
for p = 0:picNum-1
if(p<10)fileName = sprintf('%s0%d.jpg',fileNamePrefix,p);
else fileName = sprintf('%s%d.jpg',fileNamePrefix,p);end;
inputFilePath = [outFilePrefix fileName];
outputFilePath = [outFilePrefix fileName];
I = imread(inputFilePath);
INew = reScale(I,pxmin,pdxmax,pymin,pdymax);
imwrite(INew,outputFilePath,'jpg');
imshow(INew);
p
End
附2:getSmoothImage.m
function [ BW1 mask ] = getSmoothImage( BW,threshold )
%GETSMOOTHIMAGE Summary of this function goes here
% Detailed explanation goes here
% 该函数首先得到图形的蒙版,然后对蒙版进行腐蚀和扩张,最后利用蒙版收缩和扩张
HEIGHT = size(BW,1);
WIDTH = size(BW,2);
mask = zeros(HEIGHT,WIDTH,'uint8');
%得到蒙版
threshold = 230;
for i = 1:HEIGHT
for j = 1:WIDTH
if(BW(i,j,1)>threshold&&BW(i,j,2)>threshold&&BW(i,j,3)>threshold)
mask(i,j) = 255;
end
end
end
%腐蚀扩张蒙版
SE = strel('square',11);
mask = imdilate(mask,SE);
mask = imerode(mask,SE);
%利用蒙版遮罩获取图像
BW1 = BW;
for i = 1:HEIGHT
for j = 1:WIDTH
if(mask(i,j) == 255)
BW1(i,j,1) = 255;
BW1(i,j,2) = 255;
BW1(i,j,3) = 255;
end
end
end
end
附3:getFrame.m
function [ x,y,dx,dy ] = getFrame( mask )
%GETFRAME Summary of this function goes here
% Detailed explanation goes here获取图像外框
backGroundColor = 255;
found = false;
for i = 1:size(mask,1)
for j = 1:size(mask,2)
if(mask(i,j) ~= backGroundColor)
y = i;
found = true;
break;
end
end
if found
break;
end
end
found = false;
for i = 1:size(mask,1)
for j = 1:size(mask,2)
if(mask(size(mask,1)-i+1,j) ~= backGroundColor)
dy = size(mask,1)-i+1-y;
found = true;
break;
end
end
if found
break;
end
end
found = false;
for i = 1:size(mask,2)
for j = 1:size(mask,1)
if(mask(j,i) ~= backGroundColor)
x = i;
found = true;
break;
end
end
if found
break;
end
end
found = false;
for i = 1:size(mask,2)
for j = 1:size(mask,1)
if(mask(j,size(mask,2)-i+1) ~= backGroundColor)
dx = size(mask,2)-i+1-x;
found = true;
break;
end
end
if found
break;
end
end
end
附4:reScale.m
function [ INew ] = reScale(I,pxmin,pdxmax,pymin,pdymax)
%RESCALE Summary of this function goes here
% Detailed explanation goes here
global WIDTH;
global HEIGHT;
ISub = I(pymin:pymin+pdymax,pxmin:pxmin+pdxmax,:);
ISubScaled = imresize(ISub,min(WIDTH/pdxmax,HEIGHT/pdymax));
INew = 255*ones(HEIGHT,WIDTH,3,'uint8');
copyWidth = min(size(ISubScaled,2),WIDTH);
copyHeight = min(size(ISubScaled,1),HEIGHT);
if(copyWidth==WIDTH)
pstarty = max(1,floor((HEIGHT-copyHeight)/2));
pstartx = 1;
else
pstartx = max(1,floor((WIDTH-copyWidth)/2));
pstarty = 1;
end
t = ISubScaled(1:copyHeight,1:copyWidth,1);
%INew(pstarty:pstarty+copyHeight-1,pstartx:pstartx+copyWidth-1,3) = t;
for i = 1:copyHeight
for j = 1:copyWidth
INew(pstarty+i-1,pstartx+j-1,:) = ISubScaled(i,j,:);
end
end
end
附:5:在探索过程中所写的一些函数:
1、获取主体中的像素点:
通过getRect函数,通过逐行扫描,依次查找不是纯白色的点,在找到这个点之后,搜索以这个点为左上定点以estimateLength为边长的矩形,统计出纯白点和非纯白点的比例,让这个比例达到一个阈值时,我们认为这个点就是主体中的一个点,可以根据这个点采用floodfill算法。
2、去除其他干扰块的算法:
通过getRect找到的主体中的一个点,向上下左右扩展,采用广度优先的方式,用数组openTable储存每一个搜索到得点,当这个数组为空时说明元素已经全部搜索完成。建立和原图一样大小的indicaterMap来指示该店是否被搜索过。通过该算法,产生图像蒙版。
3、获取图像边框算法
通过逐点扫描图像蒙版,判断每一个点的上下左右是否与自己不同,如果不同,则标记该点为边沿。
4、获取图像最大外缘
通过就收图像蒙版mask,从上下左右四个方向想中间逼近,在遇到图像时,记录当前位置,并储存该位置。该位置用于将所有图像放大到一个合适的大小
5、缩放图像
该函数通过输入图像的最大边框,将所有图像最大边框里的东西放大到原始图像大小。
6、外包框缩减找边沿
先在图形的边框上划出一条边界,逐渐往里面收缩,遇到物体就不移动该点,直到所有点都不能移动,终止。该方法的问题是在物体是直角时会出现边界断裂的情况。