【问题标题】:Grid detection in matlabmatlab中的网格检测
【发布时间】:2013-05-04 18:58:00
【问题描述】:

我在二进制图像中有一个网格(可能会旋转)。如何使用 MATLAB 知道该网格的近似公式?

示例图片:


(来源:sjtu.edu.cn

有时这些黑点会丢失,所以我需要公式或“一种方法”来估计这些黑点的可能中心。

我尝试过使用regionprops,它可以帮助我找到这些现有黑点的中心,但不知道黑点是否缺失

clear all
im = imread('print5.jpg');
im = im2bw(im);
[sy,sx] = size(im);
im = imcomplement(im);
im(150:200,100:150) = 0; % let some dots missing!
im = imclearborder(im);
st = regionprops(im, 'Centroid');

imshow(im) hold on;
for j = 1:numel(st)
    px = round(st(j).Centroid(1,1));
    py = round(st(j).Centroid(1,2));
    plot(px,py,'b+')
end

【问题讨论】:

  • 试试看广告频率内容:fft2 网格很规则,你应该可以在频域中发现峰值。
  • 如果您将上述 cmets 中的所有信息编辑到您的问题中,您应该能够重新打开它。
  • 哇,这在短时间内吸引了很多反对票。我明白为什么它被关闭了,但它真的值得 -20 票否决...
  • @Amro 如果您查看首页,您会发现问题在一个多小时内没有更新,这可能就是他们这样做的原因。无论如何,通常会从“最新问题”部分中删除带有-3/-4 否决票的问题,以停止进一步的否决我相信,但由于这个故障,这个问​​题仍在显示:/
  • 我从 cmets 添加了 OP 的代码和描述。这应该会减慢盲目投票的人。那些做过的人,请重新考虑..

标签: matlab image-processing


【解决方案1】:

这是一种在 x 和 y 投影上在一维中使用 fft 的方法:

首先,我将通过与高斯卷积对图像进行一些模糊处理以平滑高频噪声:

m=double(imread('print5.jpg'));
m=abs(m-max(m(:))); % optional line if you want to look on the black square as "signal"
H=fspecial('gaussian',7,1);
m2=conv2(m,H,'same');

然后我将获取每个轴的投影的 fft:

delta=1;
N=size(m,1);
df=1/(N*delta);        % the frequency resolution (df=1/max_T)
f_vector= df*((1:N)-1-N/2);     % frequency vector 

freq_vec=f_vector;
fft_vecx=fftshift(fft(sum(m2)));
fft_vecy=fftshift(fft(sum(m2')));
plot(freq_vec,abs(fft_vecx),freq_vec,abs(fft_vecy))

所以我们可以看到两个轴在 0.07422 处产生一个峰值,这转换为 1/0.07422 像素或 ~ 13.5 像素的周期。

获取角度信息的更好方法是使用 2D,即:

ml= log( abs( fftshift (fft2(m2)))+1);
imagesc(ml) 
colormap(bone)

然后根据需要应用简单几何或区域道具等工具,您可以获得正方形的角度和大小。正方形的大小是背景上大旋转正方形的大小的 1/ (有点模糊,因为我模糊了图像,所以尽量不这样做),角度是atan(y/x)。正方形之间的距离是1/中心部分的强峰到图像中心的距离。

因此,如果您正确设置ml 的阈值,则说明

 imagesc(ml>11)

您可以为此访问中心峰...

另一种方法将是对二值图像进行形态学运算,例如我对模糊图像进行阈值化并将对象缩小为点。它去除像素,使没有孔的物体缩小到一个点:

BW=m2>100;
BW2 = bwmorph(BW,'shrink',Inf);
figure, imshow(BW2)

那么您实际上每个点阵站点网格都有一个像素!这样您就可以将其提供给 Amro 的解决方案 使用霍夫变换,或者用fft分析,或者拟合一个块等等……

【讨论】:

    【解决方案2】:

    您可以应用Hough transform 来检测网格线。一旦我们有了这些,您就可以推断出网格位置和旋转角度:

    %# load image, and process it
    img = imread('print5.jpg');
    img = imfilter(img, fspecial('gaussian',7,1));
    BW = imcomplement(im2bw(img));
    BW = imclearborder(BW);
    BW(150:200,100:150) = 0;    %# simulate a missing chunk!
    
    %# detect dots centers
    st = regionprops(BW, 'Centroid');
    c = vertcat(st.Centroid);
    
    %# hough transform, detect peaks, then get lines segments
    [H,T,R] = hough(BW);
    P  = houghpeaks(H, 25);
    L = houghlines(BW, T, R, P);
    
    %# show image with overlayed connected components, their centers + detected lines
    I = imoverlay(img, BW, [0.9 0.1 0.1]);
    imshow(I, 'InitialMag',200, 'Border','tight'), hold on
    line(c(:,1), c(:,2), 'LineStyle','none', 'Marker','+', 'Color','b')
    for k = 1:length(L)
        xy = [L(k).point1; L(k).point2];
        plot(xy(:,1), xy(:,2), 'g-', 'LineWidth',2);
    end
    hold off
    

    (我正在使用来自 File Exchange 的 imoverlay 函数)

    结果:

    这是累加器矩阵,其中与检测到的线对应的峰值突出显示:


    现在我们可以通过计算检测到的线的平均斜率来恢复旋转角度,过滤到两个方向之一(水平或垂直):

    %# filter lines to extract almost vertical ones
    %# Note that theta range is (-90:89), angle = theta + 90
    LL = L( abs([L.theta]) < 30 );
    
    %# compute the mean slope of those lines
    slopes = vertcat(LL.point2) - vertcat(LL.point1);
    slopes = atan2(slopes(:,2),slopes(:,1));
    r = mean(slopes);
    
    %# transform image by applying the inverse of the rotation
    tform = maketform('affine', [cos(r) sin(r) 0; -sin(r) cos(r) 0; 0 0 1]);
    img_align = imtransform(img, fliptform(tform));
    imshow(img_align)
    

    这是旋转回来的图像,以便网格与 xy 轴对齐:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 2014-06-14
      • 2016-10-04
      • 1970-01-01
      • 2016-01-22
      相关资源
      最近更新 更多