title: [OpenCV]how to fix contours to rectangle?
body: <h1>Note</h1>
  <p>I'm new to OpenCV(or computer vision), so it would be very helpful just to tell me the search query!</p>
  <h1>What I want to ask</h1>
  <p>I want to write a program that extract the business cards from pictures.
  I was able to extract a rough outline, but reflected light becomes noise and I can't extract an accurate outline. Please tell me your idea.</p>
  <h2>image(raw data)</h2>
  <p><a href="https://i.stack.imgur.com/dD1BU.jpg" rel="nofollow noreferrer">raw data</a></p>
  <h2>output</h2>
  <p><a href="https://i.stack.imgur.com/AEpS4.png" rel="nofollow noreferrer">output data(rough outline)</a></p>
  <h2>code</h2>
  <pre><code>import math
  import itertools
  from glob import glob
  
  import cv2
  import numpy as np
  from matplotlib import pyplot as plt
  from mpl_toolkits.mplot3d import Axes3D
  
  %matplotlib inline
  
  def read_images():
      &quot;read image data from data directory&quot;
      names = glob('data/*.jpg')
      names.sort()
      return map(lambda name: cv2.imread(name), names)
  
  def blur(img):
      &quot;apply blur&quot;
      return cv2.GaussianBlur(img, (25, 25), 0)
  
  def show_images(images, column, color_type=cv2.COLOR_BGR2RGB):
      &quot;plot images with matplotlib&quot;
      plt.figure(figsize=(10,10), dpi=150)
      for n, img in zip(range(len(images)), images):
          p = plt.subplot(math.ceil(len(images) / column), column, n + 1)
          p.axis('off')
          if color_type is None:
              p.imshow(img)
          else:
              p.imshow(cv2.cvtColor(img, color_type))
      plt.show()
  
  def detect_background_color(img):
      &quot;detect background color&quot;
      # Assume that the perimeter is all background
      height, width, *_ = img.shape
      background_colors = np.concatenate([
          img[5:height-5, 5],       img[5, 5:width-5],
          img[5:height-5, width-5], img[height-5, 5:width-5]
      ])
      background_colors = background_colors.astype(np.float32)
  
      # Assume that the background color is only one.
      K = 2
      iter_flg = cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER
      _, labels, centers = cv2.kmeans(
          background_colors, K, None, (iter_flg, 10, 1.0), 10,
          cv2.KMEANS_RANDOM_CENTERS)
  
      cnt1 = len(labels[labels==0])
      cnt2 = len(labels[labels==1])
      return centers[0] if cnt1 &gt; cnt2 else centers[1]
  
  def scale(img):
      bg = detect_background_color(img)
      return np.fix(np.sqrt(np.sum(np.square(img - bg), axis=2)) / 1.732).astype(np.uint8)
  
  def binarize(img):
      th, bit = cv2.threshold(img, 40, 255, cv2.THRESH_BINARY)
      return bit
  
  binarized = [binarize(scale(blur(img))) for img in read_images()]
  show_images(binarized, 4, None)
  </code></pre>