joeee149/Image_processing_app
1
1import gradio as gr
2import cv2
3import numpy as np
4import matplotlib.pyplot as plt
5from scipy.ndimage import gaussian_filter
6from skimage.segmentation import clear_border
7from skimage import color
8from scipy.ndimage import generic_filter
9from skimage.util import random_noise
10# Define the custom HTML for the radio buttons
11custom_html1= """
12<div class="radio">
13 <input value="1" name="rating" type="radio" id="rating-1" />
14 <label title="1 stars" for="rating-1">
15 <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512">
16 <path
17 d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"
18 ></path>
19 </svg>
20 </label>
21
22 <input value="2" name="rating" type="radio" id="rating-2" />
23 <label title="2 stars" for="rating-2">
24 <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512">
25 <path
26 d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"
27 ></path>
28 </svg>
29 </label>
30
31 <input value="3" name="rating" type="radio" id="rating-3" />
32 <label title="3 stars" for="rating-3">
33 <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512">
34 <path
35 d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"
36 ></path>
37 </svg>
38 </label>
39
40 <input value="4" name="rating" type="radio" id="rating-4" />
41 <label title="4 stars" for="rating-4">
42 <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512">
43 <path
44 d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"
45 ></path>
46 </svg>
47 </label>
48
49 <input value="5" name="rating" type="radio" id="rating-5" />
50 <label title="5 star" for="rating-5">
51 <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512">
52 <path
53 d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"
54 ></path>
55 </svg>
56 </label>
57</div>
58"""
59custom_css1 = """
60.radio {
61 display: flex;
62 justify-content: center;
63 gap: 10px;
64}
65
66.radio > input {
67 position: absolute;
68 appearance: none;
69 opacity: 0; /* Hide the actual radio button input */
70 width: 0;
71 height: 0;
72}
73
74.radio > label {
75 cursor: pointer;
76 font-size: 30px;
77 position: relative;
78 display: inline-block;
79 transition: transform 0.3s ease;
80}
81
82.radio > label > svg {
83 fill: #666;
84 transition: fill 0.3s ease;
85}
86
87/* Ensuring the star icons stay stable */
88.radio > label:hover {
89 transform: scale(1); /* Prevent moving on hover */
90}
91
92.radio > label:hover > svg {
93 fill: #ff9e0b; /* Highlight the star color */
94 filter: drop-shadow(0 0 15px rgba(255, 158, 11, 0.9));
95 animation: shimmer 1s ease infinite alternate;
96}
97
98.radio > input:checked + label > svg {
99 fill: #ff9e0b;
100 filter: drop-shadow(0 0 15px rgba(255, 158, 11, 0.9));
101 animation: pulse 0.8s infinite alternate;
102}
103
104/* Prevents the stars from expanding and shifting */
105.radio > label::before,
106.radio > label::after {
107 content: "";
108 position: absolute;
109 width: 6px;
110 height: 6px;
111 background-color: #ff9e0b;
112 border-radius: 50%;
113 opacity: 0;
114 transform: scale(0);
115 transition:
116 transform 0.4s ease,
117 opacity 0.4s ease;
118 animation: particle-explosion 1s ease-out;
119}
120
121.radio > label:hover::before,
122.radio > label:hover::after {
123 opacity: 1;
124 transform: translateX(-50%) scale(1.5);
125}
126
127@keyframes pulse {
128 0% {
129 transform: scale(1);
130 }
131 100% {
132 transform: scale(1.1);
133 }
134}
135
136@keyframes particle-explosion {
137 0% {
138 opacity: 0;
139 transform: scale(0.5);
140 }
141 50% {
142 opacity: 1;
143 transform: scale(1.2);
144 }
145 100% {
146 opacity: 0;
147 transform: scale(0.5);
148 }
149}
150
151@keyframes shimmer {
152 0% {
153 filter: drop-shadow(0 0 10px rgba(255, 158, 11, 0.5));
154 }
155 100% {
156 filter: drop-shadow(0 0 20px rgba(255, 158, 11, 1));
157 }
158}
159
160.radio > input:checked + label:hover,
161.radio > input:checked + label:hover ~ label {
162 fill: #e58e09;
163}
164
165.radio > label:hover,
166.radio > label:hover ~ label {
167 fill: #ff9e0b;
168}
169
170.radio input:checked ~ label svg {
171 fill: #ff9e0b;
172}
173
174"""
175custom_css2="""
176@keyframes astronaut {
177 0% {
178 transform: rotate(0deg);
179 }
180
181 100% {
182 transform: rotate(360deg);
183 }
184}
185.astronaut {
186 width: 250px;
187 height: 300px;
188 position: absolute;
189 z-index: 11;
190 top: calc(50% - 150px);
191 left: calc(50% - 125px);
192 animation: astronaut 5s linear infinite;
193}
194
195.schoolbag {
196 width: 100px;
197 height: 150px;
198 position: absolute;
199 z-index: 1;
200 top: calc(50% - 75px);
201 left: calc(50% - 50px);
202 background-color:rgb(202, 202, 202);
203 border-radius: 50px 50px 0 0 / 30px 30px 0 0;
204}
205
206.b-head {
207 width: 97px;
208 height: 80px;
209 position: absolute;
210 z-index: 3;
211 background: -webkit-linear-gradient(left, #ff9e0b 0%, #ff9e0b 50%, #ff9e0b 50%, #ff9e0b 100%);
212 border-radius: 50%;
213 top: 34px;
214 left: calc(50% - 47.5px);
215}
216
217.b-head:after {
218 content: "";
219 width: 60px;
220 height: 50px;
221 position: absolute;
222 top: calc(50% - 25px);
223 left: calc(50% - 30px);
224 background: -webkit-linear-gradient(top, #15aece 0%, #15aece 50%, #0391bf 50%, #0391bf 100%);
225 border-radius: 15px;
226}
227
228.b-head:before {
229 content: "";
230 width: 12px;
231 height: 25px;
232 position: absolute;
233 top: calc(50% - 12.5px);
234 left: -4px;
235 background-color: #618095;
236 border-radius: 5px;
237 box-shadow: 92px 0px 0px #618095;
238}
239
240.body {
241 width: 85px;
242 height: 100px;
243 position: absolute;
244 z-index: 2;
245 background-color:rgb(196, 196, 196);
246 border-radius: 40px / 20px;
247 top: 105px;
248 left: calc(50% - 41px);
249 background: -webkit-linear-gradient(left, #ff9e0b 0%, #ff9e0b 50%, #ff9e0b 50%, #ff9e0b 100%);
250}
251
252.panel {
253 width: 60px;
254 height: 40px;
255 position: absolute;
256 top: 20px;
257 left: calc(50% - 30px);
258 background-color: #b7cceb;
259}
260
261.panel:before {
262 content: "";
263 width: 30px;
264 height: 5px;
265 position: absolute;
266 top: 9px;
267 left: 7px;
268 background-color: #ff9e0b;
269 box-shadow: 0px 9px 0px #ff9e0b, 0px 18px 0px #ff9e0b;
270}
271
272.panel:after {
273 content: "";
274 width: 8px;
275 height: 8px;
276 position: absolute;
277 top: 9px;
278 right: 7px;
279 background-color: #ff9e0b;
280 border-radius: 50%;
281 box-shadow: 0px 14px 0px 2px #ff9e0b;
282}
283
284.arm {
285 width: 80px;
286 height: 30px;
287 position: absolute;
288 top: 121px;
289 z-index: 2;
290}
291
292.arm-left {
293 left: 30px;
294 background-color: #ff9e0b;
295 border-radius: 0 0 0 39px;
296}
297
298.arm-right {
299 right: 30px;
300 background-color: #ff9e0b;
301 border-radius: 0 0 39px 0;
302}
303
304.arm-left:before,
305.arm-right:before {
306 content: "";
307 width: 30px;
308 height: 70px;
309 position: absolute;
310 top: -40px;
311}
312
313.arm-left:before {
314 border-radius: 50px 50px 0px 120px / 50px 50px 0 110px;
315 left: 0;
316 background-color: #ff9e0b;
317}
318
319.arm-right:before {
320 border-radius: 50px 50px 120px 0 / 50px 50px 110px 0;
321 right: 0;
322 background-color: #ff9e0b;
323}
324
325.arm-left:after,
326.arm-right:after {
327 content: "";
328 width: 30px;
329 height: 10px;
330 position: absolute;
331 top: -24px;
332}
333
334.arm-left:after {
335 background-color:rgb(195, 195, 195);
336 left: 0;
337}
338
339.arm-right:after {
340 right: 0;
341 background-color:rgb(195, 195, 195);
342}
343
344.leg {
345 width: 30px;
346 height: 40px;
347 position: absolute;
348 z-index: 2;
349 bottom: 70px;
350}
351
352.leg-left {
353 left: 76px;
354 background-color: #ff9e0b;
355 transform: rotate(20deg);
356}
357
358.leg-right {
359 right: 73px;
360 background-color: #ff9e0b;
361 transform: rotate(-20deg);
362}
363
364.leg-left:before,
365.leg-right:before {
366 content: "";
367 width: 50px;
368 height: 25px;
369 position: absolute;
370 bottom: -26px;
371}
372
373.leg-left:before {
374 left: -20px;
375 background-color: #ff9e0b;
376 border-radius: 30px 0 0 0;
377 border-bottom: 10px solidrgb(197, 197, 197);
378}
379
380.leg-right:before {
381 right: -20px;
382 background-color: #ff9e0b;
383 border-radius: 0 30px 0 0;
384 border-bottom: 10px solidrgb(197, 197, 197);
385}
386"""
387custom_html2="""
388 <div data-js="astro" class="astronaut">
389 <div class="b-head"></div>
390 <div class="arm arm-left"></div>
391 <div class="arm arm-right"></div>
392 <div class="body">
393 <div class="panel"></div>
394 </div>
395 <div class="leg leg-left"></div>
396 <div class="leg leg-right"></div>
397 <div class="schoolbag"></div>
398 </div>
399"""
400custom_css3="""
401b-button {
402 color: white;
403 text-decoration: none;
404 font-size: 25px;
405 border: none;
406 background: none;
407 font-weight: 600;
408 font-family: 'Poppins', sans-serif;
409}
410
411b-button::before {
412 margin-left: auto;
413}
414
415b-button::after, b-button::before {
416 content: '';
417 width: 0%;
418 height: 2px;
419 background: #ff9e0b;
420 display: block;
421 transition: 0.5s;
422}
423
424b-button:hover::after, b-button:hover::before {
425 width: 100%;
426}
427"""
428custom_html3="""
429<b-button>
430
431
432
433 About US
434</b-button>
435"""
436
437js = """
438function createGradioAnimation() {
439 var container = document.createElement('div');
440 container.id = 'gradio-animation';
441 container.style.fontSize = '3em'; // Increased font size
442 container.style.fontWeight = 'bold';
443 container.style.textAlign = 'center';
444 container.style.marginBottom = '20px';
445
446 var text = 'Welcome to our image processing project!!👋💥';
447 for (var i = 0; i < text.length; i++) {
448 (function(i){
449 setTimeout(function(){
450 var letter = document.createElement('span');
451 letter.style.opacity = '0';
452 letter.style.transition = 'opacity 0.3s';
453 letter.innerText = text[i];
454
455 // Set color to orange
456 letter.style.color = 'orange';
457
458 container.appendChild(letter);
459
460 setTimeout(function() {
461 letter.style.opacity = '1';
462 }, 50);
463 }, i * 150); // Faster letter appearance
464 })(i);
465 }
466
467 var gradioContainer = document.querySelector('.gradio-container');
468 gradioContainer.insertBefore(container, gradioContainer.firstChild);
469
470 return 'Animation created';
471}
472"""
473combined_css=custom_css1+custom_css2+custom_css3
474# Image Processing Functions
475def power_law_transform(image, gamma,grayscale):
476 if grayscale:
477 image=cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
478 normalized_img = image / 255.0
479 transformed_img = np.power(normalized_img, gamma)
480 transformed_img = np.uint8(transformed_img * 255)
481 return transformed_img
482
483def histogram_equalization(image,grayscale):
484 if grayscale:
485 gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
486 return cv2.equalizeHist(gray_image)
487 # Histogram equalization on the Value channel only affects brightness and contrast, leaving the colors (Hue) unchanged
488 hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
489 # accesses the Value channel (brightness) using hsv_image[:, :, 2]
490 # equalizeHist(hsv_image[:, :, 2]) enhances the brightness (contrast) of the Value channel
491 hsv_image[:, :, 2] = cv2.equalizeHist(hsv_image[:, :, 2])
492 equalized_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)
493 return equalized_image
494def Gray_Level_Slicing(image, grayscale, min_val, max_val):
495 if grayscale:
496 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
497
498 # Convert min_val and max_val to integers (in case they are passed as strings)
499 min_val = int(min_val)
500 max_val = int(max_val)
501
502 # Create the output image, where only values between min_val and max_val are set to 255
503 output_image = np.zeros_like(image)
504 output_image[(image >= min_val) & (image <= max_val)] = 255
505
506 return output_image
507
508def linear_negative_transformation(image, grayscale):
509 # Convert to grayscale if the flag is set
510 if grayscale:
511 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
512
513 # Ensure the image is in uint8 format (0-255 range)
514 if image.dtype != np.uint8:
515 image = np.uint8(image)
516
517 # Get the maximum intensity value from the image
518 max_val = 255 # For 8-bit images, the max value is 255
519
520 # Apply the linear negative transformation
521 transformed_image = max_val - image
522
523 return transformed_image
524def log_transformation(image,grayscale):
525 if grayscale:
526 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
527 max_val = np.max(image)
528 # The value of ‘c’ is chosen such that we get the maximum output value corresponding to the bit size used
529 C = 255 / np.log(1 + max_val)
530 # Converts the image data type to float32 to allow for fractional calculations since logarithmic operations
531 transformed_image = C * np.log(1 + image.astype(np.float32))
532 transformed_image = np.uint8(transformed_image)
533 return transformed_image
534
535def piecewise_linear_transformation(image,grayscale):
536 if grayscale:
537 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
538 # Breakpoints: Divide the pixel intensity range into sections, 0-99: Dark regions, 100-199: Mid-tones, 200-255: Bright regions
539 #Slopes: Control how much to stretch or compress the intensity in each section, 0.5: Compress dark pixels (make them closer together),
540 #1.5: Stretch mid-tones (increase contrast), 0.8: Slightly compress bright pixels
541 #Intercepts: Add or subtract intensity values to shift brightness in each section, 0: No shift for dark regions, -50: Darken mid-tones slightly
542 #100: Brighten bright regions
543 breakpoints = [0, 100, 200, 256]
544 slopes = [0.5, 1.5, 0.8]
545 intercepts = [0, -50, 100]
546 transformed_image = np.zeros_like(image, dtype=np.float32)
547 for i in range(len(breakpoints) - 1):
548 mask = (image >= breakpoints[i]) & (image < breakpoints[i + 1])
549 # s=slopes[i]⋅r+intercepts[i]
550 transformed_image[mask] = slopes[i] * image[mask] + intercepts[i]
551 transformed_image = np.clip(transformed_image, 0, 255)
552 return np.uint8(transformed_image)
553
554def bit_plane_slicing(image):
555 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
556 bit_planes = []
557 for i in range(8):
558 bit_plane = (image >> i) & 1 # Extract bit-plane i
559 bit_plane = bit_plane * 255 # Scale it to 0-255
560 bit_planes.append(bit_plane)
561
562 return bit_planes
563
564def generate_bit_plane_plot(image):
565 bit_planes = bit_plane_slicing(image)
566
567 # Create the plot using matplotlib
568 plt.figure(figsize=(10, 8))
569 plt.subplot(3, 3, 1)
570 plt.imshow(image, cmap='gray')
571 plt.title('Original Image')
572 plt.axis('off')
573
574 for i in range(8):
575 plt.subplot(3, 3, i + 2)
576 plt.imshow(bit_planes[i], cmap='gray')
577 plt.title(f'Bit-Plane {i}')
578 plt.axis('off')
579
580 plt.tight_layout()
581
582 # Save the plot to a temporary file
583 plot_filename = "Image Project/bit_plane_plot.png"
584 plt.savefig(plot_filename)
585 plt.close()
586
587 return plot_filename
588def sharp_thresholding(image, grayscale, threshold):
589 if grayscale:
590 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
591
592 # Convert threshold value to integer
593 threshold = int(threshold)
594
595 threshold_value_computed, sharp_thresholded_image = cv2.threshold(image, threshold, 255, cv2.THRESH_BINARY)
596 return sharp_thresholded_image
597
598def soft_thresholding(image, grayscale, threshold):
599 if grayscale:
600 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
601
602 # Convert threshold value to float
603 threshold = float(threshold)
604
605 # Apply soft thresholding
606 transformed_image = np.copy(image).astype(np.float32)
607 transformed_image[transformed_image > threshold] -= threshold
608 transformed_image[transformed_image <= threshold] = 0
609
610 # Ensure the pixel values are in the valid range (0-255) after thresholding
611 transformed_image = np.clip(transformed_image, 0, 255)
612
613 # Convert the image back to uint8 format
614 transformed_image = transformed_image.astype(np.uint8)
615
616 return transformed_image
617
618def diffenece_theresholds(image,grayscale,threshold_value):
619 difference = np.abs(sharp_thresholding(image,grayscale,threshold_value) - soft_thresholding(image,grayscale,threshold_value))
620 return difference
621
622
623def thresholding(image, grayscale, threshold_type, threshold_value):
624
625 if threshold_type == "Sharp":
626 return sharp_thresholding(image, grayscale, threshold_value)
627 elif threshold_type == "Soft":
628 return soft_thresholding(image, grayscale, threshold_value)
629 elif threshold_type =="Difference":
630 return diffenece_theresholds(image, grayscale, threshold_value)
631
632 else:
633 raise gr.Error("Please select a Threshold type")
634def arithmetic_operations(image1, image2, operation_type):
635 # Resize image2 to match image1's dimensions if necessary
636 if image2 is not None:
637 image2_resized = cv2.resize(image2, (image1.shape[1], image1.shape[0]))
638 else:
639 image2_resized = None
640
641 # Perform the selected arithmetic operation
642 if operation_type == "Addition":
643 result_image = cv2.add(image1, image2_resized)
644 elif operation_type == "Subtraction":
645 result_image = cv2.subtract(image1, image2_resized)
646 elif operation_type == "Multiplication":
647 result_image = cv2.multiply(image1, image2_resized, scale=1/255)
648 elif operation_type == "Division":
649 result_image = cv2.divide(image1, image2_resized, scale=255)
650 else:
651 raise gr.Error("Please select an operation type")
652
653 return result_image
654
655def Generic_filter(image,grayscale):
656 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
657 filtered_image = generic_filter(image, np.std, size=(3,3))
658 if grayscale:
659 return filtered_image
660 RGB=cv2.cvtColor(filtered_image,cv2.COLOR_GRAY2RGB)
661 return filtered_image
662def Gaussian_filter(image,Sigma,grayscale):
663 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
664 smoothed_image = gaussian_filter(image, sigma=Sigma)
665 if grayscale:
666 return smoothed_image
667 RGB=cv2.cvtColor(smoothed_image,cv2.COLOR_GRAY2RGB)
668 return RGB
669
670def salt_and_pepper_noise(image,grayscale,noise_type):
671 if grayscale:
672 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
673 salt_paper = random_noise(image, mode='s&p')
674 salt_paper = np.array(255 * salt_paper, dtype='uint8')
675 if noise_type =="Salt & Pepper":
676 return salt_paper
677 if noise_type =="Denoised Image":
678 denoised_image = cv2.medianBlur(salt_paper, 3)
679 return denoised_image
680 else:
681 raise gr.Error("Please select a noise type")
682
683def add_nosie(image,grayscale,noise_type,reduction,reduction_type):
684 if grayscale:
685 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
686 if noise_type == "additive":
687 gauss = np.random.normal(0, 25, image.shape).astype(np.float32)
688 noisy = cv2.add(image.astype(np.float32), gauss)
689 if reduction:
690 return noise_reduction(image,grayscale,reduction_type)
691 return np.clip(noisy, 0, 255).astype(np.uint8)
692 elif noise_type == "multiplicative":
693 speckle = np.random.normal(0, 0.2, image.shape).astype(np.float32)
694 noisy = image.astype(np.float32) * (1 + speckle)
695 if reduction:
696 return noise_reduction(image,grayscale,reduction_type)
697 return np.clip(noisy, 0, 255).astype(np.uint8)
698 elif noise_type == "impulse":
699 noisy = image.copy()
700 prob = 0.05
701 random_matrix = np.random.rand(*image.shape)
702 noisy[random_matrix < (prob / 2)] = 0
703 noisy[random_matrix > 1 - (prob / 2)] = 255
704 if reduction:
705 return noise_reduction(image,grayscale,reduction_type)
706 return noisy
707 elif noise_type == "quantization":
708 levels = 16
709 factor = 256 // levels
710 noisy = (image // factor) * factor
711 if reduction:
712 return noise_reduction(image,grayscale,reduction_type)
713 return noisy
714 else:
715 raise gr.Error("Please select a noise type")
716
717def noise_reduction(image,grayscale,reduction_type):
718 if reduction_type == "Gaussian":
719 return cv2.GaussianBlur(image, (5, 5), sigmaX=1)
720 elif reduction_type == "Median":
721 return cv2.medianBlur(image, 5)
722 elif reduction_type == "Mean":
723 kernel = np.ones((5, 5), np.float32) / 25
724 return cv2.filter2D(image, -1, kernel)
725 else:
726 raise gr.Error("Please select a noise reduction type")
727
728def progressive_image_transmission(image, grayscale,see_difference, output_path=None):
729 if output_path is None:
730 output_path = "progressive_image.jpg"
731 if grayscale:
732 image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
733 is_written = cv2.imwrite(output_path, image, [int(cv2.IMWRITE_JPEG_PROGRESSIVE), 1])
734 if grayscale:
735 progressive_image = cv2.imread(output_path, cv2.IMREAD_GRAYSCALE)
736 else:
737 progressive_image = cv2.imread(output_path)
738 if see_difference:
739 difference = cv2.absdiff(image, progressive_image)
740 plt.imshow(difference, cmap="hot")
741 plt.axis('off')
742 plt.tight_layout()
743 cmap_output_path = "cmap_difference.png"
744 plt.savefig(cmap_output_path, bbox_inches='tight', pad_inches=0)
745 plt.close()
746 color_diff = cv2.imread(cmap_output_path)
747 return color_diff
748 return progressive_image
749import cv2
750
751def lossy_compression(image, grayscale, lossy_quality, see_difference2):
752 lossy_quality = int(lossy_quality)
753 if lossy_quality < 0 or lossy_quality > 100:
754 return image
755 original_image = image.copy()
756 if grayscale:
757 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
758 lossy_encode_param = [cv2.IMWRITE_JPEG_QUALITY, lossy_quality]
759 result, lossy_compressed_image = cv2.imencode('.jpg', image, lossy_encode_param)
760 lossy_compressed_image = cv2.imdecode(lossy_compressed_image, 1)
761 if grayscale:
762 original_image = cv2.cvtColor(original_image, cv2.COLOR_RGB2GRAY)
763 if original_image.shape != lossy_compressed_image.shape:
764 lossy_compressed_image = cv2.resize(lossy_compressed_image, (original_image.shape[1], original_image.shape[0]))
765 if len(original_image.shape) == 2:
766 if len(lossy_compressed_image.shape) == 3:
767 lossy_compressed_image = cv2.cvtColor(lossy_compressed_image, cv2.COLOR_BGR2GRAY)
768 if see_difference2:
769 difference = cv2.absdiff(original_image, lossy_compressed_image)
770 plt.imshow(difference, cmap="hot")
771 plt.axis('off')
772 plt.tight_layout()
773 cmap_output_path = "cmap_difference.png"
774 plt.savefig(cmap_output_path, bbox_inches='tight', pad_inches=0)
775 plt.close()
776 color_diff = cv2.imread(cmap_output_path)
777 return color_diff
778 return lossy_compressed_image
779
780def lossless_compression(image, grayscale, level, see_difference3):
781 if grayscale:
782 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
783 result, lossless_compressed_image = cv2.imencode('.png', image, [cv2.IMWRITE_PNG_COMPRESSION, level])
784 lossless_compressed_image = cv2.imdecode(lossless_compressed_image, cv2.IMREAD_UNCHANGED)
785 if grayscale and len(lossless_compressed_image.shape) == 3:
786 lossless_compressed_image = cv2.cvtColor(lossless_compressed_image, cv2.COLOR_BGR2GRAY)
787 if see_difference3:
788 if image.shape == lossless_compressed_image.shape:
789 difference = cv2.absdiff(image, lossless_compressed_image)
790 plt.imshow(difference, cmap="hot")
791 plt.axis('off')
792 plt.tight_layout()
793 cmap_output_path = "cmap_difference.png"
794 plt.savefig(cmap_output_path, bbox_inches='tight', pad_inches=0)
795 plt.close()
796 color_diff = cv2.imread(cmap_output_path)
797 return color_diff
798 return lossless_compressed_image
799
800import cv2
801import numpy as np
802
803def gray_level_discontinuity_point_detection(image, grayscale=True, threshold_factor=2.0):
804 if grayscale:
805 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
806 mask = np.array([[-1, -1, -1],
807 [-1, 8, -1],
808 [-1, -1, -1]], dtype=np.float32)
809 filtered_image = cv2.filter2D(image, -1, mask)
810 threshold_value = np.std(image) * threshold_factor
811 isolated_points = np.zeros_like(image)
812 isolated_points[np.abs(filtered_image) > threshold_value] = 255
813
814 return isolated_points
815
816import cv2
817import numpy as np
818
819def gray_level_discontinuity_line_detection(image, grayscale=True, mask_type="Horizontal", threshold_value=100):
820 # Convert to grayscale if necessary
821 if grayscale:
822 image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
823
824 # Define masks for horizontal, vertical, and diagonal line detection
825 horizontal_mask = np.array([[-1, -1, -1],
826 [ 2, 2, 2],
827 [-1, -1, -1]], dtype=np.float32)
828
829 vertical_mask = np.array([[-1, 2, -1],
830 [-1, 2, -1],
831 [-1, 2, -1]], dtype=np.float32)
832
833 diagonal_mask = np.array([[ 2, -1, -1],
834 [-1, 2, -1],
835 [-1, -1, 2]], dtype=np.float32)
836
837 # Apply the chosen mask
838 if mask_type == "Horizontal":
839 filtered_image = cv2.filter2D(image, -1, horizontal_mask)
840 elif mask_type == "Vertical":
841 filtered_image = cv2.filter2D(image, -1, vertical_mask)
842 elif mask_type == "Diagonal":
843 filtered_image = cv2.filter2D(image, -1, diagonal_mask)
844 else:
845 raise gr.Error("Please select a mask type")
846
847 # Apply thresholding to detect lines
848 detected_lines = np.zeros_like(image)
849 detected_lines[np.abs(filtered_image) > threshold_value] = 255
850
851 return detected_lines
852
853def gray_level_discontinuity_edge_detection(image,dilation):
854 low_threshold = 100
855 high_threshold = 200
856 edges = cv2.Canny(image, low_threshold, high_threshold)
857 kernel = np.ones((3, 3), np.uint8)
858 if dilation:
859 dilated_edges = cv2.dilate(edges, kernel, iterations=1)
860 return dilated_edges
861 else:
862 return edges
863
864def watershed_segmentation(image):
865 cells = image[:, :, 0] # Extract the first channel
866
867 # Step 2: Otsu Thresholding
868 ret1, thresh = cv2.threshold(cells, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
869
870 # Step 3: Morphological Opening
871 kernel = np.ones((3, 3), np.uint8)
872 opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
873
874 # Step 4: Remove Edge-Touching Grains
875 opening_cleared = clear_border(opening)
876
877 # Step 5: Identify Background
878 sure_bg = cv2.dilate(opening_cleared, kernel, iterations=1)
879
880 # Step 6: Identify Foreground Area using Distance Transform
881 dist_transform = cv2.distanceTransform(opening_cleared, cv2.DIST_L2, 5)
882 result, sure_fg = cv2.threshold(dist_transform, 0.2 * dist_transform.max(), 255, 0)
883 sure_fg = np.uint8(sure_fg)
884
885 # Step 7: Find Unknown Region
886 unknown = cv2.subtract(sure_bg, sure_fg)
887
888 # Step 8: Label Markers for Watershed
889 result, markers = cv2.connectedComponents(sure_fg)
890 markers = markers + 10
891 markers[unknown == 255] = 0
892
893 # Step 9: Apply Watershed Algorithm
894 markers = cv2.watershed(image, markers)
895 watershed_result = image.copy()
896 watershed_result[markers == -1] = [0, 0, 255] # Mark boundaries
897
898 # Step 10: Overlay on Original Image and Create Colored Grains
899 image[markers == -1] = [255, 255, 255]
900 img2 = color.label2rgb(markers, bg_label=0)
901 # Enhancement functions based on the dropdown option
902 plt.figure(figsize=(15, 15))
903
904 # Subplot 1: Original Cells
905 plt.subplot(4, 3, 1)
906 plt.imshow(cells, cmap='gray')
907 plt.title("Original Cells")
908 plt.axis('off')
909
910 # Subplot 2: Otsu Threshold
911 plt.subplot(4, 3, 2)
912 plt.imshow(thresh, cmap='gray')
913 plt.title("Otsu Threshold")
914 plt.axis('off')
915
916 # Subplot 3: Morphological Opening
917 plt.subplot(4, 3, 3)
918 plt.imshow(opening, cmap='gray')
919 plt.title("Morphological Opening")
920 plt.axis('off')
921
922 # Subplot 4: Cleared Border
923 plt.subplot(4, 3, 4)
924 plt.imshow(opening_cleared, cmap='gray')
925 plt.title("Cleared Border")
926 plt.axis('off')
927
928 # Subplot 5: Sure Background
929 plt.subplot(4, 3, 5)
930 plt.imshow(sure_bg, cmap='gray')
931 plt.title("Sure Background")
932 plt.axis('off')
933
934 # Subplot 6: Distance Transform
935 plt.subplot(4, 3, 6)
936 plt.imshow(dist_transform, cmap='gray')
937 plt.title("Distance Transform")
938 plt.axis('off')
939
940 # Subplot 7: Sure Foreground
941 plt.subplot(4, 3, 7)
942 plt.imshow(sure_fg, cmap='gray')
943 plt.title("Sure Foreground")
944 plt.axis('off')
945
946 # Subplot 8: Unknown Region
947 plt.subplot(4, 3, 8)
948 plt.imshow(unknown, cmap='gray')
949 plt.title("Unknown Region")
950 plt.axis('off')
951
952 # Subplot 9: Markers Labeled
953 plt.subplot(4, 3, 9)
954 plt.imshow(markers, cmap='gray')
955 plt.title("Markers Labeled")
956 plt.axis('off')
957
958 # Subplot 10: Watershed Boundaries
959 plt.subplot(4, 3, 10)
960 plt.imshow(watershed_result)
961 plt.title("Watershed Boundaries")
962 plt.axis('off')
963
964 # Subplot 11: Overlay on Original
965 plt.subplot(4, 3, 11)
966 plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
967 plt.title("Overlay on Original")
968 plt.axis('off')
969
970 # Subplot 12: Colored Grains
971 plt.subplot(4, 3, 12)
972 plt.imshow(img2)
973 plt.title("Colored Grains")
974 plt.axis('off')
975
976 plt.tight_layout()
977 plot_filename = "Image Project/watershed_plot.png"
978 plt.savefig(plot_filename)
979 plt.close()
980
981 return plot_filename
982
983def thresholding_segmentation(image,display):
984 image=cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
985 hist = cv2.calcHist([image], [0], None, [256], [0, 256])
986 ret, otsu_thresholded_img = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
987 otsu_thresholded_hist = cv2.calcHist([otsu_thresholded_img], [0], None, [256], [0, 256])
988 if display == "Image":
989 return otsu_thresholded_img
990 if display == "Original Image Histogram":
991 plt.plot(hist, color='blue')
992 plt.title("Histogram of Original Image")
993 plt.xlabel("Pixel Intensity")
994 plt.ylabel("Frequency")
995 plt.tight_layout()
996 plot_filename = "Image Project/original_hist_plot.png"
997 plt.savefig(plot_filename)
998 plt.close()
999 return plot_filename
1000 if display == "Thresholded Histogram":
1001 plt.plot(otsu_thresholded_hist, color='green')
1002 plt.title("Histogram of Thresholded Image")
1003 plt.xlabel("Pixel Intensity")
1004 plt.ylabel("Frequency")
1005 plt.tight_layout()
1006 plot_filename = "Image Project/thresh_hist_plot.png"
1007 plt.savefig(plot_filename)
1008 plt.close()
1009 return plot_filename
1010 else:
1011 raise gr.Error("Please select a Threshold type")
1012
1013def multilevel_thresholding(image, hist=False):
1014 image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
1015 T1 = 80
1016 T2 = 160
1017 thresholded_img = np.zeros_like(image_gray, dtype=np.uint8)
1018 thresholded_img[image_gray <= T1] = 0
1019 thresholded_img[(image_gray > T1) & (image_gray <= T2)] = 127
1020 thresholded_img[image_gray > T2] = 255
1021 if hist:
1022 plt.figure()
1023 plt.hist(image_gray.ravel(), bins=256, range=(0, 256), color='blue')
1024 plt.title("Histogram of Grayscale Image")
1025 plt.xlabel("Pixel Intensity")
1026 plt.ylabel("Frequency")
1027 plot_filename = "hist_plot.png"
1028 plt.savefig(plot_filename)
1029 plt.close()
1030 return plot_filename
1031 else:
1032 return thresholded_img
1033def colored_thresholding(image, color, hist):
1034 threshold_value = 100
1035 r, g, b = cv2.split(image)
1036
1037 if color == "Red":
1038 if hist:
1039 r_hist = cv2.calcHist([r], [0], None, [256], [0, 256])
1040 plt.plot(r_hist, color='red')
1041 plt.title('Histogram of Red Channel')
1042 plt.xlim([0, 256])
1043 plt.tight_layout()
1044 plot_filename = "hist_Red.png"
1045 plt.savefig(plot_filename)
1046 plt.close()
1047 return plot_filename
1048 r_thresh = cv2.inRange(r, threshold_value, 255)
1049 red_img = cv2.merge([r_thresh, g*0, b*0])
1050 return red_img
1051
1052 elif color == "Green":
1053 if hist:
1054 g_hist = cv2.calcHist([g], [0], None, [256], [0, 256])
1055 plt.plot(g_hist, color='green')
1056 plt.title('Histogram of Green Channel')
1057 plt.xlim([0, 256])
1058 plt.tight_layout()
1059 plot_filename = "hist_Green.png"
1060 plt.savefig(plot_filename)
1061 plt.close()
1062 return plot_filename
1063 g_thresh = cv2.inRange(g, threshold_value, 255)
1064 green_img = cv2.merge([r*0, g_thresh, b*0])
1065 return green_img
1066 elif color == "Blue":
1067 if hist:
1068 b_hist = cv2.calcHist([b], [0], None, [256], [0, 256])
1069 plt.plot(b_hist, color='blue')
1070 plt.title('Histogram of Blue Channel')
1071 plt.xlim([0, 256])
1072 plt.tight_layout()
1073 plot_filename = "hist_Blue.png"
1074 plt.savefig(plot_filename)
1075 plt.close()
1076 return plot_filename
1077 b_thresh = cv2.inRange(b, threshold_value, 255)
1078 blue_img = cv2.merge([r*0, g*0, b_thresh])
1079 return blue_img
1080 elif color == "Combined":
1081 if hist:
1082 r_hist = cv2.calcHist([r], [0], None, [256], [0, 256])
1083 g_hist = cv2.calcHist([g], [0], None, [256], [0, 256])
1084 b_hist = cv2.calcHist([b], [0], None, [256], [0, 256])
1085 plt.plot(r_hist, color='red', label='Red')
1086 plt.plot(g_hist, color='green', label='Green')
1087 plt.plot(b_hist, color='blue', label='Blue')
1088 plt.title('Combined RGB Histogram')
1089 plt.xlim([0, 256])
1090 plt.legend()
1091 plt.tight_layout()
1092 plot_filename = "hist_Combined.png"
1093 plt.savefig(plot_filename)
1094 plt.close()
1095 return plot_filename
1096 r_thresh = cv2.inRange(r, threshold_value, 255)
1097 g_thresh = cv2.inRange(g, threshold_value, 255)
1098 b_thresh = cv2.inRange(b, threshold_value, 255)
1099 combined_thresh = cv2.merge([b_thresh, g_thresh, r_thresh])
1100 return combined_thresh
1101 else:
1102 raise gr.Error("Please select a color")
1103
1104def global_thresholding(image,grayscale):
1105 if grayscale:
1106 image=image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
1107 T = np.mean(image)
1108 T0 = 1
1109 iteration = 0
1110 prev_T = T
1111 while True:
1112 G1 = image[image > T]
1113 G2 = image[image <= T]
1114 mean1 = np.mean(G1) if G1.size > 0 else 0
1115 mean2 = np.mean(G2) if G2.size > 0 else 0
1116 T = (mean1 + mean2) / 2
1117 if abs(prev_T - T) < T0:
1118 break
1119 prev_T = T
1120 iteration += 1
1121
1122 segmented_image = np.zeros_like(image)
1123 segmented_image[image > T] = 255
1124 segmented_image[image <= T] = 0
1125 return segmented_image
1126
1127def hough_transform(image):
1128 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
1129
1130 edges = cv2.Canny(gray, 50, 150)
1131
1132 lines = cv2.HoughLines(edges, 1, np.pi/180, 100)
1133 if lines is not None:
1134 for line in lines:
1135 rho, theta = line[0]
1136 a, b = np.cos(theta), np.sin(theta)
1137 x0, y0 = a * rho, b * rho
1138 x1, y1 = int(x0 + 1000 * (-b)), int(y0 + 1000 * (a))
1139 x2, y2 = int(x0 - 1000 * (-b)), int(y0 - 1000 * (a))
1140 cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
1141 return image
1142 else:
1143 return image
1144
1145def enhance_image(image1, image2, enhancement_type, min_val, max_val, grayscale, gamma=1, threshold_type="Soft", threshold_value=100,operation_type=None
1146,sigma=1,noise_type=None,noise_type2=None,reduction=False,reduction_type=None):
1147 if image1 is None or image1.size == 0:
1148 raise gr.Error("Please select an image🌅")
1149 if min_val:
1150 min_val = int(min_val)
1151 if max_val:
1152 max_val = int(max_val)
1153 if threshold_value:
1154 threshold_value = int(threshold_value)
1155
1156 if enhancement_type == "Power Law Transform":
1157 return power_law_transform(image1, gamma, grayscale)
1158 elif enhancement_type == "Histogram Equalization":
1159 return histogram_equalization(image1, grayscale)
1160 elif enhancement_type == "Gray Level Slicing":
1161 return Gray_Level_Slicing(image1, grayscale, min_val, max_val)
1162 elif enhancement_type == "Linear Negative Transformation":
1163 return linear_negative_transformation(image1, grayscale)
1164 elif enhancement_type == "Log Transformation":
1165 return log_transformation(image1, grayscale)
1166 elif enhancement_type == "Piecewise Linear Transformation":
1167 return piecewise_linear_transformation(image1, grayscale)
1168 elif enhancement_type == "Bit Plane Slicing":
1169 return generate_bit_plane_plot(image1)
1170 elif enhancement_type == "Thresholding":
1171 return thresholding(image1, grayscale, threshold_type, threshold_value)
1172 elif enhancement_type == "Arithmetic Operations":
1173 if image2 is None or image2.size == 0:
1174 raise gr.Error("Please select another image🌅")
1175 return arithmetic_operations(image1, image2, operation_type)
1176 elif enhancement_type =="Generic Filter":
1177 return Generic_filter(image1,grayscale)
1178 elif enhancement_type =="Gaussian Filter":
1179 return Gaussian_filter(image1,grayscale,sigma)
1180 elif enhancement_type =="Salt & Pepper":
1181 return salt_and_pepper_noise(image1,grayscale,noise_type)
1182 elif enhancement_type =="Noise Reduction":
1183 return add_nosie(image1,grayscale,noise_type2,reduction,reduction_type)
1184 else:
1185 raise gr.Error("🚫Please select an Enhancement type🚫")
1186
1187
1188def compress_image(image, compression_type, grayscale, output_path,see_difference=False,lossy_quality=None,see_difference2=False,level=None
1189 ,see_difference3=False):
1190 if compression_type == "Progressive Image Transmission":
1191 return progressive_image_transmission(image, grayscale, output_path,see_difference)
1192 elif compression_type =="Lossy Compression":
1193 return lossy_compression(image,grayscale,lossy_quality,see_difference2)
1194 elif compression_type =="Lossless Compression":
1195 return lossless_compression(image,grayscale,level,see_difference3)
1196 else:
1197 raise gr.Error("🚫Please select a Compression type🚫")
1198
1199def segment_image(image,segmentation_type,grayscale,mask_type,dilation,display,hist,color,hist2):
1200 if segmentation_type == "Gray Level Discontinuity Point Detection":
