MATLAB 局部图像处理

我想将下图中的四个圆内的部分进行中值滤波,圆外的部分不要了。就是说,想用圆框框出那四个圆,只处理圆内区域的图像,怎么把那部分圈出来?程序怎么写?圆边框线用红色,然后后序处理程序都只在圆框内进行。

I=imread('E:\QQ截图(百度知道)\8c1001e9ba102363b80e2d09.jpg');

I1=rgb2gray(I);

I2=im2bw(I1);%%转化成二值图像

%figure,imshow(I2);

se=strel('square',3);

I2_1=imopen(I2,se);%%用开运算去掉很小的毛刺

se1=strel('disk',11);

I2_2=imclose(I2_1,se1);%%闭运算进行小区域填充

Image=zeros(size(I1));

[m,n]=size(I1);

for i=1:m

    for j=1:n

        if I2_2(i,j)==1

            Image(i,j)=I1(i,j);%%根据最后的二值图像对原图像进行筛选,保留四个圆区域,其余部分去掉

        end

    end

end

figure,imshow(uint8(Image))

%%%%%%%%%%%%%%%%%%%%

这样后,可以直接对Image进行中值滤波,即可达到对四个圆区域的中值滤波。

要对区域进行标记的话,参考regionprops函数中的'ConvexHull'属性,最小外接凸多边形。

追问

挺好的。不过还想问一下你会多边形提取吗?因为边缘对后面程序 的影响太大,所以我想把现有的圆半径缩小,去掉影响太大的边缘,可以写下程序 吗?我给你追加50分。

追答

I=imread('E:\QQ截图(百度知道)\8c1001e9ba102363b80e2d09.jpg');
I1=rgb2gray(I);
I11=imresize(I1,0.4);%%把图像缩小了0.4倍,这样检测出来的边缘是连续的,容易标记
I2=im2bw(I11);%%转化成二值图像
%figure,imshow(I2);
se=strel('square',3);
I2_1=imopen(I2,se);%%用开运算去掉很小的毛刺
se1=strel('disk',8);
I2_2=imclose(I2_1,se1);%%闭运算进行小区域填充
I3=edge(double(I2_2),'canny');
%figure,imshow(I3);
[L, num] = bwlabel(I3);
[xx1,yy1]=find(L==2);
x1=sum(xx1)/length(xx1);y1=sum(yy1)/length(yy1);
[xx2,yy2]=find(L==3);
x2=sum(xx2)/length(xx2);y2=sum(yy2)/length(yy2);
[xx3,yy3]=find(L==4);
x3=sum(xx3)/length(xx3);y3=sum(yy3)/length(yy3);
[xx4,yy4]=find(L==5);
x4=sum(xx4)/length(xx4);y4=sum(yy4)/length(yy4);%%对四个圆区域求取其重心,也就是圆心
[m,n]=size(I1);
I4=zeros(m,n);
for i=1:m
for j=1:n
if (i-107.97*2.5)^2+(j-127.57*2.5)^2<=55000%%乘以2.5,是转化到原坐标系下,107.97是缩小0.4倍后的图像的坐标,x1=107.97,y1=127.57,我直接写进去了
I4(i,j)=I1(i,j);
elseif (i-391.72*2.5)^2+(j-125.32*2.5)^2<=55000%%x2=391.72,y2=125.32
I4(i,j)=I1(i,j);
elseif (i-106.05*2.5)^2+(j-383.1*2.5)^2<=55000%%x3=106.05,y3=383.1
I4(i,j)=I1(i,j);
elseif (i-384.57*2.5)^2+(j-395.87*2.5)^2<=55000%%%适当控制半径大小,即可取到很平滑的边缘,半径大小是我试的,楼主要是觉得不合适,可以自己调;x4=384.57,y4=395.87
I4(i,j)=I1(i,j);
end
end
end
figure,imshow(uint8(I4));

追问

后面出来的图我看了,不是这样的,只能是要么四个圆的半径一起缩小,要一致,不能选择性的去掉影响大的部分,因为我后面是要用二值化提取的起球部分的面积/总面积,得出我要的比例,你这样的话,如果我换张图片,很可能对比不公平,那样就不是误差而是错误了,不知道你明不明白。所以我要的是半径减小,不是直接去掉一部分。

追答

根据他们的重心,设定半径,四个圆就是一样大小的。楼主的意思是四个区域的缩小,这样操作比较麻烦,涉及压缩,采样等方面。楼主可以将Image缩小,检测边缘,得到连续的边缘后,进行后续的操作,最终结果乘以相应的倍数即可!

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-05-23
很简单的, 因为你的图中的圆不是标准的规范的圆, 用圆的方程之类的方法话边框反而不好, 直接遍历图像中所有像素, 如果相邻像素的像素值相差超过了一定的阈值(自己试一下, 我感觉至少有50以上), 就把这个点标记成红色. 以后处理的时候判断一下当前经过的红色点的个数, 偶数个肯定是圆框外的部分, 奇数个就在圆框内的部分.
比如说我现在遍历到了图像的第二行, 一开始我没有遇到红色点, 红色像素点个数累积为0. 这时就不用做图像处理, 等到遇到了第一个红色像素, 这时我们就进入了图中第一个圆的区域中, 然后开始做处理, 下次遇到红色点就表示离开了圆形区域. 后面的同样道理追问

不光要思路,最重要程序?我之后还要对圆内的像素求面积

追答

你图像里的圆都不是标准的圆, 想要怎么样求面积? 求近似面积?
for(int i = 0; i = 50) //这里自己试验一下阈值大小
pixel[i*image.cols+j] = 红色;
}
}

for(int i = 0; i < image.rows i++)
{
int numberOfRedPoint = 0;
for(int j = 0; j <image.cols; j++)
{
if(pixel[i*image.cols+j] == 红色)
numberOfRedPoint++;
if(numberOfRedPoint % 2 == 1)
{
//做中值滤波处理, 这个代码不用我再写了吧
}
}
}

用c语言简单的写一下思路

追问

我C很烂,MATLAB也是因为毕设才学的,也很烂,你写的这么委婉,我当然不懂,你能写成MATLAB的吗?最好是我直接添加进我现有的程序里。我上一个处理完的图像变量名为bg1。是边缘处理的,能看见我要处理的四个圆的轮廓。

第2个回答  2011-05-24

把1楼的程序用2次,就实现了2次子区域滤波。

a=imread('待分割滤波处理图片.图片格式');
gaussianFilter=fspecial('gaussian',[7,7],5); %设置滤波器

%读出a中待滤波区域1: 10:100,20:120分别为y,x的区间,
b=a(10:100,20:120);
c=imfilter(b,gaussianFilter,'symmetric','conv')%滤波
a(10:100,20:120)=c; %读回

%读出a中待滤波区域2:10:100,120:220分别为y,x的区间,
b=a(10:100,120:220);
c=imfilter(b,gaussianFilter,'symmetric','conv'); %滤波
a(10:100,120:220)=c; %读回

%二值化,假设阈值为150

d=find(I<150);
I(d)=0;
d=find(I>=150);
I(d)=255;追问

这是你自己的还是COPY别人的?我见过这个,还是不会用……没出来我要的效果,你会改吗?

第3个回答  2011-05-23
可以直接处理呀,不用管周围,因为黑色都是灰度为零的啊,对整幅图像中值滤波,在用edge函数取边,对边缘的红色分量增加到最大,其余绿色和蓝色分量将为零(灰度图像不用分),在画出整幅图就ok啦,以后处理的时候也不会对其他位置的像素值有太大影响。追问

不要光给我思路,程序怎么写?

相似回答