-
Notifications
You must be signed in to change notification settings - Fork 0
/
Image_enhancement_project.txt
196 lines (165 loc) · 8.78 KB
/
Image_enhancement_project.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
from cv2 import imshow
import numpy as np
import cv2 as cv
from cv2 import threshold
from cv2 import imwrite
from numpy import uint, uint8
import numpy
class Enhance:
@staticmethod
def noise_reducer_cv(image,dilate_iteration=1,erode_iteration=1):
"""noise_reducer_cv(...)
reduces noise in a given image
image: image type ( opened using the OpenCV's - cv.imread - function ) contains potential noise that should be removed
dilate_iteration: integer representing how many interations when calling the - cv.dilate - function, 1 by default
erode_iteration: integer representing how many interations when calling the - cv.erode - function, 1 by default
"""
kernel= np.ones((1,1), np.uint8)
image=cv.dilate(image,kernel,iterations = dilate_iteration)
kernel= np.ones((1,1), np.uint8)
image=cv.erode(image,kernel,iterations = erode_iteration)
image=cv.morphologyEx(image,cv.MORPH_CLOSE,kernel)
image=cv.medianBlur(image, 3)
return (image)
@staticmethod
def thin_font_cv(image):
"""thin_font_cv(...)
uses the OpenCV's - cv.erode - function inorder to make text in an image thinner
image: image type ( opened using -cv.imread - function )
"""
import numpy as np
image=cv.bitwise_not(image) #inverting the image (swapping the colours)
kernel=np.ones((2,2), np.uint8) #managing the number of pixels to be eroded/dilated
image= cv.erode(image,kernel,iterations=1) #To make the font thicker (dilation) we just need to replace 'cv.erode' with 'cv.dilate'
image=cv.bitwise_not(image)
return (image)
@staticmethod
def dynamic_resize(image,static=0,height_portrait=8465,height_landscape=8465):
"""dynamic_resize(...)
does a complex resizing operation using OpenCV's - cv.resize - function
the concept is the following: inorder to apply certain filters on a given image,
the image must contain at least a - well chosen - number of pixels, because
if that number was too low, the outcome of the filter applied on to the image
would not be as expected, so we need to increase the number of pixels,
and that is by resizing it ( upscaling it ), at the same time we do not want the
image to get too big, so that it can be processed faster, and then we won't end
up having huge files.
the desired number of pixels is defined by the height of the image with the desired size
image: image type ( opened using -cv.imread - function )
static: positive integer, by default at 0 if we want dynamic_resize, different from 0 if want
to force all the images to be resize (upscaled), - static- would then present the resizing factor
height_portrait: the best height to compare with when having portrait images, by
default is 8465, for newspaper pages
height_landscape: the best height to compare with when having portrait images, by
default is 8465, for newspaper pages
"""
height=image.shape[0]
width=image.shape[1]
# case of dynamic resize
if not static:
if height>=width:
#the analysed image is in portrait
n=height_portrait//height
else:
#the analysed image is in landscape
n=height_landscape//height
# case of static resize
else:
n=static
# applying the resizing function
return cv.resize(image, (0, 0), fx=n , fy=n )
#function to convert a coloured image to a gray image
@staticmethod
def gray_image_cv(image):
"""gray_image_cv(...)
function to convert a coloured image to a gray image
image: image type ( opened using -cv.imread - function )
"""
return cv.cvtColor(image,cv.COLOR_BGR2GRAY)
@staticmethod
def thresholded_img(image,threshold_value=202):
"""thresholded_img(...)
thresholding function, the most important in this image processing class,
it transforms grayscale images into binary ones ( contains pixels with exactly two colors, in this case black and white)
which is very useful to increase OCR accuracy.
recommended (effective) on images with less noise
image: image type ( opened using -cv.imread - function )
threshold_value: integer: hex color value (between 0 and 255) that sparates pixels that will turn into white ones from those
that will turn into black ones, the selection of the value of - threshold_value - will affect how the result will look like
default value : 202 , for modification, values between 150 and 210 are recommended
example -> for text images the bigger the value of threshold_value the thicker and more filled the
caracter's will be, the opposite is true
"""
thres,mono_image=threshold(image,threshold_value,253,cv.THRESH_BINARY) #adjusting the threshold
return (thres,mono_image)
@staticmethod
def sharpened_img(image,sharpening_filter=np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]])):
"""sharpened_img(...)
adds a sharpening filter to the image
image: image type ( opened using -cv.imread - function )
we recommend using the default values for the rest of the parameters"""
sharp_img=cv.filter2D(image,-1,sharpening_filter)
return sharp_img
@staticmethod
def full_filter(image,resize=0,resize_to_original=False,gray=True,thresholding=True,denoising=True,eroding=True,sharpening=True):
"""full_filter(...)
a genral image enhancing method that packs up all the methods in the - Enhance - class
with parameters chosen by the developers
image: image type ( opened using -cv.imread- function)
resize_to_original: boolean that activates the resizing to original step
( if resize_to_original is True , the inverse of -resize- will be used as a factor of resizing )
resize: integer that replaces the -static- parameter in the resizing step
(type : help(dynamic_resize) for more details)
gray: boolean that activates the greyscaling step
thresholding: boolean that activates the thresholding step
denoising: boolean that activates the denoising step
eroding: boolean that activates the eroding step
sharpening: boolean that activates the sharpening step
"""
# adjust the number of pixels if needed
image=Enhance.dynamic_resize(image,resize)
# transform into grayscale
if gray:
image=Enhance.gray_image_cv(image)
# thresholding the image and turning it into a binary image
if thresholding:
thres,mono_image=Enhance.thresholded_img(image)
# denoising the image
if denoising:
image=Enhance.noise_reducer_cv(mono_image)
# thinning the caracters
if eroding:
image=Enhance.thin_font_cv(image)
# sharpening the result
if sharpening:
image=Enhance.sharpened_img(image)
#resizing back
if resize_to_original and resize:
image=Enhance.dynamic_resize(image,1/resize)
return image
cv.waitKey(0)
#####################################################################################################
# part 2: test
#Testing the class
#reading an example
image=cv.imread("paper.jpg")
#resizing
imwrite("paper_resized.jpg",Enhance.dynamic_resize(image,0.5))
#grayscaling
imwrite("paper_grayscale.jpg",Enhance.gray_image_cv(image))
#denoising
imwrite("paper_denoised.jpg",Enhance.noise_reducer_cv(image))
#sharpening
imwrite("paper_sharpened.jpg",Enhance.sharpened_img(image))
#eroding
imwrite("paper_thin_font.jpg",Enhance.thin_font_cv(image))
#thresholding
thesh,img=Enhance.thresholded_img(image)
imwrite("paper_thresholded.jpg",img)
#applying the full filter
imwrite("paper_filtered_default.jpg",Enhance.full_filter(image))
#applying the first custom filter
imwrite("paper_filtered_custom_1.jpg",Enhance.full_filter(image,3))
#applying the second custom filter
imwrite("paper_filtered_custom_2.jpg",Enhance.full_filter(image,3,True))
#help(Enhance.full_filter)