I would do this with numpy
rather than OpenCV, but the two are compatible so you can mix and match anyway, or you can adapt the technique to OpenCV once you get the idea of how I am tackling it.
The strategy is to sum all the pixels across every row and make a single pixel wide image (shown on the right below) that is the sum of all the pixels in each row. I then find the biggest value in that column and divide by that to normalise everything to the range 0..100. Now any pixel that is less than 30 in that single pixel wide image means that the corresponding row had less than 30% of white pixels in the original image - i.e. it was largely black.
Then I make the same summation of all the columns to produce the column sums - shown across the bottom of the image below:

I think some folks refer to this technique as a "projection" if you want to Google it.
So, the code looks like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Load image - you can use OpenCV "imread()" just the same and convert to grayscale
im = np.array(Image.open('maze.jpg').convert('L'))
# Get height and width
h,w = im.shape[0:2]
# Make a single pixel wide column, same height as image to store row sums in
rowsums=np.empty((h))
# Sum all pixels in each row
np.sum(im,axis=1,out=rowsums)
# Normalize to range 0..100, if rowsum[i] < 30 that means fewer than 30% of the pixels in row i are white
rowsums /= np.max(rowsums)/100
# Find first and last row that is largely black
first = last = -1
for r in range(h):
if first < 0 and rowsums[r] < 30:
first = r
if rowsums[r] < 30:
last = r
print(first,last)
# Make a single pixel tall row, same width as image to store col sums in
colsums=np.empty((w))
# Sum all pixels in each col
np.sum(im,axis=0,out=colsums)
# Normalize to range 0..100, if colsum[i] < 30 that means fewer than 30% of the pixels in col i are white
colsums /= np.max(colsums)/100
# Find first and last col that is largely black
first = last = -1
for c in range(w):
if first < 0 and colsums[c] < 30:
first = c
if colsums[c] < 30:
last = c
print(first,last)
That outputs:
62 890
36 1509
So the top row of the maze is row 62, and the bottom one is row 890. The left column of the maze is column 36 and the rightmost column is col 1509.
If I draw on an 80% transparent red rectangle to match those locations, I get:
