《数字图像处理原理与实践,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);

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

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