File size: 16,628 Bytes
598166e
 
 
 
 
 
 
 
 
 
6700e87
598166e
 
 
 
 
 
 
6700e87
598166e
6700e87
598166e
 
 
 
 
 
 
 
 
 
39a07f8
598166e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317aea0
598166e
 
 
6700e87
598166e
 
 
 
 
 
 
 
 
6700e87
598166e
6700e87
598166e
 
 
6700e87
 
598166e
 
6700e87
 
 
39a07f8
598166e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6700e87
 
 
598166e
 
6700e87
598166e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
import cv2
import numpy as np
import gradio as gr


def pirahansiah_threshold_method_find_threshold_values_2(grayImg):
    #http://www.jatit.org/volumes/Vol95No21/1Vol95No21.pdf
    #https://pdfs.semanticscholar.org/05b2/d39fce4e8a99897e95f8c75416f65a5a0acc.pdf
    assert grayImg is not None, "file could not be read, check with os.path.exists()"
    #img = cv2.GaussianBlur(self.grayImg, (3, 3), 0)       
    image = grayImg
    # Initialize an array to store the PSNR values for each threshold value
    psnr_values = np.zeros(256)        
    psnr_max=0
    th=0
    # Iterate over all possible threshold values with a step size of 5
    for t in range(0, 256, 5):
        # Threshold the image using the current threshold value
        _, binary = cv2.threshold(image, t, 255, cv2.THRESH_BINARY)            
        # Calculate the PSNR between the binary image and the original image
        psnr = cv2.PSNR(binary, image)            
        # Store the PSNR value
        psnr_values[t] = psnr
        if (psnr_max<psnr):
            psnr_max=psnr
            th=t        
    # Calculate the mean PSNR value
    mean_psnr = np.mean(psnr_values)
    th=int(th/mean_psnr)
    # Find the threshold values that satisfy the condition
    thresh = th #np.argwhere((mean_psnr / k1 < psnr_values) & (psnr_values < mean_psnr / k2)).flatten()
    #print(th)
    return thresh
def pirahansiah_threshold_method_find_threshold_values_1(grayImg):      
    #https://www.jatit.org/volumes/Vol57No2/4Vol57No2.pdf                      
    assert grayImg is not None, "file could not be read, check with os.path.exists()"
    gray = cv2.GaussianBlur(grayImg, (3, 3), 0)                
    max1=0
    max2=0     
    # Iterate over all possible threshold values
    for t in range(0, 256, 10):            
        # Threshold the image using the current threshold value            
        _, binary = cv2.threshold(gray, t, 255, cv2.THRESH_BINARY)          
        # Find the contours in the binary image            
        contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)                             
        if max1<=len(contours):
            max1=len(contours)
            max2=t                        
    threshold_values =max2 
    return threshold_values



path  = [['files/image_0.png'],['files/huggingface.png']]
inputs_thresh = [
gr.inputs.Image(type="filepath", label="Input Image"),
gr.inputs.Radio(label="Threshold Methods", 
                choices=[                         
                        "cv2.threshold(grayImg, 128, 255, cv2.THRESH_BINARY)"
                        ,"cv2.threshold(grayImg, 128, 255, cv2.THRESH_BINARY_INV)"
                        ,"cv2.threshold(grayImg, 128, 255, cv2.THRESH_TRUNC)"
                        ,"cv2.threshold(grayImg, 128, 255, cv2.THRESH_TOZERO)"
                        ,"cv2.threshold(grayImg, 128, 255, cv2.THRESH_TOZERO_INV)"
                        ,"cv2.adaptiveThreshold(grayImg, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)"
                        ,"cv2.threshold(grayImg, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU,)"
                        ,"Adapted from PirahanSiah Threshold Method I derivative demo"
                        ,"Inspired by PirahanSiah Threshold Method II derivative demo"
                        ,"Manual Threshold Value select by Slider"                 
                    ]),  
gr.components.Slider(label="Manual Threshold Value", value=125, minimum=10, maximum=255, step=5),    
]

