MATLAB实现静态图像分割

原文:https://blog.csdn.net/jiji_vip/article/details/72487804 

MATLAB实现静态图像分割
待处理图像是一张药板图,我们的处理目标有以下几个: 
1. 将药板从黑色背景中分离(药板部分显示为白色,背景显示为黑色); 
2. 根据分割结果将药板旋转至水平; 
3. 提取药板中的药丸的信息; 

å¾å¤çç§ç
首先将药板从黑色背景中分离出来,用otsu对图像进行分割,很简单,代码是王道。

clc;clear all;  
H=imread('C:\Users\Administrator\Desktop\1\1.tiff');       
I=rgb2gray(H);  
T=graythresh(I);    %采用Otsu方法计算最优阈值T对图像二值化;  
Ibw1 = im2bw(I,T);
figure, imshow(Ibw1);title('Otsu-图1');


只贴一个 结果: 

è¿æ¯å¾
 
接着将孔洞填充:

clear,clc,close all;
I=imread('C:\Users\Administrator\Desktop\1\1.tiff');
bw=rgb2gray(I);
bw=im2bw(I,graythresh(bw));%采用Otsu方法
BW1 = imfill(bw, 'holes');%孔洞填充
figure;imshow(BW1);title('分离出的药板')


æ¯ä¸æ¯å¾çº¯æ´äº
将药板旋转至水平 
将药板二值化之后,取出边缘,Hough变换求出线段斜率,得到角度,然后通过imrotate()函数进行自动旋转。这一步重点在于标出直线,求得斜率。 
霍夫变换传送门
废话不多说,代码:

clear,clc,close all;
I=imread('C:\Users\Administrator\Desktop\1\1.tiff');
bw=rgb2gray(I);
bw=im2bw(I,graythresh(bw));%采用Otsu方法
bw=double(bw);
BW=edge(bw,'canny');
%霍夫变换
[H,T,R]=hough(BW);
P=houghpeaks(H,4,'threshold',ceil(0.3*max(H(:))));
lines=houghlines(BW,T,R,P,'FillGap',50,'MinLength',7);
max_len = 0;
%figure,imshow(BW),title('直线标识产物');
%hold on;
for k=1:length(lines)
xy=[lines(k).point1;lines(k).point2];
%plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% 标出线段的起始和终端点
%plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
%plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
    len=norm(lines(k).point1-lines(k).point2);
    Len(k)=len;
    if (len>max_len)
        max_len=len;
        xy_long=xy;
    end
end
[L1 Index1]=max(Len(:));
% 求得最长线段的斜率
K1=-(lines(Index1).point1(2)-lines(Index1).point2(2))/...
    (lines(Index1).point1(1)-lines(Index1).point2(1))
angle=atan(K1)*180/pi
A = imrotate(I,-angle,'bilinear','crop');% imrorate 是逆时针的所以取负
figure; imshow(A);title('旋转后的药板')


现在老规矩就是贴上结果: 
 
 è¿æ¯æåçè¾¹ç¼
 æ转正çå¾ç

æ转çè§åº¦8.9726
当然你可以用眼睛看着调,除了有点low之外。。

提取药板中药丸的位置信息 
简单点说就是把药丸框起来。用到regionprops函数
%在二值图中确定出标记位置信息

B=rgb2gray(A);
B=im2bw(A,graythresh(A));
L = bwlabel(~B);
stats = regionprops(L, 'BoundingBox');
%在旋转后的图像中标记
figure; imshow(A);title('旋转后的药板(标记药丸位置)')
hold on;
for i = 1 : length(stats)
    if stats(i).BoundingBox(1)>10
    rectangle('Position', stats(i).BoundingBox, 'edgecolor', 'r','LineWidth',3);
    end
end


运行结果: 
 æ è®°è¯ä¸¸
可能有人说了,你咋标成这个样子??这我也不想啊,otsu分割完只能弄成这样。基于颜色特征的区域分割 
“早干嘛去了,一开始就应该用这个东西。。”我不服啊,什么东西刚开始弄就很十全十美。代码有个重构的过程,人类更有个从猿人进化到智人的阶段。 
首先看张图: 
 
你有什么发现?是不是感觉两个图就像一个夫妻,一阴一阳,一上一下。没错,这是原始图片分别在y颜色空间和cb颜色空间图像。

ycbcr=rgb2ycbcr(A);
y=ycbcr(:,:,1);
cb=ycbcr(:,:,2);
cr=ycbcr(:,:,3);

thr_y=graythresh(y);
bw_y=im2bw(y,thr_y);

thr_cb=graythresh(cb);
bw_cb=im2bw(cb, thr_cb);


将两个颜色空间的图像取反,相加,即B=~bw_y+~bw_cb,结果如下: 
 
剩下的我想你们也知道该怎么办——做一下形态学运算,再框起来 
结果: 
 
附代码,亲测

clear,clc,close all;
I=imread('C:\Users\Administrator\Desktop\1\1.tiff');
bw=rgb2gray(I);
bw=im2bw(I,graythresh(bw));%采用Otsu
%将药板从黑色背景中分离
BW1 = imfill(bw, 'holes');
figure;imshow(BW1);title('分离出的药板')

bw=double(bw);
BW=edge(bw,'canny');
%哈佛变换
[H,T,R]=hough(BW);%H是霍夫变换矩阵,T、R是p和θ值向量,在这些值上产生霍夫变换BW是二值图像
P=houghpeaks(H,4,'threshold',ceil(0.3*max(H(:))));
lines=houghlines(BW,T,R,P,'FillGap',50,'MinLength',7);%%lines为结构数组,长度等于找到的线段数
max_len = 0;
for k=1:length(lines)
    xy=[lines(k).point1;lines(k).point2];
    len=norm(lines(k).point1-lines(k).point2);
    Len(k)=len;
    if (len>max_len)
        max_len=len;
        xy_long=xy;
    end
end
[L1 Index1]=max(Len(:));
% 求得线段的斜率
K1=-(lines(Index1).point1(2)-lines(Index1).point2(2))/...
    (lines(Index1).point1(1)-lines(Index1).point2(1))
angle=atan(K1)*180/pi
A = imrotate(I,-angle,'bilinear','crop');% imrate 是逆时针的所以取负

%颜色特征的区域分割
ycbcr=rgb2ycbcr(A);
y=ycbcr(:,:,1);
cb=ycbcr(:,:,2);
cr=ycbcr(:,:,3);

thr_y=graythresh(y);
bw_y=im2bw(y,thr_y);

thr_cb=graythresh(cb);
bw_cb=im2bw(cb, thr_cb);

B=~(~bw_y+~bw_cb);

se=strel('disk',5);
B=imclose(B,se);
B=imopen(B,se);

%确定出标记位置
L = bwlabel(~B);
stats = regionprops(L, 'BoundingBox');
%在旋转后的图像中标记

figure; imshow(A);title('旋转后的药板1(标记药丸位置)')
hold on;
for i = 1 : length(stats)
    if stats(i).BoundingBox(1)>10
    rectangle('Position', stats(i).BoundingBox, 'edgecolor', 'r','LineWidth',3);
    end
end
发布了13 篇原创文章 · 获赞 34 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/xia0_ba1/article/details/83713721