├── 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://github.com/Spidy20/Document_Scanner_Python/blob/master/LICENSE.txt)
2 |
3 | [](https://www.python.org/)
4 | [](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
--------------------------------------------------------------------------------