diff --git a/README.md b/README.md index 9ce8d29..07b4729 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,19 @@ On my test dataset of 280 images, the program correctly detected the corners of This project makes use of the transform and imutils modules from pyimagesearch (which can be accessed [here](http://www.pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/)). The UI code for the interactive mode is adapted from `poly_editor.py` from [here](https://matplotlib.org/examples/event_handling/poly_editor.html). * You can manually click and drag the corners of the document to be perspective transformed: -![Example of interactive GUI](https://github.com/andrewdcampbell/doc_scanner/blob/master/ui.gif) +![Example of interactive GUI](readme_media/ui.gif) * The scanner can also process an entire directory of images automatically and save the output in an output directory: -![Image Directory of images to be processed](https://github.com/andrewdcampbell/doc_scanner/blob/master/before_after.gif) +![Image Directory of images to be processed](readme_media/before_after.gif) #### Here are some examples of images before and after scan: - + - + - + - + ### Usage diff --git a/output/cell_pic.jpg b/output/cell_pic.jpg deleted file mode 100644 index edea3a3..0000000 Binary files a/output/cell_pic.jpg and /dev/null differ diff --git a/output/chart.JPG b/output/chart.JPG deleted file mode 100644 index 11bffdd..0000000 Binary files a/output/chart.JPG and /dev/null differ diff --git a/output/desk.JPG b/output/desk.JPG deleted file mode 100644 index c4f6373..0000000 Binary files a/output/desk.JPG and /dev/null differ diff --git a/output/dollar_bill.JPG b/output/dollar_bill.JPG deleted file mode 100644 index 82daeb1..0000000 Binary files a/output/dollar_bill.JPG and /dev/null differ diff --git a/output/math_cheat_sheet.JPG b/output/math_cheat_sheet.JPG deleted file mode 100644 index e97451e..0000000 Binary files a/output/math_cheat_sheet.JPG and /dev/null differ diff --git a/output/notepad.JPG b/output/notepad.JPG deleted file mode 100644 index 2990c84..0000000 Binary files a/output/notepad.JPG and /dev/null differ diff --git a/output/receipt.jpg b/output/receipt.jpg deleted file mode 100644 index 6fba926..0000000 Binary files a/output/receipt.jpg and /dev/null differ diff --git a/output/tax.jpeg b/output/tax.jpeg deleted file mode 100644 index 3db7423..0000000 Binary files a/output/tax.jpeg and /dev/null differ diff --git a/before_after.gif b/readme_media/before_after.gif similarity index 100% rename from before_after.gif rename to readme_media/before_after.gif diff --git a/ui.gif b/readme_media/ui.gif similarity index 100% rename from ui.gif rename to readme_media/ui.gif diff --git a/sample_output/cell_pic.jpg b/sample_output/cell_pic.jpg new file mode 100644 index 0000000..1f10082 Binary files /dev/null and b/sample_output/cell_pic.jpg differ diff --git a/sample_output/chart.JPG b/sample_output/chart.JPG new file mode 100644 index 0000000..e94b4c1 Binary files /dev/null and b/sample_output/chart.JPG differ diff --git a/sample_output/desk.JPG b/sample_output/desk.JPG new file mode 100644 index 0000000..85775cd Binary files /dev/null and b/sample_output/desk.JPG differ diff --git a/sample_output/dollar_bill.JPG b/sample_output/dollar_bill.JPG new file mode 100644 index 0000000..1186895 Binary files /dev/null and b/sample_output/dollar_bill.JPG differ diff --git a/sample_output/math_cheat_sheet.JPG b/sample_output/math_cheat_sheet.JPG new file mode 100644 index 0000000..6812000 Binary files /dev/null and b/sample_output/math_cheat_sheet.JPG differ diff --git a/sample_output/notepad.JPG b/sample_output/notepad.JPG new file mode 100644 index 0000000..2dc93e4 Binary files /dev/null and b/sample_output/notepad.JPG differ diff --git a/sample_output/receipt.jpg b/sample_output/receipt.jpg new file mode 100644 index 0000000..1863085 Binary files /dev/null and b/sample_output/receipt.jpg differ diff --git a/sample_output/tax.jpeg b/sample_output/tax.jpeg new file mode 100644 index 0000000..fde145f Binary files /dev/null and b/sample_output/tax.jpeg differ diff --git a/scan.py b/scan.py index 4aa835e..332e991 100644 --- a/scan.py +++ b/scan.py @@ -25,7 +25,7 @@ class DocScanner(object): """An image scanner""" - def __init__(self, interactive=False, MIN_QUAD_AREA_RATIO=0.25, MAX_QUAD_ANGLE_RANGE=40): + def __init__(self, interactive=False, color_preserve=False, MIN_QUAD_AREA_RATIO=0.25, MAX_QUAD_ANGLE_RANGE=40): """ Args: interactive (boolean): If True, user can adjust screen contour before @@ -37,6 +37,7 @@ def __init__(self, interactive=False, MIN_QUAD_AREA_RATIO=0.25, MAX_QUAD_ANGLE_R of its interior angles exceeds MAX_QUAD_ANGLE_RANGE. Defaults to 40. """ self.interactive = interactive + self.color_preserve = color_preserve self.MIN_QUAD_AREA_RATIO = MIN_QUAD_AREA_RATIO self.MAX_QUAD_ANGLE_RANGE = MAX_QUAD_ANGLE_RANGE @@ -285,21 +286,24 @@ def scan(self, image_path): screenCnt = self.interactive_get_contour(screenCnt, rescaled_image) # apply the perspective transformation - warped = transform.four_point_transform(orig, screenCnt * ratio) + output = transform.four_point_transform(orig, screenCnt * ratio) #warped - # convert the warped image to grayscale - gray = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY) + if self.color_preserve == False: - # sharpen image - sharpen = cv2.GaussianBlur(gray, (0,0), 3) - sharpen = cv2.addWeighted(gray, 1.5, sharpen, -0.5, 0) + # convert the warped image to grayscale + gray = cv2.cvtColor(output, cv2.COLOR_BGR2GRAY) + + # sharpen image + sharpen = cv2.GaussianBlur(gray, (0,0), 3) + sharpen = cv2.addWeighted(gray, 1.5, sharpen, -0.5, 0) + + # apply adaptive threshold to get black and white effect + output = cv2.adaptiveThreshold(sharpen, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 15) #thresh - # apply adaptive threshold to get black and white effect - thresh = cv2.adaptiveThreshold(sharpen, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 15) # save the transformed image basename = os.path.basename(image_path) - cv2.imwrite(OUTPUT_DIR + '/' + basename, thresh) + cv2.imwrite(OUTPUT_DIR + '/' + basename, output) print("Proccessed " + basename) @@ -310,13 +314,17 @@ def scan(self, image_path): group.add_argument("--image", help="Path to single image to be scanned") ap.add_argument("-i", action='store_true', help = "Flag for manually verifying and/or setting document corners") + ap.add_argument("-c", action='store_true', + help = "Flag to preserve color on the cropped images") args = vars(ap.parse_args()) im_dir = args["images"] im_file_path = args["image"] interactive_mode = args["i"] + color_preserve_mode = args["c"] - scanner = DocScanner(interactive_mode) + scanner = DocScanner(interactive=interactive_mode, + color_preserve=color_preserve_mode) valid_formats = [".jpg", ".jpeg", ".jp2", ".png", ".bmp", ".tiff", ".tif"]