Login
main >   to_contours >  


""" Group image in sections. Order the sections and save as separate images.
"""

import cv2
import imutils
import os
import shutil
import sys


def sort_contours(cnts, method="left-to-right"):
    # initialize the reverse flag and sort index
    reverse = False
    i = 0

    # handle if we need to sort in reverse
    if method == "right-to-left" or method == "bottom-to-top":
        reverse = True

    # handle if we are sorting against the y-coordinate rather than
    # the x-coordinate of the bounding box
    if method == "top-to-bottom" or method == "bottom-to-top":
        i = 1

    # construct the list of bounding boxes and sort them from top to
    # bottom
    boundingBoxes = [cv2.boundingRect(c) for c in cnts]
    for boundingbox in boundingBoxes:
        print(boundingbox)
    (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
        key=lambda b:b[1][i], reverse=reverse))

    # return the list of sorted contours and bounding boxes
    return (cnts, boundingBoxes)

def draw_contour(image, c, i):
    #print(i)
    # compute the center of the contour area and draw a circle
    # representing the center
    M = cv2.moments(c)
    if not M.get("m10", ''):
        return image
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])

    # draw the countour number on the image
    cv2.putText(image, "#{}".format(i + 1), (cX - 20, cY), cv2.FONT_HERSHEY_SIMPLEX,
        1.0, (0, 0, 255), 2)
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)

    # return the image with the contour number drawn on it
    return image

def image_contour(img, cnt, i):
    #area = cv2.contourArea(cnt)
    x,y,w,h = cv2.boundingRect(cnt)

    im_out = img[y:y+h, x:x+w]
    sorted_filename = os.path.join(dest_dir, 'img_sorted_{}.png'.format(i+1))
    cv2.imwrite(sorted_filename, im_out)


try:
    filename = sys.argv[1]
except:
    print('Please provide a filename')
    sys.exit()

file_base = os.path.basename(filename)
dest_dir = file_base.rsplit('.', 1)[0]
os.mkdir(dest_dir)
img_location = os.path.join(dest_dir, file_base)
shutil.copy(filename, img_location)

# Load the image
img = cv2.imread(img_location)

# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# smooth the image to avoid noises
gray = cv2.medianBlur(gray,1)

# Apply adaptive threshold
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
thresh_color = cv2.cvtColor(thresh,cv2.COLOR_GRAY2BGR)

# apply some dilation and erosion to join the gaps - change iteration to detect more or less area's
thresh = cv2.dilate(thresh,None,iterations = 8)
thresh = cv2.erode(thresh,None,iterations = 8)

cnts = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=False)

(cnts, boundingBoxes) = sort_contours(cnts, method="top-to-bottom")

# loop over the (now sorted) contours and draw them
contour_numbered = thresh_color
print(len(cnts))
for (i, c) in enumerate(cnts):
    #print(i+1, ':', c)
    contour_numbered = draw_contour(contour_numbered, c, i)
    image_contour(img, c, i)


cv2.imwrite(os.path.join(dest_dir, 'sorted.jpg'), contour_numbered)
hidden1

hidden2