我只从拍摄的图像(RGBImg_Raw)中分割了一个瓶子。接下来,我想检测这个小洞。但是,我无法继续下去。
我尝试使用this post中 jucestain 建议的filt_img = imfilter(img, fspecial('log',31,5));
。但这似乎也不起作用。我得到一张完全黑的图像。
我也试过用不同的阈值检测Canny和Sobel图像边缘,但是它很吵。
I2 = adapthisteq(GrayImg);
BW1 = edge(I2,'canny',0.05);
BW1 = edge(I2,'sobel',0.1);
我期望在针孔周围绕圈,所以我可以找到连接的组件并检测到那个洞。
有什么建议吗?
我正在使用MATLAB。附件在Dropbox。
答案 0 :(得分:4)
您可以尝试使用基于简单分段步骤的代码:
clc
clear all
close all
im1 = imread('bottle.png');
gray1 = (rgb2gray(im1));
gray1 = imfilter(gray1,fspecial('gaussian',[5,5],1.5),'replicate');
figure,imshow(im1,[])
[~,~,mg,~] = ImageFeatures.Gradients(gray1); % Sobel is used here.
mgBw = im2bw(mg,graythresh(mg));
rg = regionprops(mgBw,'Area','PixelIdxList');
minAreaObj = false(size(mgBw));
for i = 1:length(rg)
area = rg(i).Area;
idx = rg(i).PixelIdxList;
if area<1000
minAreaObj(idx) = true;
end
end
minAreaObj = imopen(minAreaObj,strel('disk',3));
以下是算法的结果:
渐变代码:
function [gx,gy,mag,phi] = Gradients(gray)
gray = double(gray);
horzmask = fspecial('sobel');
% vertmask = horzmask';
gx = imfilter(gray,horzmask,'replicate');
gy = imfilter(gray,horzmask','replicate');
phi = (atan2((gy),(gx)));
mag = mat2gray(sqrt(gx.^2+gy.^2));
end
答案 1 :(得分:3)
此处使用FEX中的fast 2d peak finder:
% this part reads the image and gets rid of the white frame around it
d=imread('http://i.stack.imgur.com/MSQLZ.png');
d=rgb2gray(d);
d(d==255)=0;
% now peak finding with threshold as 0.8*max image intensity
p=FastPeakFind(d,max(d(:))*0.8);
figure;
imagesc(d); hold on
plot(p(1:2:end),p(2:2:end),'rx')
% the peak is found at
p =
735
355
编辑:
对于另一幅图像,平坦阈值不合适。为了使它工作,你需要应用一个局部阈值,或做一些所谓的“共模校正&#34;你的形象。一些相机产生的成像数据不应直接用于分析并需要更正。最受欢迎的修正是:暗率(基座)减法,坏像素屏蔽,共模校正,增益校正等。如果没有太多细节(您可以搜索更多关于上述信息的信息),您可以执行以下操作&#34 ;计算&#34;技巧,取你想要分析的图像的局部均值:
d=GrayImg;
% Read comments in the FEX of the 2d fast peak find, is all there
ws=100; % window size
mean_d=imfilter(d,fspecial('average',ws),'replicate'); % this a local mean operation
dd=d-mean_d;
filt = (fspecial('gaussian', 7,1));
p=FastPeakFind(dd,40,filt,600 );
imagesc(dd); hold on
plot(p(1:2:end),p(2:2:end),'wx');
所以我将edg设为600,因为我很懒。最好的办法是将上面的内容应用到图像的感兴趣区域,这样您就可以避免圆柱体的边缘给出错误的峰值。
答案 2 :(得分:1)
在一个没有附加功能但基于图像处理工具箱的解决方案下面
clear all
close all
rawimage = imread('MSQLZ.png');
sumimage = sum(rawimage,3);
bwlabelim = bwlabel(sumimage,8);
shapedata = regionprops ( bwlabelim,'all');
the_bottle = find([shapedata.MajorAxisLength] == min(shapedata.MajorAxisLength));
only_bottle = zeros(size(bwlabelim));
only_bottle(bwlabelim==the_bottle)= 1;
sumimage(~only_bottle)=0;
[y,x] = ind2sub(size(sumimage),find(sumimage==(max(max(sumimage)))));
contourf(sumimage,'LineColor','none')
hold on
plot(x,y,'ro')
它将RGB值相加并创建了一个bwimage。从这一个我提取区域属性,并搜索具有最小直径的属性,因为这是你的瓶子。我创建了一个逻辑图像来从您的图像中过滤掉只留下瓶子值的帧。在此我搜索最大值并提取坐标。
答案 3 :(得分:-1)
"/var/log/dpkg.log"