outputs_thresh = [
gr.outputs.Image(type="numpy", label="Output Threshold Image") 

]

def process_image(input_image, radio_choice,slider_val):
    img = cv2.imread(input_image,0)  
    binaryImg=img.copy()    
    #print(radio_choice) 
    if radio_choice == "cv2.threshold(grayImg, 128, 255, cv2.THRESH_BINARY)":
            _, binaryImg=cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)
    elif radio_choice == "cv2.threshold(grayImg, 128, 255, cv2.THRESH_BINARY_INV)":
            _, binaryImg=cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV)
    elif radio_choice == "cv2.threshold(grayImg, 128, 255, cv2.THRESH_TRUNC)":
            _, binaryImg=cv2.threshold(img, 128, 255, cv2.THRESH_TRUNC)
    elif radio_choice == "cv2.threshold(grayImg, 128, 255, cv2.THRESH_TOZERO)":
            _, binaryImg=cv2.threshold(img, 128, 255, cv2.THRESH_TOZERO)
    elif radio_choice == "cv2.threshold(grayImg, 128, 255, cv2.THRESH_TOZERO_INV)":
            _, binaryImg=cv2.threshold(img, 128, 255, cv2.THRESH_TOZERO_INV)
    elif radio_choice == "cv2.adaptiveThreshold(grayImg, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)":
            binaryImg=cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
    elif radio_choice == "cv2.threshold(grayImg, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU,)":
           _, binaryImg=cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU,)
    elif radio_choice == "Adapted from PirahanSiah Threshold Method I derivative demo":
           threshval=pirahansiah_threshold_method_find_threshold_values_1(img)        
           _, binaryImg = cv2.threshold(img, threshval, 255, cv2.THRESH_BINARY)                         
    elif radio_choice == "Inspired by PirahanSiah Threshold Method II derivative demo":
           threshval=pirahansiah_threshold_method_find_threshold_values_2(img)        
           _, binaryImg = cv2.threshold(img, threshval, 255, cv2.THRESH_BINARY)    
    elif  radio_choice == "Manual Threshold Value select by Slider":
          _, binaryImg = cv2.threshold(img, slider_val, 255, cv2.THRESH_BINARY)            
    return binaryImg

def on_change(radio_choice,slider_val):
    # Update output
    outputs_thresh[0].update(process_image(
        inputs_thresh[0].value, 
        slider_val, 
        radio_choice)
    )


threshold_methods = gr.Interface(
    fn=process_image,
    inputs=inputs_thresh,
    outputs=outputs_thresh, 
    on_change=on_change,
    examples=path,
    title="Computer Vision and Deep Learning by Farshid PirahanSiah",
    live=True
    )

  



# class Thresholding:
#     def __init__(self, grayImg):
#         self.grayImg = grayImg

#     def manually_python(self):        
#         threshval = 128
#         binaryImg = np.where(self.grayImg < threshval, self.grayImg, 0) if threshval < 128 else np.where(self.grayImg > threshval, self.grayImg, 0)
#         return binaryImg
    
#     def manually(self,threshval):        
#         binaryImg = np.zeros_like(self.grayImg)
#         for i in range(self.grayImg.shape[0]): #height 
#             for j in range(self.grayImg.shape[1]): #width 
#                 if self.grayImg[i, j] < threshval:
#                     binaryImg[i, j] = 0 
#                 else:
#                     binaryImg[i, j] = 1 
#         return binaryImg    

