图像边沿平滑处理的matlab实现

完成图像处理的算法:

1、读入文件

通过matlab读取图像文件。


2、获取蒙版

对图像进行逐点扫描,当点的三个通道值至少有一个小于阈值时让这个点变为纯黑色。如图,可见此时的蒙版中心有空缺,且边缘有噪声而且有粘连小块。为了消除这些噪声和小块,我们对图像的蒙版进行腐蚀和扩张操作。


3、对蒙版进行腐蚀

应用matlab的腐蚀函数,选择腐蚀的结构元素为11*11的全1矩阵,对图像进行腐蚀操作,腐蚀后,图像缩小,边缘变得平滑。腐蚀后效果如图:

4、对图像进行扩张操作

将图像复原到原始蒙版,该扩张或丢失边缘信息,正好删除掉噪声和多余的小块。进行扩张所用的结构元素和腐蚀所用的结构元素相同。可以明显看到边缘得到改善。扩张后效果如图:


5、用蒙版遮罩生成图像

利用蒙版的遮罩方式,通过原图生成新的图像。能明显看出边沿的噪声和多余小块被去除。产生的图像如下图:


6、调整图像大小

首先通过getFrame函数得到图像的边框,该函数的原理是从上下左右四个方向对图像进行逼近,记录四个边缘的位置,以便计算缩放的大小。原理如下图:


在获得了边框后,将框内的图像进行一个缩放,使该子图像的长或宽和原图一致,再用空白补齐另外一个方向。最后达到缩放后的图像如下:


matlab程序:

1main.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

附2getSmoothImage.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

 

附3getFrame.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

 

4reScale.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、外包框缩减找边沿

先在图形的边框上划出一条边界,逐渐往里面收缩,遇到物体就不移动该点,直到所有点都不能移动,终止。该方法的问题是在物体是直角时会出现边界断裂的情况。

转载于:https://www.cnblogs.com/maplewizard/archive/2012/11/07/2942040.html

你可能感兴趣的:(图像边沿平滑处理的matlab实现)