matlab二值图像截取 matlab怎么实现图像二值化分割
\u5982\u4f55\u7528Matlab\u5bf9\u4e8c\u503c\u56fe\u50cf\u8fdb\u884c\u77e9\u5f62\u8f6e\u5ed3\u63d0\u53d61 bwperim
\u6839\u636e\u53c2\u8003\u8d44\u6599[2]\u7684\u63d0\u793a\uff0c\u53ef\u4ee5\u4f7f\u7528bwperim()\u51fd\u6570\u8fdb\u884c\u8f6e\u5ed3\u63d0\u53d6\uff0c\u5177\u4f53\u4ee3\u7801\u5982\u4e0b\uff1a
%\u8bfb\u53d6\u539f\u56fe
im = imread( filepath );
imshow(im);
title('\u539f\u56fe');
% \u8f6c\u4e8c\u503c\u56fe\u50cf
bw = im2bw( im );
%\u8f6e\u5ed3\u63d0\u53d6
contour = bwperim(bw);
figure
imshow(contour);
title('\u8f6e\u5ed3')
\u539f\u56fe\u548c\u6240\u63d0\u53d6\u7684\u8f6e\u5ed3\u5206\u522b\u5982\u56fe1\u548c\u56fe2\u6240\u793a\u3002
2 edge
\u53ef\u4ee5\u501f\u52a9edge()\u51fd\u6570\u8fdb\u884c\u8fb9\u754c\u68c0\u6d4b\uff0c\u7b97\u5b50\u53ef\u4ee5\u9009\u62e9canny\uff0csoble\u7b49\u7b49\u3002\u5177\u4f53\u4ee3\u7801\u5982\u4e0b\uff1a
%\u8bfb\u53d6\u539f\u56fe
im = imread( filepath );
imshow(im);
title('\u539f\u56fe');
% \u8f6c\u4e8c\u503c\u56fe\u50cf
bw = im2bw( im );
% \u8fb9\u754c\u68c0\u6d4b
contour = edge(bw ,'canny');
figure
imshow(contour);
title('\u8fb9\u754c')
\u7528\u51fd\u6570im2bw\u53ef\u4ee5\u5b9e\u73b0\u5bf9\u7070\u5ea6\u56fe\u50cf\uff08\u6216\u5f69\u8272\u56fe\u50cf\u7684\u4e8c\u5206\u5904\u7406\uff09\u3002
\u5177\u4f53\u7528\u6cd5\u5982\u4e0b\uff1aBW = im2bw(path, level)\u3002\u5176\u4e2d\uff0cpath\u8868\u793a\u56fe\u7247\u7684\u5b8c\u5168\u8def\u5f84\uff1blevel\u8868\u793a\u533a\u5206\u9ed1\u767d\u8272\u7684\u754c\u9650\uff080~1\u4e4b\u95f4\u7684\u6570\u5b57\uff09\u3002\u8fd4\u56de\u503cBW \u5c31\u662f\u4e00\u4e2a\u53ea\u542b\u670901\u7684\u77e9\u9635\u3002
\u901a\u5e38\u4e8c\u503c\u5316\u540e\uff0c\u7528imshow\u53ef\u4ee5\u770b\u5230\u9ed1\u767d\u56fe\u7247\uff0c\u4f46\u5b9e\u9645\u4e2d\u8fd8\u8981\u6839\u636e\u76ee\u7684\u505a\u8fdb\u4e00\u6b65\u5904\u7406\uff0c\u6bd4\u5982\u8f83\u5c0f\u7684\u5168\u533a\u57570\uff08\u6216\u80051\uff09\u4e3a\u4e86\u6574\u4f53\u5206\u5e03\u7684\u7b80\u5355\u4f1a\u5ffd\u7565\u6389\u3002
可以使用bwperim()函数进行轮廓提取,具体代码如下:
%读取原图
im = imread( filepath );
imshow(im);
title('原图');
% 转二值图像
bw = im2bw( im );
%轮廓提取
contour = bwperim(bw);
figure
imshow(contour);
title('轮廓')
原图和所提取的轮廓分别如图1和图2所示。
图1 原图
图2 轮廓
2 edge
可以借助edge()函数进行边界检测,算子可以选择canny,soble等等。具体代码如下:
%读取原图
im = imread( filepath );
imshow(im);
title('原图');
% 转二值图像
bw = im2bw( im );
% 边界检测
contour = edge(bw ,'canny');
figure
imshow(contour);
title('边界')
对图1的检测效果如图3所示:
图3 edge检测结果
参考资料
[1]轮廓提取
[2]matlab 二值图像 外轮廓提取
[3]matlab 二进制图像轮廓提取
============================================================================================
============================================================================================
转自:http://blog.sina.com.cn/s/blog_6f2d29af0101065p.html
**注意:填充时,轮廓线是闭合连续的
im=imread(filepath); %读取原图
figure,imshow(im,[]);title('Raw'); %显示原图
im=im2bw(im); %转二值图像
figure,imshow(im,[]),title('BW'); %显示二值图像
im2=imfill(im,'holes'); %填充
im3=bwperim(im2); %轮廓提取
figure,imshow(im2,[]); title('') %显示
figure,imshow(im3,[]);
1、Matlab简述
Matlab是国际上最流行的科学与工程计算的软件工具,它起源于矩阵运算,已经发展成一种高度集成的计算机语言。有人称它为“第四代”计算机语言,它提供了强大的科学运算、灵活的程序设计流程、高质量的图形可视化界面设计、便捷的与其它程序和语言接口的功能。随着Matlab语言功能越来越强大,不断适应新的要求并提出新的解决方法,可以预见,在科学运算,自动控制与科学绘图领域,Matlab语言将长期保持其独一无二的地位。
2、几种常用的边缘检测算子
边缘是图像的最重要的特征,。边缘是指周围像素灰度有阶跃变化或屋顶变化的那些像素的集合。边缘检测主要是灰度变化的度量、检测和定位。有很多种不同的边缘检测方法,同一种方法使用的滤波器也不尽相同。图像边缘检测就是研究更好的边缘检测方法和检测算子。
边缘检测的基本思想首先是(1)利用边缘增强算子,突出图像中的局部边缘,(2)然后定义象素的“边缘强度”,通过设置阈值的方法提取边缘点集。由于噪声和模糊的存在,监测到的边界可能会变宽或在某点处发生间断。因此,边界检测包括两个基本内容:
i. 用边缘算子提取出反映灰度变化的边缘点集
ii. 在边缘点集合中剔除某些边界点或填补边界间断点,并将这些边缘连接成完整的线
常用的检测算子有微分算子、拉普拉斯高斯算子和canny算子。
在Matlab图像处理工具箱中,提供了edge函数利用以上算子来检测灰度图像的边缘。
2.1微分算子法
经典的边缘提取方法是考察图像的每个像素的某个邻域内灰度的变化,利用边缘邻近一阶或二阶方向导数变化规律,用简单的方法检测边缘,称为微分算子法。
导数算子具有突出灰度变化的作用,对图像运用导数算子,灰度变化较大的点处算得的值较高,因此我们将图像的导数算子运算值作为相应的边界强度,所以可以通过对这些导数值设置阈值,提取边界的点集。
一阶导数是最简单的导数算子。已知在点f(x,y)处,梯度grad(F(x,y))的幅度为:
它们分别求出了灰度在x和y方向上的变化率,但是要对每一个像素进行以上的运算,运算量较大,所以在实际应用中常用小区域模板卷积运算来进行近似计算。模板运算的想法是将赋予某一个像素的值作为它本身灰度值和相邻象素灰度值的函数。运用中,对x,y方向各用一个模板。
2.1.1 Sobel算子
Sobel算子是滤波算子的形式来提取边缘。X,Y方向各用一个模板,两个模板组合起来构成1个梯度算子。X方向模板对垂直边缘影响最大,Y方向模板对水平边缘影响最大。
图1 Sobel算子模板
2.1.2 robert算子
Robert算子是一种梯度算子,它用交叉的差分表示梯度,是一种利用局部差分算子寻找边缘的算子,对具有陡峭的低噪声的图像效果最好:
模板如图:
图2 Robert算子模板
2.1.3 prewitt算子
prewitt算子是加权平均算子,对噪声有抑制作用,但是像素平均相当于对图像进行地同滤波,所以prewitt算子对边缘的定位不如robert算子。模板如图;
图3 prewitt算子模板
代码如下:
原始图像为三位编织复合材料二维截面图,对原始图像进行前期处理
i=imread('d1.jpg');
i2=im2double(i);
ihd=rgb2gray(i2);
[thr,sorh,keepapp]=ddencmp('den','wv',ihd);
ixc=wdencmp('gbl',ihd,'sym4',2,thr,sorh,keepapp);
figure,imshow(ixc),title('消噪后图像 ');
k2=medfilt2(ixc,[7 7]);
figure,imshow(k2),title('中值滤波');
isuo=imresize(k2,0.25,'bicubic');
%sobert、robert和prewitt算子检测图像边缘
esobel=edge(isuo,'sobel');
erob=edge(isuo,'roberts');
eprew=edge(isuo,'prewitt');
subplot(2,2,1);
imshow(isuo);title('前期处理图像');
subplot(2,2,2);
imshow(esobel);title('sobel算子提取');
subplot(2,2,3);
imshow(erob);title('roberts算子提取');
subplot(2,2,4);
imshow(eprew);title('prewitt算子提取');
图4 微分算子边缘检测结果
2.2 Laplacian算子
拉普拉斯高斯算子是一种二阶导数算子,将在边缘处产生一个陡峭的零交叉。前面介绍的几种梯度法具有方向性,不能对各种走向的边缘都具有相同的增强效果。但是Laplacian算子是各向同性的,能对任何走向的界线和线条进行锐化,无方向性。这是拉普拉斯算子区别于其他算法的最大优点。
对一个连续函数,它在位置的拉普拉斯算子定义如下:
在图像边缘检测中,为了运算方便,函数的拉普拉斯高斯算子也是借助模板来实现的。其模板有一个基本要求:模板中心的系数为正,其余相邻系数为负,所有系数的和应该为零。
图5 Laplacian算子模板
2.3 Canny边缘检测法
Canny边缘检测是一种比较新的边缘检测算子,具有很好的边缘监测性能,在图像处理中得到了越来越广泛的应用。它依据图像边缘检测最优准则设计canny边缘检测算法:
(1) 首先用2D高斯滤波模板进行卷积以消除噪声
(2) 利用导数算子找到图像灰度地沿着两个方向的偏导数,并求出梯度的大小:
(3) 利用(2)的结果计算出梯度的方向
(4) 一旦知道了边缘的方向,就可以把边缘的梯度方向大致分为四种:水平、竖直、45度方向、135度方向。通过梯度的方向,就可以找到这个像素梯度方向的邻接像素。
(5) 遍历图像,若某个像素的灰度值与其梯度方向上前后两个像素的灰度值相比不是最大的,那么这个像素值置为0,即不是边缘。
(6) 使用累计直方图计算两个阈值,大于高阈值的一定是边缘,小于低阈值的一定不是边缘,介于之间的,看这个像素的邻接像素中有没有超过高阈值的边缘像素,如果有的话那么它
就是边缘了,否则它就不是边缘。
调用Laplacian算子、canny算子检测法检测图像边缘的程序如下:
elog=edge(isuo,'log');
ecanny=edge(isuo,'canny');
subplot(1,2,1);
imshow(elog);title('log算子提取');
subplot(1,2,2);
imshow(ecanny);title('canny算子提取');
图6 canny算子、Laplacian算子检测结果
3.边缘检测结果比较
Roberts算子检测方法对具有陡峭的低噪声的图像处理效果较好,但是利用roberts算子提取边缘的结果是边缘比较粗,因此边缘的定位不是很准确。
Sobel算子检测方法对灰度渐变和噪声较多的图像处理效果较好,sobel算子对边缘定位不是很准确,图像的边缘不止一个像素。
Prewitt算子检测方法对灰度渐变和噪声较多的图像处理效果较好。但边缘较宽,而且间断点多。
Laplacian算子法对噪声比较敏感,所以很少用该算子检测边缘,而是用来判断边缘像素视为与图像的明区还是暗区。
Canny方法不容易受噪声干扰,能够检测到真正的弱边缘。优点在于,使用两种不同的阈值分别检测强边缘和弱边缘,并且当弱边缘和强边缘相连时,才将弱边缘包含在输出图像中。
参考文献
[1] 赵春晖.现代图像处理技术及Matlab实现[M].北京:人民邮电出版社,2001.
[2] 阮秋琦.数字图像处理学[M].北京:电子工业出版社,2001.
[3] 何斌.数字图像处理[M].北京:人民邮电出版社,2001
I=imread('lena.bmp');% 提取图像
BW1=edge(I,'sobel'); %用SOBEL算子进行边缘检测
BW2=edge(I,'roberts');%用Roberts算子进行边缘检测
BW3=edge(I,'prewitt'); %用prewitt算子进行边缘检测
BW4=edge(I,'log'); %用log算子进行边缘检测
BW5=edge(I,'canny'); %用canny算子进行边缘检测
h=fspecial('gaussian’,5);
BW6=edge(I,’canny’);
subplot(2,3,1), imshow(BW1);
title(‘sobel edge check’);
subplot(2,3,2), imshow(BW2);
title(‘sobel edge check’);
subplot(2,3,3), imshow(BW3);
title(‘prewitt edge check’);
subplot(2,3,4), imshow(BW4);
title(‘log edge check’);
subplot(2,3,5), imshow(BW5);
title(‘canny edge check’);
subplot(2,3,6), imshow(BW6);
title(‘gasussian&canny edge check’);%此为用高斯滤波后Canny算子边缘检测结果
(注意:代码中有一些标点是中文模式,若输入代码后标点显示红色,则为中文标点,改回来就行了)
绛旓細[x,y]=find(Img==1); %img鏄綘鐨浜屽煎浘 涓嶈繃鐪嬩綘鐨勯棶棰樹綘鍦ㄦ妸闂鎼炲鏉...瀵逛簬浜屽煎浘锛屼綘鍏跺疄鏍规湰涓嶉渶瑕佸彇鍧愭爣灏卞彲浠ュ仛浠讳綍鎿嶄綔浜嗐傚鏋滄病鏄庣櫧鐨勮瘽浣犲彲浠ュ憡璇夋垜浣犺鍋氫粈涔堬紝鎴戠粰浣犱妇渚嬪瓙銆
绛旓細浣犵殑break鍙槸璺冲嚭浜嗗唴寰幆锛坖锛夛紝娌℃湁璺冲嚭澶栧惊鐜紙i锛夌▼搴忓叾瀹炲彲浠ョ畝鍗曚竴鐐 [row,col] = find(S==1, 1, 'first')
绛旓細缁欎竴涓悎閫傝鏁 澶х害鏄95 鐨勬牱瀛 鐒跺悗鍙︾煩闃电殑 95:end 琛 = 榛戣壊 (澶ф鏄0)
绛旓細鍩烘湰鎬濊矾灏辨槸锛氬钩鍧嘡鍊=R鍒嗛噺鍥.*妯℃澘/妯℃澘鍏冲績鍖哄煙鐐规暟 clear all im=imread('鍘熷.tif');im_red=double(im(:,:,1));im0=imread('妯℃澘.tif');im0=double(im0/max(im0(:)));meanRed=im_red(:).*im0(:)/sum(im0(:));
绛旓細灏卞皢涓ょ鏂规硶锛1銆 鏍规嵁榛勮壊鍦╮gb鍚勪釜鍒嗛噺鐨勫垎甯冭寖鍥寸洿鎺ユ彁鍙栵紝鍐嶅悎骞躲備絾鍙兘浼氬姞鍏ヤ笉闇瑕佺殑閮ㄥ垎銆2. 瀹炵幇閲囨牱锛屽埄鐢ㄩ鑹叉ā鍨嬶紙鍙弬鑰冪畝鏄撻珮鏂ā鍨嬶級锛岃嚜鍔ㄩ夊彇
绛旓細鍋囪浜屽煎浘鍍涓篜 [row col] = find(P);姣忓瀵瑰簲鐨剅ow鍜宑ol浠h〃鍊间负1鐨勫悇涓偣鍧愭爣 濡傛灉鎻愬彇琛屾暟鏈灏忕殑锛屽垯锛歔m, index] = min(row);row = m;col = col(index);杩欐牱(row, col)浠h〃x鏈灏忕殑鍍忕礌鍧愭爣 鏈涢噰绾筹紝璋㈣阿锛
绛旓細浜屽煎浘鍍涓嶆槸0锛屽氨鏄1锛屼竴鑸敤閫昏緫鐭╅樀琛ㄧず 浣犳湁鏉ヨ嚜浜庡悓涓寮犲浘鐗囩殑涓ゅ紶浜屽煎浘鐗 搴旇灏辨槸鐢ㄤ袱涓ぇ灏忎竴鏍风殑閫昏緫鐭╅樀 浜屽煎浘鐗囦腑鐧借壊鐨勯儴鍒嗕竴鏀瑰氨鏄昏緫1鐨勯儴鍒 姹備袱涓簩鍊煎浘鍍忓叕鍏辩櫧鑹查儴鍒嗙敤閫昏緫涓庡氨鍙互浜 鍔犲叆鍘熸潵鐨勪袱涓簩鍊煎浘鐗囨槸a鍜宐 閭d箞c=a&b 寰楀埌鐨刢涔熸槸涓涓昏緫鐭╅樀锛屽叾涓负1鐨勯儴鍒...
绛旓細鏄兂鍘婚櫎鍣0鎶婏紝鍦鍥惧儚杩樻槸鐏板害鍥剧殑鏃跺欏姞涓腑鍊兼护娉
绛旓細clear all;clc;str='picturename';%杩欎釜鍦版柟鏀规垚浣犵殑鍥剧墖鐨勫悕绉拌寰楀姞涓婅矾寰 img=imread([str,'.jpg']);%璇鍥惧儚 img=rgb2gray(img)%鍙樻垚鐏板害鍥惧儚 level = graythresh(img);bw=im2bw(img,level);%鍙樻垚浜屽璇 [row col]=size(bw);瀹屾垚浜屽煎寲 涓嬮潰鏄鎵惧埌鍒嗗壊鐨勫潗鏍 娉ㄦ剰鏄湪img 涓婅繘琛屽垎鍓...
绛旓細[m,n]=size(im);%鍘熷浘鍍忕殑澶у皬 for i=1:m;for j=1:n;if binarymap(i,j) ==1%binarymap鏄綘鐨浜屽煎浘鍍 im(i,j,1)=255;i m(i,j,2)=255;im(i,j,3)=255;end end end figure imshow(im);