#     def pirahansiah_threshold_method_find_threshold_values_2(self):
#         #http://www.jatit.org/volumes/Vol95No21/1Vol95No21.pdf
#         #https://pdfs.semanticscholar.org/05b2/d39fce4e8a99897e95f8c75416f65a5a0acc.pdf
#         assert self.grayImg is not None, "file could not be read, check with os.path.exists()"
#         #img = cv2.GaussianBlur(self.grayImg, (3, 3), 0)       
#         img = self.grayImg
#         # Initialize an array to store the PSNR values for each threshold value
#         psnr_values = np.zeros(256)        
#         psnr_max=0
#         th=0
#         # Iterate over all possible threshold values with a step size of 5
#         for t in range(0, 256, 5):
#             # Threshold the image using the current threshold value
#             _, binary = cv2.threshold(img, t, 255, cv2.THRESH_BINARY)            
#             # Calculate the PSNR between the binary image and the original image
#             psnr = cv2.PSNR(binary, img)            
#             # Store the PSNR value
#             psnr_values[t] = psnr
#             if (psnr_max<psnr):
#                 psnr_max=psnr
#                 th=t        
#         # Calculate the mean PSNR value
#         mean_psnr = np.mean(psnr_values)
#         th=int(th/mean_psnr)
#         # Find the threshold values that satisfy the condition
#         thresh = th #np.argwhere((mean_psnr / k1 < psnr_values) & (psnr_values < mean_psnr / k2)).flatten()
        
#         return thresh
#     def pirahansiah_threshold_method_find_threshold_values_1(self):      
#         #https://www.jatit.org/volumes/Vol57No2/4Vol57No2.pdf                      
#         assert self.grayImg is not None, "file could not be read, check with os.path.exists()"
#         gray = cv2.GaussianBlur(self.grayImg, (3, 3), 0)                
#         max1=0
#         max2=0     
#         # Iterate over all possible threshold values
#         for t in range(0, 256, 10):            
#             # Threshold the image using the current threshold value            
#             _, binary = cv2.threshold(gray, t, 255, cv2.THRESH_BINARY)          
#             # Find the contours in the binary image            
#             contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)                             
#             if max1<=len(contours):
#                 max1=len(contours)
#                 max2=t                        
#         threshold_values =max2 
#         return threshold_values


#     def opencv_th(self):
#         font = cv2.FONT_HERSHEY_SIMPLEX
#         fontScale = 2
#         color = (0, 0, 0)
#         colorInv = (255, 255, 255)
#         thickness = 2
#         # Set the position of the text
#         textX = 25
#         textY = 45
#         textSize, _ = cv2.getTextSize("Otsu Method   ", font, fontScale, thickness)
#         # Draw a white rectangle behind the text
        
#         # Apply different thresholding methods
#         _, binaryImg = cv2.threshold(self.grayImg, 128, 255, cv2.THRESH_BINARY)                
#         cv2.rectangle(binaryImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(binaryImg, 'Binary', (textX, textY), font, fontScale, color, thickness)
        
#         _, binaryInvImg = cv2.threshold(self.grayImg, 128, 255, cv2.THRESH_BINARY_INV)
#         cv2.rectangle(binaryInvImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(binaryInvImg, 'Binary Inv', (textX, textY), font, fontScale, color, thickness)
        
#         _, truncImg = cv2.threshold(self.grayImg, 128, 255, cv2.THRESH_TRUNC)
#         cv2.rectangle(truncImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(truncImg, 'Trunc', (textX, textY), font, fontScale, color, thickness)
        
#         _, toZeroImg = cv2.threshold(self.grayImg, 128, 255, cv2.THRESH_TOZERO)
#         cv2.rectangle(toZeroImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(toZeroImg, 'To Zero', (textX, textY), font, fontScale, color, thickness)
        
#         _, toZeroInvImg = cv2.threshold(self.grayImg, 128, 255, cv2.THRESH_TOZERO_INV)
#         cv2.rectangle(toZeroInvImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(toZeroInvImg, 'To Zero Inv', (textX, textY), font, fontScale, color, thickness)
        
#         adaptiveImg = cv2.adaptiveThreshold(self.grayImg, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
#         cv2.rectangle(adaptiveImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(adaptiveImg, 'Adaptive', (textX, textY), font, fontScale, color, thickness)
        
#         otsu_threshold, image_result = cv2.threshold(self.grayImg, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU,)        
#         cv2.rectangle(image_result, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(image_result, 'Otsu Threshold Method', (textX, textY), font, fontScale, color, thickness)

