Wikipedia:Reference desk/Archives/Mathematics/2024 July 2

Mathematics desk
< July 1 << Jun | July | Aug >> Current desk >
Welcome to the Wikipedia Mathematics Reference Desk Archives
The page you are currently viewing is a transcluded archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


July 2

edit

Array of random values

edit

Given a 2-dimensional array of random values (think of a noisy image) how do you construct an autocorrelation filter that will converge on a given point in the array starting anywhere in the array (or almost anywhere) Philvoids (talk) 15:41, 2 July 2024 (UTC)[reply]

Does this answer your question?
  1. Compute the two-dimensional discrete Fourier transform of the image (for which you can use the two-dimensional version of the fast Fourier transform algorithm).
  2. Filter out the high spatial frequencies.
  3. Compute the inverse transform.
 --Lambiam 17:54, 2 July 2024 (UTC)[reply]
A numerical test
The following discussion has been closed. Please do not modify it.
Below is an 8x8 array of numbers. Start from any one of 64 locations ranging from (x0,y0) = (0,0) bottom left to (7,7) top right. Can you show a formula whose input (x0,y0) always yields as output (X,Y) = (3,3) ?

Y
^
|
|

7  247   51  132   34  223    6  121  243

6   81  196  176  224   77  159  211  171

5  119  245   56  244  141  247   33  115

4  254   49  175  170   95   19  208  108

3  118  204  145  117   25  242  162  229

2   35  200  250  115   45   62  229  135

1  212  219  232  186  196   59   68   74

0  192  207   14  129  102   13   28   65

    0    1    2    3    4    5    6    7    -->X 

Philvoids (talk) 09:08, 3 July 2024 (UTC)[reply]

