Average a matrix over all possible rotations

83 Views Asked by At

Is there a mathematically simple way to create a matrix M' from a matrix M, which is equal to

$\int_0^{2 \pi} \hat{R}_\theta \; M \; d \theta$

Say I have a matrix which represents an image and I want to simulate the image I would have got if I was spinning the target image really fast. I realise what I proposed was more like spinning the camera, but I don't think that matters as I was going to trip the edges of the matrix to force it to be the original size.

Example:

I have a 3x3 matrix

$ M = \begin{pmatrix} 0 & 0 & 1 \\ 0 & 2 & 0 \\ 0 & 0 & 0 \end{pmatrix} $

This would be averaged to something like

$ M = \begin{pmatrix} 1/8 & 0 & 1/8 \\ 0 & 2 & 0 \\ 1/8 & 0 & 1/8 \end{pmatrix} $

where I would really need a 5x5 to represent it, but I have just thrown that stuff away. Dealing with the discritisation is a problem as well.

Is there a standard procedure for this? It seems like something that would be used by photoshop.

2

There are 2 best solutions below

1
On

In principle you can rotate the image $n$ times by $360/n$ and then average over all the images, but a simpler way is to average all pixels in a ring directly:

  • Choose the pixel that is the center of rotation ( say $x_c,y_c$)
  • Create an image with pixel values that are the radial distance from the center of rotation, that is , $I_r(x,y)=\sqrt{(x-x_c)^2+(y-y_c)^2}$.
  • Divide your original image into concentric rings based on the value of $I_r$.
  • Average the values of all the pixels in a ring and replace the image pixels in that ring with these values
0
On

I went with a method of taking an average of all pixels within a radial bin. In case anyone wants to try this themselves I've posted the matlab code I used to implement this.

rsq = ((1:length(M))  - (length(M)+1)/2).^2;
r = sqrt(rsq + rsq');
[r_sorted, sort_idx] = sort(r(:));
[r_unique, IA, IC] = unique(r_sorted); % unique r values
[r_whole, IA2, IC2] = unique(round(r_unique));  % unique when limited to integers

IAA = cat(1, IA(IA2), length(r_whole)+1); % range mapping
Mr = zeros(length(r_whole), 1);
rmax = max(r_whole);
r_cutoff = rmax/sqrt(2);

Mrflat = M(:);
Mrflat = M(sort_idx);


for lp = 1: length(r_whole)
    idx = IAA(lp):IAA(lp+1)-1;
    if r_whole(lp) < r_cutoff % can count squares
        n_fact = length(idx);
    else
        n_fact =  pi*(r_whole(lp).^2-(r_whole(lp)-1).^2); % area between circles
    end
    Mr(lp)  =  sum(Mrflat(idx))./n_fact;
end