圖像邊沿平滑處理的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、外包框縮減找邊沿

先在圖形的邊框上划出一條邊界,逐漸往里面收縮,遇到物體就不移動該點,直到所有點都不能移動,終止。該方法的問題是在物體是直角時會出現邊界斷裂的情況。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM