├── CS_GUI.py ├── Cropped_image ├── img_1.jpg ├── img_2.jpg ├── img_3.jpg └── img_4.jpg ├── LICENSE.txt ├── Processed_image ├── img_1.jpg ├── img_2.jpg ├── img_3.jpg ├── img_4.jpg └── z.jpg ├── README.md ├── Scanned_PDF └── Scanned_1.pdf ├── meta ├── arial.ttf ├── cs.ico └── pdf.png ├── requirements.txt ├── test1.jpeg ├── test2.png └── thumb.jpg /CS_GUI.py: -------------------------------------------------------------------------------- 1 | from PIL import ImageTk 2 | import PIL 3 | from PIL import ImageDraw,ImageFont 4 | import numpy as np 5 | from PIL import Image 6 | from tkinter import * 7 | import tkinter as tk 8 | import cv2 9 | import glob,os 10 | import time,datetime 11 | from urllib.request import urlopen 12 | from pathlib import Path 13 | from skimage.filters import threshold_local 14 | 15 | windo = Tk() 16 | windo.configure(background='white') 17 | windo.title("Document Scanner App") 18 | width = windo.winfo_screenwidth() 19 | height = windo.winfo_screenheight() 20 | windo.geometry(f'{width}x{height}') 21 | 22 | windo.iconbitmap('./meta/cs.ico') 23 | windo.resizable(0, 0) 24 | launch = False 25 | 26 | # Size for displaying Image 27 | w = 385;h = 535 28 | size = (w, h) 29 | 30 | def launch_mob_cam(): 31 | global cp2, crop_c, crop_images, pdf_c, pdf_b, scanned_imgs 32 | url = txt.get() 33 | crop_c = 0 34 | pdf_c = 0 35 | scanned_imgs = [] 36 | 37 | cp2 = tk.Button(windo, text='Capture Image', bg="spring green", fg="black", width=22, 38 | height=1, font=('times', 22, 'italic bold '),command = crop_image, activebackground='yellow') 39 | cp2.place(x=27, y=620) 40 | 41 | pdf_img = PIL.Image.open('./meta/pdf.png') 42 | pdf_img = pdf_img.resize((148, 52), PIL.Image.ANTIALIAS) 43 | sp_img1 = ImageTk.PhotoImage(pdf_img) 44 | 45 | pdf_b = Button(windo, borderwidth=0, command=pdf_gen, image=sp_img1, bg='white') 46 | pdf_b.pack() 47 | pdf_b.image = sp_img1 48 | pdf_b.place(x=430, y=80) 49 | 50 | try: 51 | if url == '': 52 | noti = tk.Label(windo, text='Check the URL!!', width=20, height=1, fg="white", bg="firebrick1", 53 | font=('times', 13, ' bold ')) 54 | noti.place(x=24, y=68) 55 | windo.after(2000, destroy_widget, noti) 56 | else: 57 | global display, imageFrame, cp1, img 58 | imageFrame = tk.Frame(windo) 59 | imageFrame.place(x=24, y=80) 60 | 61 | display = tk.Label(imageFrame) 62 | display.grid() 63 | 64 | cp1 = tk.Button(windo, text='Turn off', bg="spring green", fg="black", width=12, 65 | height=1, font=('times', 14, 'italic bold '), command=destroy_cam, 66 | activebackground='yellow') 67 | cp1.place(x=430, y=33) 68 | 69 | def show_frame(): 70 | global img 71 | img_resp = urlopen(url) 72 | img_arr = np.array(bytearray(img_resp.read()), dtype=np.uint8) 73 | frame = cv2.imdecode(img_arr, -1) 74 | frame = cv2.rotate(frame, cv2.cv2.ROTATE_90_CLOCKWISE) 75 | 76 | # frame = cv2.VideoCapture('new.mp4') 77 | # _,frame = frame.read() 78 | cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) 79 | rgb = cv2.cvtColor(cv2image, cv2.COLOR_RGBA2RGB) 80 | img = PIL.Image.fromarray(rgb) 81 | img1 = img.resize(size, PIL.Image.ANTIALIAS) 82 | imgtk = ImageTk.PhotoImage(image=img1) 83 | display.imgtk = imgtk 84 | display.configure(image=imgtk) 85 | display.after(10, show_frame) 86 | show_frame() 87 | except Exception as e: 88 | print(e) 89 | noti1 = tk.Label(windo, text='Connection Closed!!', width=20, height=1, fg="white", bg="firebrick1", 90 | font=('times', 13, ' bold ')) 91 | noti1.place(x=24, y=68) 92 | windo.after(2000, destroy_widget, noti1) 93 | imageFrame.destroy() 94 | display.destroy() 95 | cp1.destroy() 96 | cp2.destroy() 97 | 98 | def destroy_widget(widget): 99 | widget.destroy() 100 | 101 | def destroy_cam(): 102 | imageFrame.destroy() 103 | display.destroy() 104 | cp1.destroy() 105 | cp2.destroy() 106 | 107 | 108 | def crop_image(): 109 | global cropping, crop_c, launch, scanned_imgs 110 | launch = True 111 | repn = Path('Cropped_image') 112 | if repn.is_dir(): 113 | pass 114 | else: 115 | os.mkdir('Cropped_image') 116 | crop_c += 1 117 | 118 | img1 = img.copy() 119 | img1 = cv2.cvtColor(np.asarray(img1), cv2.COLOR_RGB2BGR) 120 | cn = './Cropped_image/img_' + str(crop_c) + '.jpg' 121 | cv2.imwrite(cn, img1) 122 | 123 | imlab2 = tk.Label(windo, text="Orignal: "+ cn[16:], width=22, height=1, fg="black", bg="yellow", 124 | font=('times', 15, ' bold ')) 125 | imlab2.place(x=430, y=140) 126 | 127 | imageFrame2 = tk.Frame(windo) 128 | imageFrame2.place(x=430, y=170) 129 | 130 | display2 = tk.Label(imageFrame2) 131 | display2.grid() 132 | 133 | cv2image = cv2.cvtColor(img1, cv2.COLOR_BGR2RGBA) 134 | rgb = cv2.cvtColor(cv2image, cv2.COLOR_RGBA2RGB) 135 | img2 = PIL.Image.fromarray(rgb) 136 | img2 = img2.resize((270, 480), PIL.Image.ANTIALIAS) 137 | imgtk = ImageTk.PhotoImage(image=img2) 138 | display2.imgtk = imgtk 139 | display2.configure(image=imgtk) 140 | windo.after(10000, destroy_widget, display2) 141 | windo.after(10000, destroy_widget, imageFrame2) 142 | windo.after(10000, destroy_widget, imlab2) 143 | 144 | imgr = cv2.imread(cn) 145 | imgr = cv2.cvtColor(imgr, cv2.COLOR_BGR2GRAY) 146 | t = threshold_local(imgr, 17, offset=15, method='gaussian') 147 | imgr = (imgr > t).astype('uint8') * 255 148 | repn = Path('Processed_image') 149 | if repn.is_dir(): 150 | pass 151 | else: 152 | os.mkdir('Processed_image') 153 | cn1 = './Processed_image/img_' + str(crop_c) + '.jpg' 154 | cv2.imwrite(cn1,imgr) 155 | scanned_imgs.append(cn1) 156 | print(scanned_imgs) 157 | imlab4 = tk.Label(windo, text="Scanned: "+ cn[16:], width=22, height=1, fg="white", bg="black", 158 | font=('times', 15, ' bold ')) 159 | imlab4.place(x=730, y=140) 160 | 161 | imageFrame4 = tk.Frame(windo) 162 | imageFrame4.place(x=730, y=170) 163 | 164 | display4 = tk.Label(imageFrame4) 165 | display4.grid() 166 | 167 | cv2image4 = cv2.cvtColor(imgr, cv2.COLOR_GRAY2RGBA) 168 | rgb4 = cv2.cvtColor(cv2image4, cv2.COLOR_RGBA2RGB) 169 | img4 = PIL.Image.fromarray(rgb4) 170 | img4 = img4.resize((270, 480), PIL.Image.ANTIALIAS) 171 | imgtk4 = ImageTk.PhotoImage(image=img4) 172 | display4.imgtk = imgtk4 173 | display4.configure(image=imgtk4) 174 | windo.after(10000, destroy_widget, display4) 175 | windo.after(10000, destroy_widget, imageFrame4) 176 | windo.after(10000, destroy_widget, imlab4) 177 | 178 | def pdf_gen(): 179 | global pdf_c, pdf_b, launch, scanned_imgs 180 | print(launch) 181 | if launch == False: 182 | noti = tk.Label(windo, text='Capture the Images first!!', width=20, height=1, fg="white", bg="firebrick1", 183 | font=('times', 13, ' bold ')) 184 | noti.place(x=24, y=68) 185 | windo.after(2000, destroy_widget, noti) 186 | destroy_cam() 187 | pdf_b.destroy() 188 | else: 189 | pdf_b.destroy() 190 | pdf_c+=1 191 | 192 | ## Generate folder for PDF 193 | repn = Path('Scanned_PDF') 194 | if repn.is_dir(): 195 | pass 196 | else: 197 | os.mkdir('Scanned_PDF') 198 | 199 | ## Create First Intro page 200 | img = PIL.Image.new('RGB', (100, 30), color=(255, 255, 255)) 201 | fnt = ImageFont.truetype('./meta/arial.ttf', 13) 202 | d = ImageDraw.Draw(img) 203 | d.text((5, 10), "Scanned PDF ", font=fnt,fill=(0, 0, 0)) 204 | img.save('./Processed_image/z.jpg') 205 | scanned_imgs.append('./Processed_image/z.jpg') 206 | ## Generate PDF- 207 | image_list = [] 208 | for image in scanned_imgs: 209 | img = PIL.Image.open(image) 210 | img = img.convert('RGB') 211 | image_list.append(img) 212 | image_list.pop(-1) 213 | ts = time.time() 214 | timeStam = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S') 215 | Hour, Minute, Second = timeStam.split(":") 216 | img.save('./Scanned_PDF/Scanned_'+str(pdf_c)+'_'+str(Hour)+'_'+str(Minute)+'_'+str(Second)+'.pdf',save_all=True, append_images=image_list) 217 | # img.save('./Scanned_PDF/Scanned_'+str(pdf_c)+'.pdf',save_all=True, append_images=image_list) 218 | noti = tk.Label(windo, text='PDF Generated!!', width=20, height=1, fg="black", bg="spring green", 219 | font=('times', 13, ' bold ')) 220 | noti.place(x=24, y=68) 221 | windo.after(2000, destroy_widget, noti) 222 | destroy_cam() 223 | 224 | lab = tk.Label(windo, text="Enter your URL", width=18, height=1, fg="white", bg="blue2", 225 | font=('times', 16, ' bold ')) 226 | lab.place(x=24, y=5) 227 | 228 | txt = tk.Entry(windo, borderwidth=4, width=34, bg="white", fg="black", font=('times', 16, ' bold ')) 229 | txt.place(x=24, y=35) 230 | txt.insert(0,'http://192.168.1.102:8080/shot.jpg') 231 | 232 | cp = tk.Button(windo, text='Turn on', bg="midnightblue", fg="white", width=12, 233 | height=1, font=('times', 14, 'italic bold '), command=launch_mob_cam, activebackground='yellow') 234 | cp.place(x=430, y=33) 235 | 236 | windo.mainloop() -------------------------------------------------------------------------------- /Cropped_image/img_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Cropped_image/img_1.jpg -------------------------------------------------------------------------------- /Cropped_image/img_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Cropped_image/img_2.jpg -------------------------------------------------------------------------------- /Cropped_image/img_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Cropped_image/img_3.jpg -------------------------------------------------------------------------------- /Cropped_image/img_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Cropped_image/img_4.jpg -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Kushal Bhavsar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Processed_image/img_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Processed_image/img_1.jpg -------------------------------------------------------------------------------- /Processed_image/img_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Processed_image/img_2.jpg -------------------------------------------------------------------------------- /Processed_image/img_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Processed_image/img_3.jpg -------------------------------------------------------------------------------- /Processed_image/img_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Processed_image/img_4.jpg -------------------------------------------------------------------------------- /Processed_image/z.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Processed_image/z.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Document📝 Scanner🖨️ using Python [![](https://img.shields.io/github/license/sourcerer-io/hall-of-fame.svg)](https://github.com/Spidy20/Document_Scanner_Python/blob/master/LICENSE.txt) 2 | 3 | [![forthebadge made-with-python](http://ForTheBadge.com/images/badges/made-with-python.svg)](https://www.python.org/) 4 | [![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/) 5 | 6 | ## [Follow us on Instagram for Machine Learning Guidelines & Path](https://www.instagram.com/machine_learning_hub.ai/) 7 | ## [Buy Python & ML projects for students at lower rate](https://www.instamojo.com/kushalbhavsar1820) 8 | ## [Watch Tutorial for this project](https://www.youtube.com/c/MachineLearningHub) 9 | 10 | ### Sourcerer 11 | 12 | 13 | 14 | 15 | ## [See the Demo of Project](https://youtu.be/YSIQWZintAQ) 16 | 17 | ## Usage:- 18 | 19 | - Clone my repository. 20 | - Open CMD in working directory. 21 | - Run `pip install -r requirements.txt` 22 | - Install [IPWebcam](https://play.google.com/store/apps/details?id=com.pas.webcam&hl=en_IN&gl=US) in your mobile. 23 | - Connect your Mobile & PC with same network 24 | - Run `CS_GUI.py`. 25 | - Write your IPV4 URL in the GUI Entry box. (URL will look like 'http://192.168.1.102:8080/shot.jpg'). This `shot.jpg` will send the continuous Camera frames to our UI. 26 | - Capture image with button, It will stored in `Cropped_image` folder. It will automatically scanned the image. 27 | - Scanned image will stored in `Processed_image` folder. 28 | - When you click on 'PDF' button, it will generate the PDF for your all scanned image, it will store PDFs in `Scanned_PDF` folder. 29 | - All the folders are auto-generated. 30 | 31 | ## Screenshots 32 | 33 | 34 | 35 | 36 | 37 | ## Just follow☝️ me and Star⭐ my repository 38 | 39 | # [Buy me a Coffee☕](https://www.buymeacoffee.com/spidy20) 40 | ## [Donate me on PayPal(It will inspire me to do more projects)](https://www.paypal.me/spidy1820) 41 | ## Donate me on GPAY:- kushalbhavsar58-1@okaxis 42 | -------------------------------------------------------------------------------- /Scanned_PDF/Scanned_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/Scanned_PDF/Scanned_1.pdf -------------------------------------------------------------------------------- /meta/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/meta/arial.ttf -------------------------------------------------------------------------------- /meta/cs.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/meta/cs.ico -------------------------------------------------------------------------------- /meta/pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/meta/pdf.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | scikit-image 2 | Pillow 3 | opencv-python -------------------------------------------------------------------------------- /test1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/test1.jpeg -------------------------------------------------------------------------------- /test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/test2.png -------------------------------------------------------------------------------- /thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spidy20/Document_Scanner_Python/f7a0df6d8dac946f3929365f940dffa26f931efb/thumb.jpg --------------------------------------------------------------------------------