Repository: opencv
Issue: DISOpticalFlow crashing with unknown exception for a particular choice of image pair, flow direction and params
Labels: bug,category: video,confirmed

<!--
If you have a question rather than reporting a bug please go to https://forum.opencv.org where you get much faster responses.
If you need further assistance please read [How To Contribute](https://github.com/opencv/opencv/wiki/How_to_contribute).

This is a template helping you to create an issue which can be processed as quickly as possible. This is the bug reporting section for the OpenCV library.
-->

##### System information (version)
<!-- Example
- OpenCV => 4.2
- Operating System / Platform => Windows 64 Bit
- Compiler => Visual Studio 2017
-->

- OpenCV => 4.2
- Operating System / Platform => Windows 10 64bit, Linux 20.04 64bit
- Compiler => prebuilt opencv-python & opencv plugin for matlab with mex, compiler VS 2017

##### Detailed description

I am using the DISOpticalFlow optical flow class to calculate flow between pairs of images. I call the optical flow via the python bindings and/or through matlab by compiling C++ code to MEX using the Matlab OpenCV plugin. I expect the code to not crash and in the case that it does crash to raise a meaningful exception.

When run with some fixed/moving image pairs the process crashes. Until opencv-python 4.5.1.48 these crahes were silent, without even raising an exception. Since the latest 4.5.2.52 opencv-python release, an "Unknown C++ exception from OpenCV code" is raised. This is a huge improvement already, since it can be worked around in some cases, but it is still unhelpful in tracking down the issue and resolving it.

After extensive testing it seems that whether the process will crash depends on at least the image pair, which image is considered fixed and the patchSize parameter. Changing the preset seems to also effect whether the code will crash or not with FAST/ULTRAFAST less likely to crash, but also sometimes crashes.


##### Steps to reproduce
Image to reproduce the issue are attached in (large) zip file.
[optical_flow_issue_images.zip](https://github.com/opencv/opencv/files/6568927/optical_flow_issue_images.zip)

<!-- to add code example fence it with triple backticks and optional file extension
    ```.cpp
    // C++ code example
    ```
 or attach as .txt or .zip file
-->
The following code demonstrate the issue by calculating optical flow between two pairs of images, fixed + moving_w (working) and fixed + moving_nw (not working), and patchSize 15 or 25. 

When run in the reverse direction (from moving to fixed), there is no error regardless of which image pair is used. When using patchSize=15 also everything is working for both pairs. 

When calculating optical flow from fixed to moving (straight direction) and patchSize=25 the running crashes.

I have run this code mostly using the python bindings (opencv-python), but I have experienced the same issue when compiling C++ code to MEX using the matlab OpenCV plugin, so I do not think this issue is due to the python binding directly. 

I was able to reproduce this issue on both Win and Linux machines.

```
import cv2


def get_DIS_flow(moving, fixed, patch_size):
    preset = cv2.DISOPTICAL_FLOW_PRESET_MEDIUM
    patch_stride = 10

    DIS_flow = cv2.DISOpticalFlow.create(preset)

    DIS_flow.setPatchSize(patch_size)
    DIS_flow.setPatchStride(patch_stride)

    flow = DIS_flow.calc(fixed, moving, None)
    return flow


if __name__ == '__main__':

    fixed = cv2.imread('./fixed_gray.tiff', cv2.IMREAD_GRAYSCALE)
    moving_nw = cv2.imread('./moving_nw_gray.tiff', cv2.IMREAD_GRAYSCALE)
    moving_w = cv2.imread('./moving_w_gray.tiff', cv2.IMREAD_GRAYSCALE)

    patch_size = 15
    # with patch_size=15 everything is working
    print('patch_size {} moving_w call straight direction'.format(patch_size))
    D = get_DIS_flow(moving_w, fixed, patch_size)
    print('ok')
    print('patch_size {} moving_w call reverse direction'.format(patch_size))
    D = get_DIS_flow(fixed, moving_w, patch_size)
    print('ok')

    print('patch_size {} moving_nw call straight direction'.format(patch_size))
    D = get_DIS_flow(moving_nw, fixed, patch_size)
    print('ok')
    print('patch_size {} moving_nw call reverse direction'.format(patch_size))
    D = get_DIS_flow(fixed, moving_nw, patch_size)
    print('ok')

    patch_size = 25
    # with patch_size=25 moving_w calls still work
    print('patch_size {} moving_w call straight direction'.format(patch_size))
    D = get_DIS_flow(moving_w, fixed, patch_size)
    print('ok')
    print('patch_size {} moving_w call reverse direction'.format(patch_size))
    D = get_DIS_flow(fixed, moving_w, patch_size)
    print('ok')

    # with patch_size=25 moving_nw in reverse direction works
    print('patch_size {} moving_nw call reverse direction'.format(patch_size))
    D = get_DIS_flow(fixed, moving_nw, patch_size)
    print('ok')
    # with patch_size=25 moving_nw in straight direction crashes
    print('patch_size {} moving_nw call straight direction'.format(patch_size))
    try:
        D = get_DIS_flow(moving_nw, fixed, patch_size)
        print('ok')
    except Exception as e:
        print('only gets here in version 4.5.2.52')
        print(e)

```

Thank you for taking the time to look into this.
##### Issue submission checklist

 - [* ] I report the issue, it's not a question
   <!--
   OpenCV team works with forum.opencv.org, Stack Overflow and other communities
   to discuss problems. Tickets with question without real issue statement will be
   closed.
   -->
 - [ *] I checked the problem with documentation, FAQ, open issues,
       forum.opencv.org, Stack Overflow, etc and have not found solution
   <!--
   Places to check:
   * OpenCV documentation: https://docs.opencv.org
   * FAQ page: https://github.com/opencv/opencv/wiki/FAQ
   * OpenCV forum: https://forum.opencv.org
   * OpenCV issue tracker: https://github.com/opencv/opencv/issues?q=is%3Aissue
   * Stack Overflow branch: https://stackoverflow.com/questions/tagged/opencv
   -->
 - [* ] I updated to latest OpenCV version and the issue is still there
   <!--
   master branch for OpenCV 4.x and 3.4 branch for OpenCV 3.x releases.
   OpenCV team supports only latest release for each branch.
   The ticket is closed, if the problem is not reproduced with modern version.
   -->
 - [* ] There is reproducer code and related data files: videos, images, onnx, etc
   <!--
   The best reproducer -- test case for OpenCV that we can add to the library.
   Recommendations for media files and binary files:
   * Try to reproduce the issue with images and videos in opencv_extra repository
     to reduce attachment size
   * Use PNG for images, if you report some CV related bug, but not image reader
     issue
   * Attach the image as archive to the ticket, if you report some reader issue.
     Image hosting services compress images and it breaks the repro code.
   * Provide ONNX file for some public model or ONNX file with with random weights,
     if you report ONNX parsing or handling issue. Architecture details diagram
     from netron tool can be very useful too. See https://lutzroeder.github.io/netron/
   -->