检测圆柱表面上的小针孔

时间:2015-10-27 05:17:06

标签: algorithm matlab image-processing

我只从拍摄的图像(RGBImg_Raw)中分割了一个瓶子。接下来,我想检测这个小洞。但是,我无法继续下去。

enter image description here

我尝试使用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

4 个答案:

答案 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));

以下是算法的结果:

enter image description here

enter image description here

渐变代码:

  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

enter image description here

编辑:

对于另一幅图像,平坦阈值不合适。为了使它工作,你需要应用一个局部阈值,或做一些所谓的“共模校正&#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');

enter image description here

所以我将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"