title: How to pad an numpy.array so it can be np.vsplit()?
body: <p>I am trying to build my own Bubble sheet OMR engine with Python 3.8 and OpenCV.
  Despite several days of debugging, I can't beat that error which occurs when I am cropping the bubbles individualy:</p>
  <pre><code>Traceback (most recent call last):
  File &quot;C:\Users\hsolatges\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\shape_base.py&quot;, line 867, in split
  len(indices_or_sections)
  TypeError: object of type 'int' has no len()
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
  File &quot;c:/autoQuiz/omr.py&quot;, line 80, in &lt;module&gt;
  anwsers_array = tb.parse_anwsers(anwsers_field, MCQ.get('QUESTIONS'), MCQ.get('CHOICES'))
  bubbles = get_bubbles(padded_img, questions, choices)
  File &quot;c:\autoQuiz\toolbox.py&quot;, line 81, in get_bubbles
  rows = np.vsplit(img, questions)
  File &quot;&lt;__array_function__ internals&gt;&quot;, line 5, in vsplit
  File &quot;C:\Users\hsolatges\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\shape_base.py&quot;, line 991, in vsplit
  return split(ary, indices_or_sections, 0)
  File &quot;&lt;__array_function__ internals&gt;&quot;, line 5, in split
  File &quot;C:\Users\hsolatges\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\shape_base.py&quot;, line 872, in split
  raise ValueError(
  ValueError: array split does not result in an equal division
  </code></pre>
  <p>As the size of the bubbles region is arbitrary, I tried to edge-pad it so that its width and height are both a multiple of the number of questions / number of choices (A B C D E). Unfortunately, <em>it doesn't work properly.</em> Except for <strong>tests/omr-1.jpg</strong>, the others fail.</p>
  <p>Here an excerpt of the code:</p>
  <pre><code>def to_next_multiple(n,b):
      return int(ceil(n/b) * b)
  
  def pad_image(img, questions, choices):  
      w, h = img.shape[:2]
      w_final, h_final, = to_next_multiple(w, choices), to_next_multiple(h, questions)
  
      w_padding, h_padding = max(0, w-w_final), max(0, h-h_final)
      padded_img = np.pad(img, ((0, h_padding), (0, w_padding)), 'edge')
  
      return padded_img
  
  def get_bubbles(img, questions, choices):
      bubbles = []
      rows = np.vsplit(img, questions)
      for row in rows:
      cells = np.hsplit(row, choices)
          bubbles.append(cells)
      
      return bubbles
  
  def parse_anwsers(img, questions, choices):
      # Otsu's thresholding after Gaussian filtering
      gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
      blurred = cv.GaussianBlur(gray, (5,5), 0)
      retValue, thresh = cv.threshold(blurred, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
  
      padded_img = pad_image(thresh, questions, choices)
      w, h = padded_img.shape[:2]
  
      # Debugging
      print(f'width: {w}, w_division: {w/choices}')
      print(f'height: {h}, h_division: {h/questions}')
  
      bubbles = get_bubbles(padded_img, questions, choices)
      answers_array = bubbles
      return answers_array
  </code></pre>
  <p>The repo can be found here: <a href="https://github.com/hsolatges/autoQuiz" rel="nofollow noreferrer">https://github.com/hsolatges/autoQuiz</a></p>
  <p><strong>How can I consistently get a ready to be np.vsplit/np.hsplit image ?</strong></p>