StereoSGBM: different outcome with same input

Consider following snippet:

stereo = cv2.StereoSGBM_create(minDisparity=1, numDisparities=16, blockSize=11)
imgL = np.array([
        [0, 0, 0, 0, 119, 166, 97, 48, 56, 100, 68, 104, 163, 172, 87, 81, 129, 91, 96, 75, 33, 60],
        [0, 0, 0, 0, 216, 212, 146, 107, 123, 157, 208, 110, 134, 136, 49, 139, 125, 110, 66, 106,
         69, 84],
        [0, 0, 0, 0, 184, 204, 195, 180, 162, 174, 148, 78, 92, 125, 141, 202, 128, 75, 91, 188, 91,
         97],
        [0, 0, 0, 0, 76, 218, 211, 185, 95, 76, 126, 110, 121, 183, 153, 177, 206, 62, 104, 204,
         198, 168],
        [0, 0, 0, 0, 99, 176, 169, 180, 105, 50, 184, 128, 100, 157, 82, 43, 101, 67, 85, 85, 134,
         195],
        [0, 0, 0, 0, 89, 125, 150, 215, 102, 100, 216, 114, 119, 127, 177, 71, 94, 191, 214, 109,
         116, 188],
        [0, 0, 0, 0, 56, 140, 142, 153, 96, 87, 122, 119, 222, 202, 142, 55, 66, 127, 172, 135, 64,
         66],
        [0, 0, 0, 0, 23, 83, 87, 96, 115, 165, 101, 134, 204, 223, 100, 36, 92, 174, 157, 155, 202,
         146]
    ], dtype=np.uint8)
imgR = np.array([
        [0, 0, 0, 0, 138, 170, 167, 75, 65, 162, 152, 147, 204, 227, 205, 158, 105, 178, 217, 176,
         157, 128],
        [0, 0, 0, 0, 116, 142, 103, 65, 111, 187, 190, 157, 122, 134, 194, 117, 119, 189, 217, 141,
         134, 100],
        [0, 0, 0, 0, 177, 129, 70, 62, 165, 191, 145, 101, 91, 122, 153, 93, 81, 196, 173, 159, 150,
         54],
        [0, 0, 0, 0, 177, 133, 123, 69, 65, 90, 104, 115, 192, 157, 131, 111, 32, 61, 65, 168, 159,
         107],
        [0, 0, 0, 0, 68, 73, 54, 26, 18, 138, 182, 83, 109, 81, 130, 82, 24, 35, 122, 194, 186,
         150],
        [0, 0, 0, 0, 166, 97, 86, 118, 78, 136, 239, 124, 119, 154, 238, 125, 86, 45, 144, 196, 231,
         149],
        [0, 0, 0, 0, 173, 150, 214, 116, 74, 145, 204, 213, 206, 192, 178, 102, 124, 101, 128, 166,
         99, 57],
        [0, 0, 0, 0, 100, 120, 85, 10, 93, 97, 111, 175, 83, 122, 182, 72, 91, 131, 58, 127, 100,
         29]
    ], dtype=np.uint8)

disparity = stereo.compute(imgL, imgR) / 16

This produces a different matrix each time. Is this to be expected? Is my input not proper?

version: opencv-contrib-python-headless 4.10.0.84 (also opencv-python)
system: Linux version 6.6.31-linuxkit (root@buildkitsandbox) (gcc (Alpine 13.2.1_git20231014) 13.2.1 20231014, GNU ld (GNU Binutils) 2.41) #1 SMP Thu May 23 08:36:57 UTC 2024
Python: 3.10.14 (also with later versions)

I thought I could rein it in by passing disparity=None or a zeroed disparity array. none of that works to make it stable. not even recreating the SGBM instance resets the state.

it’s not random though. it cycles between two solutions.

there must be some internal state for this to happen. I can’t guess where it could be. it’s not in the SGBM. might be in the OpenCL backend.

Thanks for your help @ crackwitz. I just tried the same, with disparity=None as compute() arg. It remains non-deterministic.
The (or an underlying) library indeed seems to be stateful.

I’d like to add that this did not happen with open-cv 3.4.3.18 and Python 3.6. So it used to be deterministic.

Reinitialising the class with cv2.StereoSGBM_create() does not work as you experienced as well.