I have a hard time understanding the question. What does it mean for a formula (or an algorithm) to "start from a location"? The constant function   trivially meets the requirement, but this cannot be what you are looking for. If the output should be the same, regardless of   why is this location supplied as input? I assume that the matrix of values is also part of the input. What is it about these values that makes   the desired output?  --Lambiam 12:03, 3 July 2024 (UTC)[reply]
I have a hard time understanding it as well. I don't know what an "autocorrelation filter" is either, but maybe that's just me. I know what autocorrelation is, and I know what a filter is, but the two words together don't seem to have any special meaning and a Google search wasn't very enlightening. A filter would, according to my understanding of the meaning in this context, produce an array from a another array. The generic application of a filter would produce a sequence from another sequence. For example a noise filter would take, for example, an audio file, and remove the noise producing another file with just the speech or music or whatever. You can use the same idea with two dimensional arrays to clean up images, or three dimensional arrays to clean up video. (This is basically what Lambiam's original answer would do.) Such arrays are typically highly autocorrolated and the outputs of a noise filter would be more so, but I don't see how that translates to "autocorrelation filter". In any case, the question seems to want not an array as output, but a location within the array. In general you have to be more specific about what the function is supposed to do, not just give an example. If I ask for a function with f(2)=4, it could be f(x)=x2 or x+2 or just 4; there's not enough information in the question to get a meaningful answer. --RDBury (talk) 16:06, 3 July 2024 (UTC)[reply]
"Given a 2-dimensional array" - it could be any array and in the test example I give an 8x8 array of integers. That is a given data.(It could be a different array, maybe larger.) "Start anywhere in the array" - there are 64 locations in the example array and you can start at (0,0) or (0,1) or (0,2) or...all the way up to (7,7). Whatever formula or procedure or algorithm you provide MUST ALWAYS yield as output the arbitrary (means I chose it) location x=3, y=3 i.e. (3,3) that happens to hold the value 117 in the example. I don't know whether you can manage it, and you may have difficulty with the corner or edge locations. But if you can't solve the question, maybe you can reword it for everyone better than I have managed. Philvoids (talk) 20:27, 3 July 2024 (UTC)[reply]
Define function   by
 
If that does not solve your problem, can you explain how this falls short?  --Lambiam 21:26, 3 July 2024 (UTC)[reply]
@Lambiam Your first response described how you would use an FFT and its inverse to remove high frequency "noise" from the array data. Your latest response abandons the reader to define a map conversion. Philvoids (talk) 14:55, 4 July 2024 (UTC)[reply]
I do not understand what problem you are trying to solve. Given how you restated it, my latest response should – using my best effort in interpreting the restatement – be a solution (in fact, the only solution). Since I also understand that it can't be this simple, your pointing out in some detail in which respects it does not satisfy the requirements for being a solution might, perhaps, help me get some grip on what problem you are trying to solve. At the moment, I am totally clueless.  --Lambiam 17:31, 4 July 2024 (UTC)[reply]
I do not understand these problem statements either. Is the intended output an input? If it's not an input then how is an independent oracle going about computing the output? Otherwise, "f(x,y) times zero plus i" and "f(x,y) minus f(x,y) plus j" are just a few of many arithmetic formula that take the values at any f(x,y) as inputs and are negated, and thus always return indexes i and j as input for some value at f(i,j). Modocc (talk) 21:02, 4 July 2024 (UTC)[reply]
Perhaps it would help to give some context to the problem instead of trying to state it in the abstract. What does the array represent? What does a position on the array represent? If we had the real world situation you're trying to deal with then maybe the problem you're trying to solve would be self-evident. --RDBury (talk) 21:32, 4 July 2024 (UTC)[reply]

The context for my question is my interest in efficient software to perform Image stitching, Document mosaicing or extraction of unlimited large-area maps from multiple map patches screen dumped from sites such as Google Maps. In each case we begin with a pair of images (which are 2D arrays of pixel values) that are known to overlap partly, but the exact offset between them has to be found before we can join them seamlessly. Stitching map patches together seems relatively easy because with correct offset there will be 100% correlation between the images in their overlap area; this is an autocorrelation because the pixels come from one master map. Consider my 8x8 array example as part of a map overlap area; we make a rough guess of the x-y offset of the overlapping map. Allow that the guess is likely inaccurate, which becomes apparent if we look for the pixel value at position (x,y)=(3,3) on the second map, and are disapointed to find it is not 117. We know all the array values and its size suggests there is one correct offset and 63 wrong offsets.

Pseudocode for a clumsy stitching
The following discussion has been closed. Please do not modify it.
define maparray(8,8)
x=0
y=0
v=maparray(0,0)
while v != maparray(3,3)
  {x++
   if x==8 then x=0, y++
   if y==8 then print "No match found."
   v=maparray(x,y)
                  }
print "Update offset by x:",-x,"  y:",-y

Deficiencies of this code are
- Up to 63 comparisons can be be needed before the correct offset is found
- Noise causing false positive(s) or failure is not considered in my question but it arises when stitching photographs. The clumsy routine lacks noise tolerance because a 1 or 2 unit deviation at (3,3) disables the search, or causes a false positive at (3,2), (0,3), (0,5) or (7,5). That is regarding the array byte values that could represent 256 grey levels; I think that the error probabilities in hardware are independent of bit weightings and I find that there are 13 locations whose values have 2 or less [[Hamming distance]] from the value in (3,3) that was used for searching.

Ideas for an improved algorithm

- A larger array may be needed for a larger overlap area

- Sequential search costs time and computation effort but is only necessary where there is no gradient to follow towards the correct offset.

- False positives that arise from noise when searching for one pixel value may be reduced by searching for blocks of pixel values, such as the combination of (3,3), (4,3), (3,4) and (4,4). Philvoids (talk) 20:05, 5 July 2024 (UTC)[reply]

The commonly used methods for photo stitching and for document mosaicing involve feature detection, which can be seen as a (possible very rudimentary) way of interpreting the images. You appear to be seeking an approach that is, so to speak, interpretation-free.
In your pseudocode there is only one map, but a stitching algorithm needs two maps as input. Very abstractly, the general problem involves
A "map" is then a function from a domain to a codomain.
Moreover, there is
Given a map   and a domain transformation   we can define
 
The problem is now, given two maps   and   to determine a transformation   that maximizes the goodness of fit between   and   Ideally, the latter is the same as the goodness of fit between   and   so that the problem is symmetric.
In your case the domains are rectangular subsets of   and the codomain is the set of integers or real numbers, but it could also be the set of values of some colour model. The domain transformations are translations of the elements of a domain. The measure for goodness of fit could be the correlation (not "autocorrelation") between   and   restricted to the intersection of their domains. Depending on the application, other measures may give better results.
I am not aware of efficient algorithms for your version of the general problem, but here is an approach that I expect to work well for certain types of images – but not so well on some other types.
The basic idea is to find the best shift for scaled-down versions of the images. The scaled-back-up shift should be close to the optimal one; simple hill climbing should quickly lead to an optimum. This can be applied recursively, but scaling down too much may turn the images into featureless blurs for which the goodness of fit is a meaningless measure.  --Lambiam 13:49, 6 July 2024 (UTC)[reply]
The only thing I'd add is that it seems to me that creating such an algorithm from scratch is reinventing the wheel. Hugin is open source, stable (or so they claim), and available for download. I can understand wanting to "roll your own" if you really want to understand the algorithms, but there is a lot of specialized knowledge involved and you should at least have a general idea what actually goes into the programs. There is more than you might think, such as adjusting for differences in lighting and perspective. "I hear, I forget. I see, I remember. I do, I understand," as the proverb goes, But we can't always the spare the man-years needed to skip the "I hear" and "I see" stages. --RDBury (talk) 03:02, 7 July 2024 (UTC)[reply]

I limit the scope of my question to solving the challenge of stitching together map patches under these conditions: 1. There is no differential distortion between patches, no rotation, no stretching or compression, no lighting or parallax difference as can occur between photographs. 2. There is some uncertainty in the offset of the X and Y coordinates of the 2nd patch from the coordinates of the 1st patch that shall be regarded as the true reference coordinates for the full map to be produced. 3. From our knowledge of manually collecting map patches we predict our maximum error in estimating the X and Y offsets of a new patch. To accomodate these errors we need a practical overlap area between patches. The example calls for an 8x8 pixel overlap area. 4. For stitching a given pair of map patches, the predicted overlap area will be chosen close to a corner of the first established patch, from which the array of pixel values is read. Condition no. 1 guarantees that exactly the same array of pixel values exists somewhere to be found on the 2nd patch. 5. To run the pseudocoded algorithm below we must identify a unique target pixel in the overlap array. This was done in the example presented. Here only the pixel located at (xt,yt) = (3,3) and no other has the value 117. The algorithm fails if any other pixel in the array has the same value as the target. Obviously it is difficult to find a unique target in, say, a featureless desert area on a map. In such cases it may be easiest with manual interaction to try another target within the given array, or to choose a different overlap area. Pinpointing a suitable target pixel is a simpler and quicker task than the feature detection described by Lambiam. 6. The pseudocode below obviously does find the target pixel at correct offset (3,3) when it sees as input data only the test array that already has correct reference XY coordinates. However it succeeds in finding the target pixel wherever it may be hidden within the overlap array by incorrect estimates of the 2nd patch coordinates; this solution I report as tested for all 63 possible misalignments of the patches. The algorithm proceeds by building two "guide" arrays XG() and YG() that are progressively filled with 511 (a pixel value that is outside the range of single-byte pixel values) at invalid locations. 7. The inference when the algorithm takes as input array the 2nd patch using the uncertain estimated coordinate system (Xestim, Yestim) and finds the target pixel at (xu,yu) is that the correct 2nd patch coordinates to be used for stitching are ( (Xestm - xu + 3), (Yestim - yu + 3) ).

Pseudocode for stitching map patches
The following discussion has been closed. Please do not modify it.
rem INPUTS:
     dimension A(7,7) as example array A(x,y)
     tx=3             example target is (3,3)
     ty=3
rem VARIABLES:
     dimension B(7,7), XG(7,7), YG(7,7)
rem ASSIGNATIONS:
     for y=0 to 7
     { for x=0 to 7
       { B(x,y)=A(x,y)-A(tx,ty)
         if y==ty {
                    XG(x,ty)=B(x,y)
                                    }
            else {
                    XG(x,ty)=511
                                    }
         if x==tx {
                    YG(tx,y)=B(x,y)
                                    }
            else {
                    XG(tx,y)=511
                                    }
        }
rem SEARCH:
     for x=0 to 7
     { for y=0 to 7
       { if B(x,y)==YG(x,y)
          { xu=x
            goto XFOUND
                         }
       }"
     print ERROR: X NOT FOUND
XFOUND:
     for y=0 to 7
     { for x=0 to xu
       { if B(x,y)==XG(x,y)
          { yu=y
            print OFFSET (X,Y) FOUND.
            end
                          }
       }
     print ERROR: Y NOT FOUND

Philvoids (talk) 20:47, 16 July 2024 (UTC)[reply]

In this form the problem looks like a 2D version of a string-searching algorithm. In 1D, a good algorithm is the Knuth–Morris–Pratt algorithm, and I expect similar ideas can be used to improve this 2D version.  --Lambiam 20:53, 16 July 2024 (UTC)[reply]