简体   繁体   English

如何计算图像的中心矩?

[英]How do I calculate the central moment in an image?

I need to find central moment of an image. 我需要找到图像的中心时刻。 The central moment is given by the equation: 中心矩由下式给出:

where x and y are the spatial image co-ordinates, 其中xy是空间图像坐标, and are the mean x and y (or centroid) co-ordinates, p and q being integers and f(x,y) is an image. 是平均值xy (或质心)坐标, pq是整数, f(x,y)是图像。

In addition, I want to understand how to deal with f(x,y) because it will be holding all pixel values. 另外,我想了解如何处理f(x,y)因为它将保存所有像素值。

Use bsxfun 使用bsxfun

sz = size( img ); %// assuming image is gray scale - 2D array
x = ( 1:sz(2) );
y = ( 1:sz(1) ).'; %'
x = x - mean(x);
y = y - mean(y);
Mpq = sum( reshape( bsxfun( @times, bsxfun( @times, img, x.^p ), y.^q ), [], 1 ) ); %// computing the p-q moment

benchmarking: 基准测试:

disp('Solution of rayryeng')
tic
[rows, cols] = size(img);
[X, Y] = meshgrid(1:cols, 1:rows);
X = X(:);
Y = Y(:);
Mpq = sum((X - mean(X)).^p .* (Y - mean(Y)).^q .* img(:));
toc

disp('rayryeng with dot product');
tic
[rows, cols] = size(img);
[X, Y] = meshgrid(1:cols, 1:rows);
X = X(:);
Y = Y(:);
Mpq = ((X.' - mean(X)).^p )* ((Y - mean(Y)).^q .* img(:));
toc

disp('this solution - using bsxfun');
tic
sz = size( img ); %// assuming image is gray scale - 2D array
x = ( 1:sz(2) );
y = ( 1:sz(1) ).'; %'
x = x - mean(x);
y = y - mean(y);
Mpq = sum( reshape( bsxfun( @times, bsxfun( @times, img, x.^p ), y.^q ), [], 1 ) );
toc

Resulting with 结果与

Solution of rayryeng
Elapsed time is 0.009426 seconds.
rayryeng with dot product
Elapsed time is 0.008374 seconds.
this solution - using bsxfun
Elapsed time is 0.001404 seconds.

As you can see bsxfun is significantly faster than meshgrid -based solutions. 如您所见, bsxfun比基于meshgrid的解决方案要快得多。 Moreover, using dot-product instead of elem-wise product with sum is faster. 而且,使用点积代替带sum的elemwise积更快。

f(x,y) are simply your image intensities at each column location y and each row location x . f(x,y)只是您在每个列位置y和每个行位置x处的图像强度。 If you want to calculate the pq moment for your image, you can do what Shai suggested which will probably be faster. 如果要计算图像的pq矩,则可以按照Shai的建议执行 ,这可能会更快。 However, if you want something more readable that doesn't use , you can simply do this assuming your image is grayscale and stored in im : 但是,如果您想要不使用更具可读性的东西,则可以简单地假设您的图像是灰度图像并存储在im

[rows, cols] = size(im);
im = double(im); %// For precision
[X, Y] = meshgrid(1:cols, 1:rows);
X = X(:);
Y = Y(:);
Mpq = sum((X - mean(X)).^p .* (Y - mean(Y)).^q .* im(:));

First we convert the image to double to ensure that we get the best precision possible. 首先,我们将图像转换为double以确保获得最佳精度。 Your image will probably be of type uint8 , and any values computed that exceed 255 will be clipped. 您的图片可能是uint8类型的,计算出的任何超过255的值都将被裁剪。 You will probably get values beyond this and so casting to double is recommended. 您可能会获得超出此范围的值,因此建议强制转换为double We then use meshgrid to generate a grid of spatial co-ordinates with the same size of the image, then unroll the co-ordinates to a single vector. 然后,我们使用meshgrid生成与图像大小相同的空间坐标网格,然后将坐标展开为单个矢量。 This will make it easier to compute the moment. 这将使计算力矩变得更加容易。 The last line of code finally computes our moment as per the equation. 最后一行代码最终根据方程式计算了我们的力矩。 We also need to unroll the image in the same fashion so that the elements line up properly. 我们还需要以相同的方式展开图像,以便元素正确对齐。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM