Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用matlab检测图像中的多个符号实例_Matlab_Image Processing - Fatal编程技术网

如何用matlab检测图像中的多个符号实例

如何用matlab检测图像中的多个符号实例,matlab,image-processing,Matlab,Image Processing,我曾尝试使用中提供的代码,使用与FFT匹配的模板检测符号(通过fft2) 但是,该代码只检测一个符号,但不会检测所有相似的符号 代码已根据链接的帖子进行了修改,如下所示 template=im2bw(imread(http://www.clipartkid.com/images/543/floor-plan-symb-aT0MYg-clipart.png)); background=im2bw(imread(http://www.the-house-plans-guide.com/images

我曾尝试使用中提供的代码,使用与FFT匹配的模板检测符号(通过
fft2

但是,该代码只检测一个符号,但不会检测所有相似的符号

代码已根据链接的帖子进行了修改,如下所示

template=im2bw(imread(http://www.clipartkid.com/images/543/floor-plan-symb-aT0MYg-clipart.png)); 
background=im2bw(imread(http://www.the-house-plans-guide.com/images/blueprints/draw-floor-plan-step-6.png));

bx = size(background, 2); 
by = size(background, 1);
tx = size(template, 2); % used for bbox placement
ty = size(template, 1);
pos=[];
%// Change - Compute the cross power spectrum
Ga = fft2(background);
Gb = fft2(template, by, bx);
c = real(ifft2((Ga.*conj(Gb))./abs(Ga.*conj(Gb))));

%% find peak correlation
[max_c, imax]   = max(abs(c(:)));
[ypeak, xpeak] = find(c == max(c(:))); % Added to make code work
if ~isempty(ypeak) || ~isempty(xpeak)
 pos=position;

plot(xpeak,ypeak,'x','LineWidth',1,'Color','g');
rectangle('position',position,'edgecolor','b','linewidth',1, 'LineStyle', '-  ');
end

如何使用上述代码检测多个符号而不是一个符号?

Amitay的评估是正确的。顺便说一句,您获取的代码来自以下帖子:

该代码仅用于检测指定模板中的一个匹配项。如果您希望检测多个模板,可以尝试各种方法,每种方法各有优缺点:

  • 使用全局阈值,从交叉功率谱中,任何超过该阈值的值都认为存在匹配
  • 在交叉功率谱中找到最大的相似性,任何与该最大值相距一定距离的东西都将被视为存在匹配。也许一个百分比或者一个标准差就行了
  • 尝试制作交叉功率谱中唯一值的柱状图,并找到与模板明显不相关的值与相关值之间存在明显分离的点。我不会在这里为您实现这一点,因为它要求我们查看您的图像,然后通过检查直方图找到阈值,所以我不会为您这样做。相反,你可以尝试前两种情况,看看结果如何
  • 如果出现多个匹配项,则必须循环多个匹配项,因此需要循环绘制图像中矩形的代码


    案例1 第一种情况非常简单。您所要做的就是修改
    find
    语句,这样就不用搜索具有最大值的位置,只需查找超过阈值的位置即可

    因此:

    %% find peak correlation
    thresh = 0.1; % For example
    [ypeak, xpeak] = find(c >= thresh);
    
    案例2 这与第一种情况非常相似,但不是查找超过阈值的值,而是确定最大的相似性值(已完成),并对高于
    (1-x)的任何值设置阈值*max_val
    其中
    x
    是一个介于0和1之间的值,表示希望从最大值中减去的百分比被视为匹配。因此,如果您希望与最大值相差不超过5%,
    x=0.05
    ,因此阈值现在变为
    0.95*max\u val
    。同样,对于标准偏差,只需使用
    std
    函数找到它是什么,并确保将其转换为一个向量,以便可以计算整个图像的值,然后阈值变为
    max\u val-std\u val
    ,其中
    std\u val
    是相似性值的标准偏差

    因此,对于百分比比较,请执行以下操作:

    %% find peak correlation
    x = 0.05; % For example
    [max_c, imax] = max(abs(c(:)));
    [ypeak, xpeak] = find(c >= (1-x)*max_c);
    
    std_dev = std(abs(c(:)));
    [max_c, imax] = max(abs(c(:)));
    [ypeak, xpeak] = find(c >= (max_c - std_dev));
    
    。。。并对标准偏差进行比较:

    %% find peak correlation
    x = 0.05; % For example
    [max_c, imax] = max(abs(c(:)));
    [ypeak, xpeak] = find(c >= (1-x)*max_c);
    
    std_dev = std(abs(c(:)));
    [max_c, imax] = max(abs(c(:)));
    [ypeak, xpeak] = find(c >= (max_c - std_dev));
    

    一旦您最终确定了这一点,您将看到有多个匹配项。现在需要在图像顶部绘制所有检测到的模板。使用“借用”代码的帖子,可以修改用于绘制检测到的模板的代码以绘制多个模板

    您可以在下面执行此操作:

    %% display best matches
    tx = size(template, 2);
    ty = size(template, 1);
    hFig = figure;
    hAx  = axes;
    imshow(background, 'Parent', hAx);
    hold on;
    
    for ii = 1 : numel(xpeak)
        position = [xpeak(ii), ypeak(ii), tx, ty]; % Draw match on figure
        imrect(hAx, position);
    end
    

    你只取c中的最大值,它只给你一分。取而代之的是取与最大值相距一定epsilon距离的所有点。如何找到与最大值相距的epsilon距离尝试将c中的唯一值分成两组(可能使用kmeans)。一个简单的方法就是从最大值中减去一个STD。或者获取c中唯一值的直方图,并尝试查看是否可以轻松找到相关性值下降的点。仅供参考,此用户从以下帖子获取此代码:。这将是很好的信贷,你从那里采取的代码,所以人们没有解释,你写的代码自己。此代码也没有运行,因为您缺少
    find
    语句,该语句给出了最大值的位置,分别存储在
    xpeak
    ypeak
    中。我在第一行中提到了问题引用,并在代码中使用了“find”。