完成圖像處理的算法:
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、外包框縮減找邊沿
先在圖形的邊框上划出一條邊界,逐漸往里面收縮,遇到物體就不移動該點,直到所有點都不能移動,終止。該方法的問題是在物體是直角時會出現邊界斷裂的情況。