Performance 找到不同广场标志的最快方法

Performance 找到不同广场标志的最快方法,performance,matlab,image-processing,optimization,matrix,Performance,Matlab,Image Processing,Optimization,Matrix,给定一个图像I和两个矩阵m_1;m_2(与I尺寸相同)。函数f定义为: 因为我的目标设计想要得到f的符号。因此,函数f可以重写如下: 我认为第二个公式比第一个公式快,因为:它 可以忽略平方项 它可以直接计算符号,而不是第一个方程中的两个步骤:计算f和检查符号 你同意我的看法吗?你有其他更快的f公式吗 I =[16 23 11 42 10 11 21 22 24 30 16 22 154 155 156

给定一个图像I和两个矩阵m_1;m_2(与I尺寸相同)。函数f定义为: 因为我的目标设计想要得到f的符号。因此,函数f可以重写如下:

  • 我认为第二个公式比第一个公式快,因为:它 可以忽略平方项
  • 它可以直接计算符号,而不是第一个方程中的两个步骤:计算f和检查符号
你同意我的看法吗?你有其他更快的f公式吗

I =[16    23    11    42    10
    11    21    22    24    30
    16    22   154   155   156
    25    28   145   151   156
    11    38   147   144   153];

m1 =[0     0     0     0     0
     0     0    22    11     0
     0    23    34    56     0
     0    56     0     0     0
     0    11     0     0     0];

m2 =[0     0     0     0     0
     0     0    12    11     0
     0    22   111   156     0
     0    32     0     0     0
     0    12     0     0     0];
输出f是

 f =[1     1     1     1     1
     1     1    -1     1     1
     1     1     1     1     1
     1     1     1     1     1
     1     1     1     1     1]
我实现了第一种方法,但是我没有用matlab完成第二种方法。你能帮我查一下第二条路并比较一下吗

更新:我想添加chepyle和Divakar的代码,以明确问题。请注意,它们都给出了与上述f相同的结果

function compare()
I =[16    23    11    42    10
    11    21    22    24    30
    16    22   154   155   156
    25    28   145   151   156
    11    38   147   144   153];

m1 =[0     0     0     0     0
    0     0    22    11     0
    0    23    34    56     0
    0    56     0     0     0
    0    11     0     0     0];

m2 =[0     0     0     0     0
    0     0    12    11     0
    0    22   111   156     0
    0    32     0     0     0
    0    12     0     0     0];

    function f=first_way()
        f=sign((I-m1).^2-(I-m2).^2);
        f(f==0)=1;

    end

    function f= second_way()
        f = double(abs(I-m1) >= abs(I-m2));
        f(f==0) = -1;

    end

    function f= third_way()
        v1=abs(I-m1);
        v2=abs(I-m2);
        f= int8(v1>v2) + -1*int8(v1<v2); % need to convert to int from logical
        f(f==0) = 1;

    end

disp(['First way : '  num2str(timeit(@first_way))])
disp(['Second way: '  num2str(timeit(@second_way))])
disp(['Third way : '  num2str(timeit(@third_way))])

end
函数比较()
I=[16 23 11 42 10
11    21    22    24    30
16    22   154   155   156
25    28   145   151   156
11    38   147   144   153];
m1=[0
0     0    22    11     0
0    23    34    56     0
0    56     0     0     0
0    11     0     0     0];
m2=[0
0     0    12    11     0
0    22   111   156     0
0    32     0     0     0
0    12     0     0     0];
函数f=第一条路径()
f=符号((I-m1)。^2-(I-m2)。^2);
f(f==0)=1;
结束
函数f=第二条路径()
f=双(abs(I-m1)>=abs(I-m2));
f(f==0)=-1;
结束
函数f=第三条路径()
v1=绝对值(I-m1);
v2=绝对值(I-m2);

f=int8(v1>v2)+-1*int8(v1第二个公式的精度有问题,但为了比较起见,我将在matlab中实现它,以及第三种避免平方和
符号()的方法
函数,符合您的意图。请注意,matlab的矩阵和符号函数经过了很好的优化,第二种和第三种方法都比较慢

function compare()
I =[16    23    11    42    10
    11    21    22    24    30
    16    22   154   155   156
    25    28   145   151   156
    11    38   147   144   153];

m1 =[0     0     0     0     0
    0     0    22    11     0
    0    23    34    56     0
    0    56     0     0     0
    0    11     0     0     0];

m2 =[0     0     0     0     0
    0     0    12    11     0
    0    22   111   156     0
    0    32     0     0     0
    0    12     0     0     0];

    function f=first_way()
        f=sign((I-m1).^2-(I-m2).^2);
    end

    function f= second_way()
        v1=(I-m1);
        v2=(I-m2);
        f= int8(v1<=0 & v2>0) + -1* int8(v1>0 & v2<=0);
    end

    function f= third_way()
        v1=abs(I-m1);
        v2=abs(I-m2);
        f= int8(v1>v2) + -1*int8(v1<v2); % need to convert to int from logical
    end

disp(['First way : '  num2str(timeit(@first_way))])
disp(['Second way: '  num2str(timeit(@second_way))])
disp(['Third way : '  num2str(timeit(@third_way))])

end

第二个公式的准确性存在问题,但为了比较起见,我将在matlab中实现它,并使用第三种方法避免平方和
符号()
函数,符合您的意图。请注意,matlab的矩阵和符号函数经过了很好的优化,第二种和第三种方法都比较慢

function compare()
I =[16    23    11    42    10
    11    21    22    24    30
    16    22   154   155   156
    25    28   145   151   156
    11    38   147   144   153];

m1 =[0     0     0     0     0
    0     0    22    11     0
    0    23    34    56     0
    0    56     0     0     0
    0    11     0     0     0];

m2 =[0     0     0     0     0
    0     0    12    11     0
    0    22   111   156     0
    0    32     0     0     0
    0    12     0     0     0];

    function f=first_way()
        f=sign((I-m1).^2-(I-m2).^2);
    end

    function f= second_way()
        v1=(I-m1);
        v2=(I-m2);
        f= int8(v1<=0 & v2>0) + -1* int8(v1>0 & v2<=0);
    end

    function f= third_way()
        v1=abs(I-m1);
        v2=abs(I-m2);
        f= int8(v1>v2) + -1*int8(v1<v2); % need to convert to int from logical
    end

disp(['First way : '  num2str(timeit(@first_way))])
disp(['Second way: '  num2str(timeit(@second_way))])
disp(['Third way : '  num2str(timeit(@third_way))])

end

这似乎是可比的,有时可能比最初的方法快一点-

f = sign(abs(I-m1) - abs(I-m2)) + sign(abs(m1-m2)) + ...
    sign(abs(2*I-m1-m2)) - 1 -sign(abs(2*I-m1-m2) + abs(m1-m2))

基准测试代码

%// Create random inputs
N = 5000;
I = randi(1000,N,N);
m1 = randi(1000,N,N);
m2 = randi(1000,N,N);

num_iter = 20;  %// Number of iterations for all approaches

%// Warm up tic/toc.
for k = 1:100000
    tic(); elapsed = toc();
end

disp('------------------------- With Original Approach')
tic
for iter = 1:num_iter
    out1 = sign((I-m1).^2-(I-m2).^2);
    out1(out1==0)=-1;
end
toc, clear out1

disp('------------------------- With Proposed Approach')
tic
for iter = 1:num_iter    
    out2 = sign(abs(I-m1) - abs(I-m2)) + sign(abs(m1-m2)) + ...
           sign(abs(2*I-m1-m2)) - 1 -sign(abs(2*I-m1-m2) + abs(m1-m2));    
end
toc
结果

------------------------- With Original Approach
Elapsed time is 1.751966 seconds.
------------------------- With Proposed Approach
Elapsed time is 1.681263 seconds.

这似乎是可比的,有时可能比最初的方法快一点-

f = sign(abs(I-m1) - abs(I-m2)) + sign(abs(m1-m2)) + ...
    sign(abs(2*I-m1-m2)) - 1 -sign(abs(2*I-m1-m2) + abs(m1-m2))

基准测试代码

%// Create random inputs
N = 5000;
I = randi(1000,N,N);
m1 = randi(1000,N,N);
m2 = randi(1000,N,N);

num_iter = 20;  %// Number of iterations for all approaches

%// Warm up tic/toc.
for k = 1:100000
    tic(); elapsed = toc();
end

disp('------------------------- With Original Approach')
tic
for iter = 1:num_iter
    out1 = sign((I-m1).^2-(I-m2).^2);
    out1(out1==0)=-1;
end
toc, clear out1

disp('------------------------- With Proposed Approach')
tic
for iter = 1:num_iter    
    out2 = sign(abs(I-m1) - abs(I-m2)) + sign(abs(m1-m2)) + ...
           sign(abs(2*I-m1-m2)) - 1 -sign(abs(2*I-m1-m2) + abs(m1-m2));    
end
toc
结果

------------------------- With Original Approach
Elapsed time is 1.751966 seconds.
------------------------- With Proposed Approach
Elapsed time is 1.681263 seconds.

我认为你的第二个公式不正确,因为平方项会改变v_I(x,y)的符号
--除非你知道
I>=m_I
或什么。你到底在找什么?第一个方程还是第二个方程,与问题标题一致,但与第一个方程不匹配?@Divakar和angdaers3:对不起,我弄错了第二个方程。我更新了它。让我们再检查一次。我的目标是检查方程1的方程f以最快的方式表示,因为我们只考虑f的符号而没有它的真值,因此,我们可以重新公式化快速计算。time@john2182将我编辑的代码添加到您的基准测试中,同时请增加数据量?我建议这样做-
N=5000;I=randi(1000,N,N);m1=randi(1000,N,N);m2=randi(1000,N,N);
如果内存允许的话。请随意更改
N
,但尽量将其保留为一个大数字。@Divakar:我再次检查它。很抱歉,我的预期结果必须是0到1。这意味着结果f只有{1;-1}。因此我们需要添加行f(f==0)=-1;你有没有其他公式可以加快速度?我提出了一个从公式1I扩展而来的公式2。我认为你的第二个公式不正确,因为平方项会改变v_I(x,y)的符号--除非你知道
I>=m_I
或什么。你到底在找什么?第一个方程还是第二个方程,与问题标题一致,但与第一个方程不匹配?@Divakar和angdaers3:对不起,我弄错了第二个方程。我更新了它。让我们再检查一次。我的目标是检查方程1的方程f以最快的方式表示,因为我们只考虑f的符号而没有它的真值,因此,我们可以重新公式化快速计算。time@john2182将我编辑的代码添加到您的基准测试中,同时请增加数据量?我建议这样做-
N=5000;I=randi(1000,N,N);m1=randi(1000,N,N);m2=randi(1000,N,N);
如果内存允许的话。请随意更改
N
,但尽量将其保留为一个大数字。@Divakar:我再次检查它。很抱歉,我的预期结果必须是0到1。这意味着结果f只有{1;-1}。因此我们需要添加行f(f==0)=-1;你还有其他的方程式可以加快速度吗?我提出了一个方程式2,它从方程式1延伸到Hank Divakar。我通过你的实现和chepyle比较了第一种方式和第二种方式。但是,最快的方式是第一种方式。为什么它最快,尽管它必须计算平方结果。@john2182如果用第一种方式,你的意思是
符号((I-m1)。^2-(I-m2)。^2)
,那么它会给你一个错误的结果,对吗?另外,确保选择足够大的数据来计时!使用这些小数据量,你将无法正确判断它们的性能!不。第一种方法和第二种方法给出相同的结果。第一种方法计算f的结果,然后检查其符号。但是,它必须计算矩阵的平方。对于第二种方法,我们可以在没有矩阵平方的情况下计算f的符号。根据我的观察,第二种方法必须更快。但matlab显示它比第一种方法慢way@john21