#         threshval=self.pirahansiah_threshold_method_find_threshold_values_1()        
#         th_img = th.manually(threshval)
#         binaryImg = th_img * 255
#         cv2.rectangle(binaryImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(binaryImg, 'PirahanSiah Threshold ', (textX, textY), font, fontScale, color, thickness)


#         cv2.rectangle(self.grayImg, (textX, textY - textSize[1]), (textX + textSize[0], textY), (255, 255, 255), -1)
#         cv2.putText(self.grayImg, 'Original', (textX, textY), font, fontScale, color, thickness)
#         # Concatenate the images into a grid with 3 rows and 3 columns
#         row1 = np.concatenate((self.grayImg, binaryImg, binaryInvImg), axis=1)
#         row2 = np.concatenate((truncImg, toZeroImg, toZeroInvImg), axis=1)                
#         row3 = np.concatenate((adaptiveImg, image_result, binaryImg), axis=1) # np.zeros_like(adaptiveImg)
#         concatenatedImg = np.concatenate((row1, row2, row3), axis=0)            
#         # Resize the concatenated image to fit the screen resolution
#         screenRes = (1920-200, 1080-200)
#         scaleWidth = screenRes[0] / concatenatedImg.shape[1]
#         scaleHeight = screenRes[1] / concatenatedImg.shape[0]
#         scale = min(scaleWidth, scaleHeight)
#         windowWidth = int(concatenatedImg.shape[1] * scale)
#         windowHeight = int(concatenatedImg.shape[0] * scale)
#         resizedImg = cv2.resize(concatenatedImg, (windowWidth, windowHeight))
#         # Display the resized image
#         cv2.imshow('Thresholded Images', resizedImg)
#         cv2.waitKey(0)
#         cv2.destroyAllWindows()


# if __name__ == "__main__":    
#     img = cv2.imread("opencv.png")    
#     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)    
#     th = Thresholding(gray)    
#     th.opencv_th()

    #threshval = 128
    # read an image
    # convert it to grayscale
    #threshval=th.pirahansiah_threshold_method_find_threshold_values_1()
    # threshval=th.pirahansiah_threshold_method_find_threshold_values_2()        
    # th_img = th.manually(threshval)
    # binaryImg = th_img * 255
    # cv2.imshow('image', binaryImg)
    # cv2.waitKey(100)


'''

cv::Mat binaryImg = threshval < 128 ? (grayImg < threshval) : (grayImg > threshval);

#thresholding #opencv #python



The PirahanSiah’s method for thresholding, described in the paper, uses a gray-scale histogram, 

thresholding range, and the Peak Signal-to-Noise Ratio (PSNR) to segment images and find the best 

threshold values to binarize the image. They argue that thresholding is an important problem in 

pattern recognition and use the PSNR quality measure to assess the similarities between the 

original and binarized image. They calculate PSNRs for every threshold value and use the 

difference between the PSNR of the previous threshold image and the new one to select the 

threshold value. They also describe a multi-threshold algorithm that applies multiple 

threshold values and computes the total number of blobs or objects in an image for each threshold.

The peak threshold values are those with the highest total number of blobs compared to their threshold neighbors.

In addition, their method uses thresholding on images suitable for OCR systems, LPR systems, etc.



The proposed adaptive threshold method, based on the Peak Signal-to-Noise Ratio (PSNR), 

has the potential to be applied in all domains, such as LPR and OCR. The proposed algorithm 

achieves competitive results in four databases, including Malaysian vehicle, standard, 

printed and handwritten images. The objective of this research was to develop a new single 

adaptive thresholding algorithm that works for a wide range of pattern recognition applications. 

The proposed method has been implemented in four different types of applications and compared 

with other methods. The results show that the proposed algorithm achieves the objective because 

it has obtained reasonable results in all four areas/domains.

https://www.jatit.org/volumes/Vol57No2/4Vol57No2.pdf 

http://www.jatit.org/volumes/Vol95No21/1Vol95No21.pdf

https://pdfs.semanticscholar.org/05b2/d39fce4e8a99897e95f8c75416f65a5a0acc.pdf

'''