Thursday, 15 April 2021

opencv 31 perspective transform


skewed image, contour bounding box is calculated after canny edge detection

canny edge detection, book contour is outlined

after perspective transform, book is straightened
#main.py
import cv2
import numpy as np
import imutils

high = 200
low = 100

trackbars_img = np.uint8(np.full((50, 500, 3), 255))
cv2.imshow('trackbars', trackbars_img)

def high_change(x):
    global high
    high = x

def low_change(x):
    global low
    low = x

cv2.createTrackbar('low', 'trackbars', 100, 150, low_change)
cv2.createTrackbar('high', 'trackbars', 200, 255, high_change)

while True:
    img = cv2.imread("assets/ikea.jpg")
    h, w, c = img.shape
    relative_h = int(1000/w*h)
    img = cv2.resize(img, (1000, relative_h))
    img_copy = img.copy()

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (7, 7), 0)

    # perform edge detection, then perform a dilation + erosion to
    # close gaps in between object edges
    edged = cv2.Canny(gray, low, high)
    edged = cv2.dilate(edged, None, iterations=1)
    edged = cv2.erode(edged, None, iterations=1)

    # find contours in the edge map
    cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)

    # find contour with biggest area
    largest_contour = None
    for c in cnts:
        largest = 0
        area = cv2.contourArea(c)

        if area > largest:
            largest = area
            largest_contour = c

    box = cv2.minAreaRect(largest_contour)
    box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
    box = np.array(box, dtype="int")

    """
    box contains coordinates of 4 vertices 
    [[ 81 801]
     [ 95  24]
     [890  37]
     [877 815]]
    """

    cv2.drawContours(img_copy, [box.astype("int")], -1, (0, 255, 0), 2)

    #transform area of interest to cover entire image
    box_frame = np.float32(box)
    img_frame = np.float32([[0, relative_h], [0, 0], [1000, 0], [1000, relative_h]])

    matrix = cv2.getPerspectiveTransform(box_frame, img_frame)
    straight_img = cv2.warpPerspective(img_copy, matrix, (1000, relative_h))

    if cv2.waitKey(1) == ord('q'):
        break

    cv2.imshow("picture", img_copy)
    cv2.imshow("canny edge", edged)
    cv2.imshow("straight image", straight_img)

reference:

No comments:

Post a Comment