7

Suppose we are given an integer matrix of pixels of size NxN and an integer k - window size. We need to find all local maximums (or minimums) in the matrix using the sliding window. It means that if a pixel has a minimum (maximum) value compared to all pixels in a window around it then it should be marked as minimum (maximum). There is a well-known sliding window minimum algorithm which finds local minimums in a vector, but not in a matrix http://home.tiac.net/~cri/2001/slidingmin.html

Do you know an algorithm which can solve this problem?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Andrei Baskakov
  • 161
  • 2
  • 3

2 Answers2

19

Since the minimum filter is a separable filter, you can calculate the 2D sliding window minimum by calculating the 1D sliding window minimum for each dimension. For a 4x4 matrix and a 2x2 window, the algorithms works as follows:

Assume this is the matrix at the beginning

3 4 2 1
1 5 4 6
3 6 7 2
3 2 5 4

First, you calculate the 1D sliding window minimum for each row of the matrix separately

3 2 1
1 4 4
3 6 2
2 2 4

Then, you calculate the 1D sliding window minimum of each column of the previous result.

1 2 1
1 4 2
2 2 2

The result is the same as if you calculate the sliding window minimum of a 2D window directly. This way, you can use the 1D sliding window minimum algorithm to solve any nD sliding window minimum problem.

Tom
  • 508
  • 4
  • 10
  • Java implementation- https://gist.github.com/itsnitinsworld/392114ce7b0e1b50fefb6c7116720c54 – Nitin Nov 02 '20 at 06:36
1

This the c++ implementation of above approach .

class MaxQ {
public:
    queue<int>q;
    deque<int>dq;
    void push(int x)
    {
        q.push(x);
        while (!dq.empty() && x > dq.back())
        {
            dq.pop_back();
        }
        dq.push_back(x);

    }
    void pop()
    {
        if (q.front() == dq.front())
        {
            q.pop();
            dq.pop_front();
        }
        else q.pop();
    }
    int max()
    {
        return dq.front();
    }

};


vector<int> maxSliding_1d_Window(vector<int>& v, int k) {
    MaxQ q;
    int n = v.size();
    vector<int>ans;
    for (int i = 0; i < k; i++)
    {
        q.push(v[i]);
    }
    for (int i = k; i < n; i++)
    {
        ans.push_back(q.max());
        q.pop();
        q.push(v[i]);
    }
    ans.push_back(q.max());
    return ans;
}

vector < vector<int> > maxSliding_2d_Window( vector<vector<int>>v, int k)
{

    int n = v.size();
    int m = v[0].size();

    //caclulting sliding window horizontally
    vector<vector<int> > horizontal;
    for (int i = 0; i < v.size(); i++)
    {
        vector<int>part = maxSliding_1d_Window(v[i], k);
        horizontal.push_back(part);
    }

    vector< vector<int > >final(n - k + 1, vector<int>(m - k + 1, -3));
    int c = 0;

    //calculationg sliding window vertically
    for (int j = 0; j < horizontal[0].size() ; j++)
    {
        vector<int>v;
        for (int i = 0; i < horizontal.size(); i++)
        {
            v.push_back(horizontal[i][j]);
        }
        vector<int> tmp = maxSliding_1d_Window(v, k);

        // pushing the result in our resultant matrix
        for (int index = 0; index < n - k + 1; index++)
        {
            final[index][c] = tmp[index];
        }
        c++;


    }

    //return final matrix
    return final;

}
Visluck
  • 47
  • 6