title: openCV doesn't always actualize the display/show the image
body: <p>I am displaying some very simple numpy array with openCV by using <code>cv2.imshow()</code> and <code>cv2.waitKey()</code>. Sometimes, I want a display to stay for a few seconds and then resume my program. I simply add a <code>time.sleep()</code> with the desired sleep value. Most of the time, everything works fine; however, sometimes the display doesn't change and remains on the previous one. It is very inconsistent. The same code might work 80% of the time, and might not work for the remaining 20%. Interestingly enough, it always seems to be the same image/display which doesn't work across multiple runs; although it does work as well sometimes. As I said, it's very inconsistent.</p>
  <p>Here is a small portion of the code I used to create and show the displays:</p>
  <pre><code>#!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  
  import sys
  import numpy as np
  import cv2
  import time
  
  from matplotlib import colors
  
  class Visual:
      def __init__(self, window, screen_size=None):
          self.window = window
          # screen size and message setting
          if screen_size is None:
              if sys.platform.startswith('win'):
                  from win32api import GetSystemMetrics
                  self.screen_width = GetSystemMetrics(0)
                  self.screen_height = GetSystemMetrics(1)
              else:
                  self.screen_width = 1024
                  self.screen_height = 768
          else:
              self.screen_width, self.screen_height = screen_size
          self.screen_center = (self.screen_width//2, self.screen_height//2)
          
      def draw_background(self, color=(210, 210, 210)):
          if isinstance(color, str):
              r, g, b, _ = colors.to_rgba(color)
              color = [int(c*255) for c in (b, g, r)]
              
          self.img = np.full((self.screen_height, self.screen_width, 3), 
                             fill_value=color, dtype=np.uint8)
          
      def show(self, wait=1):
          cv2.imshow(self.window, self.img)
          cv2.waitKey(wait)
          
  class CrossVisual(Visual):
      def __init__(self, window, screen_size=None):
          super().__init__(window, screen_size)
      
      def draw_cross(self, width_ratio=0.2, height_ratio=0.02, position='center', color='black'):
          if isinstance(color, str):
              r, g, b, _ = colors.to_rgba(color)
              color = [int(c*255) for c in (b, g, r)]
          
          rect_width = int(width_ratio*self.screen_width)
          rect_height = int(height_ratio*self.screen_height)
          
          if position == 'center':
              x = self.screen_center[0]
              y = self.screen_center[1]
          else:
              x, y = position
          
          # Rectangle 1
          xP1 = x - rect_width//2
          yP1 = y + rect_height//2
          xP2 = x + rect_width//2
          yP2 = y - rect_height//2
          cv2.rectangle(self.img, (xP1, yP1), (xP2, yP2), color, -1)
          
          # Rectangle 2
          xP1 = x - rect_height//2
          yP1 = y + rect_width//2
          xP2 = x + rect_height//2
          yP2 = y - rect_width//2
          cv2.rectangle(self.img, (xP1, yP1), (xP2, yP2), color, -1)
          
  class TextVisual(Visual):
      def __init__(self, window, screen_size=None):
          super().__init__(window, screen_size)
          
      def putText(self, text, fontFace=cv2.FONT_HERSHEY_DUPLEX, 
                  fontScale=2, color='white', thickness=2, vertical_offset=0):
          if isinstance(color, str):
              r, g, b, _ = colors.to_rgba(color)
              color = [int(c*255) for c in (b, g, r)]
          
          # Measuring text and choosing position on the screen
          textWidth, textHeight = cv2.getTextSize(text, fontFace, fontScale, thickness)[0]
          xtext = int(self.screen_center[0] - textWidth//2)
          ytext = int(self.screen_center[1] - textHeight//2 + vertical_offset)
          
          # print warnings
          if textWidth &gt; self.screen_width or textHeight &gt; (self.screen_height - ytext):
              print ('WARNING: The text and text settings lead to an output too large for the screen size.')
              
          cv2.putText(self.img, text=text, org=(xtext, ytext),
                      fontFace=fontFace, fontScale=fontScale, 
                      color=color, thickness=thickness, lineType=cv2.LINE_AA)
  </code></pre>
  <p>Sadly, I am unable to reproduce the problem with small piece of code. But I can demonstrate with the following function:</p>
  <pre><code>def display_3s_countdown(window, images=None):
      if images is None:
          images = list()
          
          Visual = TextVisual(window=WINDOW)
          Visual.draw_background(color='lightgrey')
          Visual.putText('3', color='black')
          images.append(Visual.img)
          
          Visual = TextVisual(window=WINDOW)
          Visual.draw_background(color='lightgrey')
          Visual.putText('2', color='black')
          images.append(Visual.img)
          
          Visual = TextVisual(window=WINDOW)
          Visual.draw_background(color='lightgrey')
          Visual.putText('1', color='black')
          images.append(Visual.img)
      
      for image in images:
          cv2.imshow(window, image)
          cv2.waitKey(1)
          time.sleep(1)
  </code></pre>
  <p>As you can see, this small function simply creates 3 images, each with a different number written, in order to create a small 3 seconds countdown. When I do something like:</p>
  <pre><code>v = TextVisual('test window')
  v.draw_background(color='lightgrey')
  v.putText('some random text', color='black')
  time.sleep(3) # To let enough time to read the text
  
  display_3s_countdown(window='test window', images=None)
  </code></pre>
  <p>Sometimes, the number 3 will not be displayed, and the display in the window <code>test window</code> will directly go from <code>'some random text'</code> to the number 2.</p>
  <p>Finally, usually, this behavior goes in pairs with a spinning wheel mouse when I have the mouse on the active cv2 window (only one window is opened at a time anyway). As you might have guessed from the header of my file, I am working on macOS. However, this behavior also appears on Windows.</p>
  <p>I am not very familiar with openCV, thank you for any tip and information you could provide.</p>
  <p>EDIT: Some of my displays are dynamic and are shown as soon as the image is created within a while loop. Thus, efficiency and speed in the display are important.</p>