title: Python cv2 Image Pyramids
body: <p>Trying to implement the famous Orange/Apple pyramids blending (<a href="http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_pyramids/py_pyramids.html" rel="nofollow noreferrer">cv2 Image Pyramids</a>).  </p>
  
  <p>Note: Both images shape is 307x307.  </p>
  
  <p>However, since the result image is blurred due to clipping values in <code>cv2.subtract</code> and <code>cv2.add</code> (as stated in <a href="http://opencvpython.blogspot.co.il/2012/06/difference-between-matrix-arithmetic-in.html" rel="nofollow noreferrer">cv2 vs numpy Matrix Arithmetics</a>), I have used <code>numpy</code> arithmetics instead as suggested in <a href="https://stackoverflow.com/questions/30498713/reconstructed-image-after-laplacian-pyramid-not-the-same-as-original-image">StackOverflow: Reconstructed Image after Laplacian Pyramid Not the same as original image</a>.  </p>
  
  <p>I have tested this by performing pyramids on one image and the result image constructed back using pyramids has the same Max,Min,Average pixels values as opposed to using <code>cv2</code> arithmetics.  </p>
  
  <p>However, on pyramids level 7, the result image gets a 'noise' of a red dot and on level 9 the result image gets a lot of green pixels noises. <a href="https://imgur.com/a/gQ9H8" rel="nofollow noreferrer">Images of levels 6, 7, 9 - Imgur Album</a>.</p>
  
  <p>Any ideas why would this happen? The pyramid level 9 green noise I would say happened because the image went below 1x1 shape. But what about the red dot on 7 level pyramid?</p>
  
  <ul>
  <li><p>EDIT : Code Added</p>
  
  <pre><code>numberOfPyramids = 9
  
  # generate Gaussian pyramids for A and B Images
  GA = A.copy()
  GB = B.copy()
  gpA = [GA]
  gpB = [GB]
  
  for i in xrange(numberOfPyramids):
      GA = cv2.pyrDown(GA)
      GB = cv2.pyrDown(GB)
      gpA.append(GA)
      gpB.append(GB)
  
  # generate Laplacian Pyramids for A and B Images
  lpA = [gpA[numberOfPyramids - 1]]
  lpB = [gpB[numberOfPyramids - 1]]
  
  for i in xrange(numberOfPyramids - 1, 0, -1):
      geA = cv2.pyrUp(gpA[i], dstsize = np.shape(gpA[i-1])[:2]) 
      geB = cv2.pyrUp(gpB[i], dstsize = np.shape(gpB[i-1])[:2])
  
      laplacianA = gpA[i - 1] - geA if i != 1 else cv2.subtract(gpA[i-1], geA)
      laplacianB = gpB[i - 1] - geB if i != 1 else cv2.subtract(gpB[i-1], geB)
  
      lpA.append(laplacianA)
      lpB.append(laplacianB)
  
  # Now add left and right halves of images in each level
  LS = []
  for la, lb in zip(lpA, lpB):
      _, cols, _ = la.shape
      ls = np.hstack((la[:, : cols / 2], lb[:, cols / 2 :]))
      LS.append(ls)
  
  # now reconstruct
  ls_ = LS[0]
  for i in xrange(1, numberOfPyramids):
      ls_ = cv2.pyrUp(ls_, dstsize = np.shape(LS[i])[:2])
      ls_ = ls_ + LS[i] if i != numberOfPyramids - 1 else cv2.add(ls_, LS[i])
  
  cv2.imshow(namedWindowName, ls_)
  cv2.waitKey()
  </code></pre></li>
  </ul>