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
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)))