def scan_for_checks(image_filenames: List[str], centers: np.ndarray,
                    export_dir) -> List[Dict]:
    log('Scanning centers for checks in {} files'.format(len(image_filenames)))
    page_dicts = []
    for page_num, fname in enumerate(image_filenames):
        log('Scanning {} ({} of {}):'.format(fname, page_num + 1,
                                             len(image_filenames)))
        orig = cv2.imread(fname)
        orig_height, _, _ = orig.shape
        resize_factor = wanted_height / orig_height
        resize = cv2.resize(orig, (0, 0), fx=resize_factor, fy=resize_factor)
        grey = cv2.cvtColor(resize, cv2.COLOR_RGB2GRAY)
        thresh = cv2.adaptiveThreshold(grey, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
                                       cv2.THRESH_BINARY, 11, 2)
        erode_kernel = np.ones((3, 3), np.uint8)
        erode = cv2.erode(thresh, erode_kernel)
        boxes_dict = {}
        for center_num, center in enumerate(centers):
            x, y = center[0], center[1]
            mean = np.mean(
                erode[int(y - check_range / 2):int(y + check_range / 2),
                      int(x - check_range / 2):int(x + check_range / 2)])
            cv2.circle(resize, (x, y), 2, color_blue, thickness=2)
            if mean < blank_box_mean - check_thresh:
                boxes_dict[center_num] = True
                cv2.circle(resize, (x, y),
                           circle_radius,
                           color_green,
                           thickness=3)
        page_dicts.append({'page': page_num, 'boxes': boxes_dict})
        cv2.imwrite('{}/{}.jpg'.format(export_dir, str(page_num)), resize)
    return page_dicts
def get_args() -> Tuple[str, int]:
    pdf_fname = ""
    k = 0
    try:
        pdf_fname = sys.argv[1]
        k = int(sys.argv[2])
    except (ValueError, IndexError):
        log("Usage: ./main.py file.pdf k")
        exit(1)
    finally:
        pass

    if not path.isfile(pdf_fname):
        log("{} is not a valid file".format(pdf_fname))
        exit(1)

    return pdf_fname, k
Beispiel #3
0
def convert_to_jpg(pdf_filename, export_path) -> list:
    # Convert to jpg
    log('Starting conversion to jpg...')
    start = timeit.default_timer()
    pages = convert_from_path(pdf_filename, 500)
    end = timeit.default_timer()
    log('Successfully converted %d pages in %d seconds.' %
        (len(pages), end - start))

    # Save images
    log('Saving to %s/...' % export_path)
    image_filenames = []
    for i, page in enumerate(pages):
        image_filename = '%s/p%d.jpg' % (export_path, i)
        image_filenames.append(image_filename)
        page.save(image_filename, 'JPEG')
    log('Saved all images')
    return image_filenames
def scan_for_squares(image_filenames) -> np.ndarray:
    log('Looking for checkboxes in {} images'.format(len(image_filenames)))
    centers = []
    for i, fname in enumerate(image_filenames):
        log('Scanning {} ({} of {}):'.format(fname, i + 1,
                                             len(image_filenames)),
            end=' ')
        orig = cv2.imread(fname)
        orig_height, _, _ = orig.shape
        resize_factor = wanted_height / orig_height
        resize = cv2.resize(orig, (0, 0), fx=resize_factor, fy=resize_factor)
        img2 = cv2.cvtColor(resize, cv2.COLOR_RGB2GRAY)
        canny = cv2.Canny(img2, 0, 100)
        dilate_kernel = np.ones((5, 5), np.uint8)
        dilate = cv2.dilate(canny, dilate_kernel)
        erode_kernel = np.ones((5, 5), np.uint8)
        erode = cv2.erode(dilate, erode_kernel)
        contours = cv2.findContours(erode.copy(), cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = imutils.grab_contours(contours)
        center_count = 0
        for c in contours:
            peri = cv2.arcLength(c, True)
            c_approx = cv2.approxPolyDP(c, 0.04 * peri, True)
            if len(c_approx) == 4 \
                    and square_area - area_thresh < cv2.contourArea(c) < square_area + area_thresh \
                    and square_perimeter - perimeter_thresh < peri < square_perimeter + perimeter_thresh:
                cv2.drawContours(resize, [c_approx], -1, color_green, 4)
                moments = cv2.moments(c)
                center_x = int(moments["m10"] / moments["m00"])
                center_y = int(moments["m01"] / moments["m00"])
                centers.append([center_x, center_y])
                center_count += 1
        log('{} boxes'.format(center_count))
    if len(centers) == 0:
        return np.empty(0)  # Cannot np.vstack empty list
    else:
        return np.vstack(centers)
    except (ValueError, IndexError):
        log("Usage: ./main.py file.pdf k")
        exit(1)
    finally:
        pass

    if not path.isfile(pdf_fname):
        log("{} is not a valid file".format(pdf_fname))
        exit(1)

    return pdf_fname, k


(pdf_filename, k_centers) = get_args()

log("Starting survey scan of {}. Looking for {} boxes.".format(
    pdf_filename, k_centers))

export_dirname = '/tmp/survey/{}'.format(uuid.uuid4())
makedirs(export_dirname)

raw_dir = '{}/raw'.format(export_dirname)
makedirs(raw_dir)
test_image_filenames = convert_to_jpg(pdf_filename, raw_dir)

log('Starting scan for boxes.')
start = timeit.default_timer()
test_centers = scan_for_squares(test_image_filenames)
end = timeit.default_timer()
log('Scanned {} pages in {} seconds.'.format(len(test_image_filenames),
                                             int(end - start)))