折腾了好久,还是没折腾出来,不过还是有点点进步,看看这么一张图片,我是怎么实现对6个莲子的提取的。
还是把代码贴出来,分享给大家,也请大家给提点建议。
image=imread('E:\qw1.jpg'); %%%背景的质心 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 backgroud1=zeros(height, width);%创建背景(全0) backgroud1=~backgroud1;%背景取反,目的是求质心 bckg_zhixin=regionprops(backgroud1,'Centroid');%求背景的质心 backgroud1=~backgroud1;%背景取反,恢复黑色。 bckg_x=bckg_zhixin.Centroid(1);%背景质心X坐标 bckg_y=bckg_zhixin.Centroid(2);%背景质心y坐标 %%%处理图片,提取6个贝母的边缘 [H,S,V]=rgb2hsv(image);%step1:获取图片HSV分量,分别代表色调,饱和度,亮度 hMedian=median(median(H));%step2:提取中位数以下H分量,进行二值化 hBw1=im2bw(H,hMedian);%step3:二值化,阈值为hMedian HBelowMedian=H.*(~hBw1);%step4:剩余H二值化 hBw2=im2bw(HBelowMedian,graythresh(HBelowMedian));%二值化,阈值为graythresh(HBelowMedian) for i=1:size(image,1) bwImage(i,:)=bitxor(hBw1(i,:),hBw2(i,:));%%将hBw1和hBw2异或得到结果 end bwImage=~bwImage;%图像取反 [B0,L0] = bwboundaries(bwImage,'noholes');%边界跟踪,返回划分的区域L0,noholes算法只搜索目标的外边界。 stats = regionprops(L0,'Area');%regionprops测量每个标签区域L0的属性 [sortAfter,Index] = sort([stats(:,:).Area],'descend');%对数组进行降序排序,并返回排序后的数组,Index为返回的排序后元素在原数组中的行位置或列位置. %%%处理第一个贝母 LL1 = ismember(L0,Index(1));%判断一个集合是否为另一个的子集,此地方是。 bwImage1 = bwlabel(LL1);%进行标注 bwImage1 = imfill(bwImage1,'holes');%%对二值图像中的目标孔进行填充点 stats1=regionprops(bwImage1,'Centroid'); x1=stats1.Centroid(1)% 求的图像1质心的坐标 y1=stats1.Centroid(2)% 求的图像1质心的坐标 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 for i=1:height for j=1:width if bwImage1(i,j)==0 indimage(i,j)=0; end end end iimage1=ind2rgb(indimage,map);%将处理后的索引图像转换为真彩色图像 if x1>=bckg_x image1move_x=x1-bckg_x;%贝母移动x坐标 else image1move_x=bckg_x-x1;%贝母移动x坐标 end if y1>=bckg_y image1move_y=y1-bckg_y;%贝母移动y坐标 else image1move_y=bckg_y-y1;%贝母移动y坐标 end for i=1:height for j=1:width if iimage1(i,j)~=0 iimage1(fix(i-image1move_x),fix(j-image1move_y))=iimage1(i,j); end end end rect=[bckg_x-80 bckg_y-80 bckg_x+80 bckg_y+80]; showimage1=imcrop(iimage1,rect);% 用imcrop裁剪: figure; imshow(showimage1); imwrite(showimage1,'showimage1.bmp') title('1'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LL2 = ismember(L0,Index(2));%判断一个集合是否为另一个的子集,此地方是。 bwImage2 = bwlabel(LL2);%进行标注 bwImage2 = imfill(bwImage2,'holes');%%对二值图像中的目标孔进行填充点 stats2=regionprops(bwImage2,'Centroid'); x2=stats2.Centroid(1)% 求的图像2质心的坐标 y2=stats2.Centroid(2)% 求的图像2质心的坐标 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 for i=1:height for j=1:width if bwImage2(i,j)==0 indimage(i,j)=0; end end end iimage2=ind2rgb(indimage,map);%将处理后的索引图像转换为真彩色图像 % figure; % imshow(iimage2); % title('2'); rect=[x2-80 y2-80 x2+80 y2+80]; a2=imcrop(iimage2,rect);% 用imcrop裁剪: figure; imshow(a2); imwrite(a2,'a2.bmp') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LL3 = ismember(L0,Index(3));%判断一个集合是否为另一个的子集,此地方是。 bwImage3 = bwlabel(LL3);%进行标注 bwImage3 = imfill(bwImage3,'holes');%%对二值图像中的目标孔进行填充点 stats3=regionprops(bwImage3,'Centroid'); x3=stats3.Centroid(1)% 求的图像3质心的坐标 y3=stats3.Centroid(2)% 求的图像3质心的坐标 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 for i=1:height for j=1:width if bwImage3(i,j)==0 indimage(i,j)=0; end end end iimage3=ind2rgb(indimage,map);%将处理后的索引图像转换为真彩色图像 % figure; % imshow(iimage3); % title('3'); rect=[x3-80 y3-80 x3+80 y3+80]; a3=imcrop(iimage3,rect);% 用imcrop裁剪: figure; imshow(a3); imwrite(a3,'a3.bmp') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LL4 = ismember(L0,Index(4));%判断一个集合是否为另一个的子集,此地方是。 bwImage4 = bwlabel(LL4);%进行标注 bwImage4 = imfill(bwImage4,'holes');%%对二值图像中的目标孔进行填充点 stats4=regionprops(bwImage4,'Centroid'); x4=stats4.Centroid(1)% 求的图像4质心的坐标 y4=stats4.Centroid(2)% 求的图像4质心的坐标 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 for i=1:height for j=1:width if bwImage4(i,j)==0 indimage(i,j)=0; end end end iimage4=ind2rgb(indimage,map);%将处理后的索引图像转换为真彩色图像 % figure; % imshow(iimage4); % title('4'); rect=[x4-80 y4-80 x4+80 y4+80]; a4=imcrop(iimage4,rect);% 用imcrop裁剪: figure; imshow(a4); imwrite(a4,'a4.bmp') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LL5 = ismember(L0,Index(5));%判断一个集合是否为另一个的子集,此地方是。 bwImage5 = bwlabel(LL5);%进行标注 bwImage5 = imfill(bwImage5,'holes');%%对二值图像中的目标孔进行填充点 stats5=regionprops(bwImage5,'Centroid'); x5=stats5.Centroid(1)% 求的图像5质心的坐标 y5=stats5.Centroid(2)% 求的图像5质心的坐标 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 for i=1:height for j=1:width if bwImage5(i,j)==0 indimage(i,j)=0; end end end iimage5=ind2rgb(indimage,map);%将处理后的索引图像转换为真彩色图像 % figure; % imshow(iimage5); % title('5'); rect=[x5-80 y5-80 x5+80 y5+80]; a5=imcrop(iimage5,rect);% 用imcrop裁剪: figure; imshow(a5); imwrite(a5,'a5.bmp') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LL6 = ismember(L0,Index(6));%判断一个集合是否为另一个的子集,此地方是。 bwImage6 = bwlabel(LL6);%进行标注 bwImage6 = imfill(bwImage6,'holes');%%对二值图像中的目标孔进行填充点 stats6=regionprops(bwImage6,'Centroid'); x6=stats6.Centroid(1)% 求的图像6质心的坐标 y6=stats6.Centroid(2)% 求的图像6质心的坐标 indimage=rgb2ind(image,map);%将待处理图片转换为索引图像 [height,width]=size(indimage);%计算灰度索引图像的长宽 for i=1:height for j=1:width if bwImage6(i,j)==0 indimage(i,j)=0; end end end iimage6=ind2rgb(indimage,map);%将处理后的索引图像转换为真彩色图像 % figure; % imshow(iimage6); % title('6'); rect=[x6-50 y6-50 x6+50 y6+50]; a6=imcrop(iimage6,rect);% 用imcrop裁剪: figure; imshow(a6); imwrite(a6,'a5.bmp') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
做到现在这个情况,当然还没有实现想要的效果,但是基本的框架已经搭好了,现在的问题还有2个。1是平移,可以看见我们运行后的第一张图片,我是进行了平移处理的(即把莲子的质心移动到背景的中心点),也不知道哪里的原因,运行出来时那种情况。2是截取图像,我的想法是把平移好的莲子,通过imcorp函数实现,但是也存在一点点问题,老是截出来的图大小不一。请各位大虾帮帮忙啊。