• 《数字图像处理原理与实践(MATLAB文本)》书代码Part7


    这篇文章是《数字图像处理原理与实践(MATLAB文本)》一本书的代码系列Part7(由于调整先前宣布订单,请读者注意分页程序,而不仅仅是基于标题数的一系列文章),第一本书特色186经225的代码页,有需要的读者下载用于科研。已经过半。代码运行结果请參见原书配图,建议下载代码前阅读下文:

    关于《数字图像处理原理与实践(MATLAB版)》一书代码公布的说明

    http://blog.csdn.net/baimafujinji/article/details/40987807


    P186


    A = rgb2gray(imread('circle.png'));
    B = edge(A, 'canny');
    [centers, radii, metric] = imfindcircles(B,[22 65]);
    imshow(A);
    viscircles(centers, radii,'EdgeColor','b');


    P195

    BW = imread('contour.bmp');
    imshow(BW,[]);
    hold on

    s=size(BW);
    for row = 2:55:s(1)
       for col=1:s(2)
          if BW(row,col),
             break;
          end
       end

       contour = bwtraceboundary(BW, [row, col], 'W', 8);
       if(~isempty(contour))
          plot(contour(:,2),contour(:,1),'g','LineWidth',2);
       end
    end

    P197

    I = im2bw(imread('penguins.bmp'), 0.38);
    BW = 1-I;
    B = bwboundaries(BW,8,'noholes');
    imshow(I)
    hold on

    for k = 1:length(B)
        boundary = B{k};
        plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 2)
    end

    补充一点小技巧。先前在写Demo的时候没想过这个问题。后来是由于要为图书做插图。所以就须要把处理结果的白边去掉,以下这段代码实现了这样的结果。与图像处理无关。这样的方法也没有出如今书里。不过关于MATLAB保存图像时的一点小技巧而已。



    I = im2bw(imread('penguins.bmp'), 0.38);
    BW = 1-I;
    B = bwboundaries(BW,8,'noholes');
    imshow(I,'border','tight');
    hold on

    for k = 1:length(B)
        boundary = B{k};
        plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 2)
    end

    saveas(gcf,'pengs3.bmp');

    P203

    I = imread('nums.bmp');
    locs =[57 64;47 103;81 224;94 274;11 365;85 461;86 540];
    BW = imfill(I, locs, 4);
    imshow(BW);

    P204

    I = imread('nums.bmp');
    BW2 = imfill(I,'holes');
    imshow(BW2);

    P205

    I = imread('tire.tif');
    I2 = imfill(I);
    figure, imshow(I), figure, imshow(I2)

    P206

    I = imread('eight.tif');
    c = [222 272 300 270 221 194];
    r = [21 21 75 121 121 75];
    J = roifill(I,c,r);
    imshow(I)
    figure, imshow(J)

    P207

    function J = regiongrowing(I,x,y,threshold)

    if(exist('threshold','var')==0), threshold=0.2; end
    J = zeros(size(I)); % 用来标记输出结果的二值矩阵
    [m n] = size(I); % 输入图像的尺寸
    reg_mean = I(x,y); % 被切割区域的灰度均值
    reg_size = 1; % 区域中像素的数目
    % 用以存储被切割出来的区域的邻域点的堆栈
    neg_free = 10000; neg_pos=0;
    neg_list = zeros(neg_free,3);
    delta=0; % 最新被引入的像素与区域灰度均值的差值

    % 区域生长直至满足终止条件
    while(delta<threshold && reg_size<numel(I))

        % 检測邻域像素,并判读是否将其划入区域
        for i = -1:1
            for j = -1:1
                xn = x + i; yn = y + j; % 计算邻域点的坐标
                % 检查邻域像素是否越界
                indicator = (xn >= 1)&&(yn >= 1)&&(xn <= m)&&(yn <= n);
            
                % 假设邻域像素还不属于被切割区域则增加堆栈
                if(indicator && (J(xn,yn)==0))
                    neg_pos = neg_pos+1;
                    neg_list(neg_pos,:) = [xn yn I(xn,yn)]; J(xn,yn)=1;
                end
            end
        end
        
        if(neg_pos+10>neg_free), % 假设堆栈空间不足。则对其进行扩容
            neg_free=neg_free+10000;
            neg_list((neg_pos+1):neg_free,:)=0;
        end
        
        % 将那些灰度值最接近区域均值的像素增加到区域中去
        dist = abs(neg_list(1:neg_pos,3)-reg_mean);
        [delta, index] = min(dist);
        J(x,y)=2; reg_size=reg_size+1;
        
        % 计算新区域的均值
        reg_mean = (reg_mean*reg_size + neg_list(index,3))/(reg_size+1);
        % 保存像素坐标。然后将像素从堆栈中移除
        x = neg_list(index,1); y = neg_list(index,2);
        neg_list(index,:)=neg_list(neg_pos,:); neg_pos=neg_pos-1;
    end

    % 将由区域生长得到的切割区域以二值矩阵的形式返回
    J=J>1;

    P208

    I = im2double(rgb2gray(imread('penguins.bmp')));
    x = 244; y = 679;
    J = regiongrowing(I,x,y,0.2);
    figure, imshow(I+J);

    P213

    I = imread('liftingbody.png');
    S = qtdecomp(I,.27);
    blocks = repmat(uint8(0),size(S));

    for dim = [512 256 128 64 32 16 8 4 2 1];    
      numblocks = length(find(S==dim));    
      if (numblocks > 0)        
        values = repmat(uint8(1),[dim dim numblocks]);
        values(2:dim,2:dim,:) = 0;
        blocks = qtsetblk(blocks,S,dim,values);
      end
    end

    blocks(end,1:end) = 1;
    blocks(1:end,end) = 1;
    imshow(I), figure, imshow(blocks,[])

    P219

    rgb = imread('potatos.jpg');
    I = rgb2gray(rgb);

    hy = fspecial('sobel');
    hx = hy';
    Iy = imfilter(double(I), hy, 'replicate');
    Ix = imfilter(double(I), hx, 'replicate');
    gradmag = sqrt(Ix.^2 + Iy.^2);

    L = watershed(gradmag);
    Lrgb = label2rgb(L);
    figure
    subplot(1, 2, 1); imshow(gradmag,[]), title('梯度幅值图像')
    subplot(1, 2, 2); imshow(Lrgb); title('对梯度图直接做分水岭切割')

    P221-P224

    rgb = imread('potatos.jpg');
    I = rgb2gray(rgb);

    hy = fspecial('sobel');
    hx = hy';
    Iy = imfilter(double(I), hy, 'replicate');
    Ix = imfilter(double(I), hx, 'replicate');
    gradmag = sqrt(Ix.^2 + Iy.^2);

    se = strel('disk', 12);
    Ie = imerode(I, se);
    Iobr = imreconstruct(Ie, I);

    Iobrd = imdilate(Iobr, se);
    Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));
    Iobrcbr = imcomplement(Iobrcbr);

    fgm = imregionalmax(Iobrcbr);
    It1 = rgb(:, :, 1);
    It2 = rgb(:, :, 2);
    It3 = rgb(:, :, 3);
    It1(fgm) = 255; It2(fgm) = 0; It3(fgm) = 0;
    I2 = cat(3, It1, It2, It3);

    figure
    subplot(1, 2, 1); imshow(fgm, []); title('局部极大值图像');
    subplot(1, 2, 2); imshow(I2); title('局部极大值叠加图像');

    se2 = strel(ones(15,15));
    fgm2 = imclose(fgm, se2);
    fgm3 = imerode(fgm2, se2);
    fgm4 = bwareaopen(fgm3, 400);

    bw = im2bw(Iobrcbr, graythresh(Iobrcbr));
    D = bwdist(bw);
    DL = watershed(D);
    bgm = DL == 0;
    gradmag2 = imimposemin(gradmag, bgm | fgm4);

    L = watershed(gradmag2);
    %第一种显示方法
    Lrgb = label2rgb(L, 'jet', 'w', 'shuffle');
    figure
    subplot(1,2,1), imshow(Lrgb), title('分水岭切割结果显示1');
    %另外一种显示方法
    subplot(1, 2, 2); imshow(rgb, []), title('分水岭切割结果显示2');
    hold on;
    himage = imshow(Lrgb);
    set(himage, 'AlphaData', 0.3);

    (代码公布未完成。请也许...)

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    用vs调试sql存储过程
    Html插入Flash.object.embed.swf各个参数值详解介绍[等比例缩放]
    SQL SERVER分区具体例子详解
    C#身份证识别相关技术
    C#调用Java方法(详细实例)
    Visual Studio各版本工程文件之间的转换
    彻底解决asp.net mvc5.2.2:vs2013 cshtml视图文件报错(当前上下文中不存在名称“model”,ViewBag,Url)
    HTML 5 Web 本地存储
    让WeuiPicker隐藏日期中的日,只保留年月
    javascript获取值
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4855318.html
Copyright © 2020-2023  润新知