├── NUCE_flowchart.png
├── PSO.py
├── README.md
├── __pycache__
├── PSO.cpython-37.pyc
└── utility.cpython-37.pyc
├── images
├── 1.jpeg
├── 10.jpeg
├── 11.jpeg
├── 12.jpeg
├── 13.jpeg
├── 14.jpeg
├── 2.jpeg
├── 3.jpeg
├── 4.jpeg
├── 5.jpeg
├── 6.jpeg
└── 7.jpeg
├── main.py
├── requirements.txt
├── results
├── 1.jpeg
├── 10.jpeg
├── 11.jpeg
├── 12.jpeg
├── 13.jpeg
├── 14.jpeg
├── 2.jpeg
├── 3.jpeg
├── 4.jpeg
├── 5.jpeg
├── 6.jpeg
├── 7.jpeg
├── 8.jpeg
├── 9.jpeg
└── output.jpg
└── utility.py
/NUCE_flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/NUCE_flowchart.png
--------------------------------------------------------------------------------
/PSO.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | #particle class
4 | class Particle:
5 | def __init__(self, func, dim, vmin, vmax, seed):
6 | self.rnd = np.random.seed(seed)
7 |
8 | # initialize position, velocity, local_best_particle of the particle with 0.0 value
9 | self.velocity = np.zeros(dim)
10 | self.best_part_pos = np.zeros(dim)
11 |
12 | self.position = np.random.uniform(vmin, vmax, dim)
13 |
14 | # compute fitness of particle
15 | self.fitness = func(self.position) # curr fitness
16 |
17 | # initialize best position and fitness of this particle
18 | self.best_part_pos = np.copy(self.position)
19 | self.best_part_fitness = self.fitness # best fitness
20 |
21 |
22 | def pso(func, max_iter, num_particles, dim, vmin, vmax, params):
23 |
24 | # hyper parameters
25 | wmax = params["wmax"] # maximum inertia
26 | wmin = params["wmin"] #minimum inertia
27 | c1 = params["c1"] # cognitive (particle)
28 | c2 = params["c2"] # social (swarm)
29 |
30 | rnd = np.random.seed()
31 |
32 | # create num_particles
33 | swarm = [Particle(func, dim, vmin, vmax, i) for i in range(num_particles)]
34 |
35 | # compute the value of best_position and best_fitness in swarm
36 | best_swarm_pos = np.zeros(dim)
37 | best_swarm_fitness = np.inf # swarm best
38 |
39 | # computer best particle of swarm and it's fitness
40 | for i in range(num_particles): # check each particle
41 | if swarm[i].fitness < best_swarm_fitness:
42 | best_swarm_fitness = swarm[i].fitness
43 | best_swarm_pos = np.copy(swarm[i].position)
44 |
45 | # main loop of pso
46 | it = 0
47 | while it < max_iter:
48 |
49 | # For every 5 iterations print iteration number and best fitness value
50 | if it % 5 == 0:
51 | print("Iteration = " + str(it) + " best fitness = %f" % best_swarm_fitness)
52 |
53 | w = wmax - ((wmax - wmin)/max_iter)*it
54 |
55 | for i in range(num_particles):
56 |
57 | # compute new velocity of current particle
58 | swarm[i].velocity = (
59 | (w * swarm[i].velocity) +
60 | (c1 * np.random.rand(dim) * (swarm[i].best_part_pos - swarm[i].position)) +
61 | (c2 * np.random.rand(dim) * (best_swarm_pos -swarm[i].position))
62 | )
63 |
64 | # compute new position using new velocity
65 | for k in range(dim):
66 | swarm[i].position[k] += swarm[i].velocity[k]
67 | swarm[i].position[k] = np.maximum(swarm[i].position[k], vmin)
68 | swarm[i].position[k] = np.minimum(swarm[i].position[k], vmax)
69 |
70 | # compute fitness of new position
71 | swarm[i].fitness = func(swarm[i].position)
72 |
73 | # check for local best particle
74 | if swarm[i].fitness < swarm[i].best_part_fitness:
75 | swarm[i].best_part_fitness = swarm[i].fitness
76 | swarm[i].best_part_pos = np.copy(swarm[i].position)
77 |
78 | # check for global best particle
79 | if swarm[i].fitness < best_swarm_fitness:
80 | best_swarm_fitness = swarm[i].fitness
81 | best_swarm_pos = np.copy(swarm[i].position)
82 |
83 | it += 1
84 |
85 | gbest ={}
86 | gbest["position"] = best_swarm_pos
87 | gbest["cost"] = best_swarm_fitness
88 |
89 | return gbest
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Underwater-image-color-enhancement-with-PSO-python-implementation
2 |
3 | Implemented the research paper, [Natural-based underwater image color enhancement through fusion of swarm-intelligence algorithm](http://umpir.ump.edu.my/id/eprint/26347/) in python language.
4 | ### The Four steps strategy followed in NUCE method:
5 | - Superior based underwater color cast neutralization
6 | - Dual-intensity images fusion based on average of mean and median values
7 | - Swarm-intelligence based mean equalization
8 | - Unsharp masking
9 |
10 | **Image credits**: [paper](http://umpir.ump.edu.my/id/eprint/26347/)
11 | 
12 |
13 | ## User Guide
14 | - Clone this repository
15 | ```commandline
16 | $ git clone https://github.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation.git
17 | $ cd Underwater-image-color-enhancement-with-PSO-python-implementation
18 | ```
19 | - Collect input images in **images** folder, then the enhanced output image will be saved in **results** folder with respective input image name.
20 | - Install required packages
21 | ```commandline
22 | $ pip install -r requirements.txt
23 | ```
24 | - Run main.py .
25 | ```commandline
26 | $ python main.py
27 | ```
28 |
29 | ### Code Result:
30 | 
31 |
32 | ## Dependencies
33 | - OpenCV 3.4.8
34 | - NumPy
35 | - Matplotlib
36 |
--------------------------------------------------------------------------------
/__pycache__/PSO.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/__pycache__/PSO.cpython-37.pyc
--------------------------------------------------------------------------------
/__pycache__/utility.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/__pycache__/utility.cpython-37.pyc
--------------------------------------------------------------------------------
/images/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/1.jpeg
--------------------------------------------------------------------------------
/images/10.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/10.jpeg
--------------------------------------------------------------------------------
/images/11.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/11.jpeg
--------------------------------------------------------------------------------
/images/12.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/12.jpeg
--------------------------------------------------------------------------------
/images/13.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/13.jpeg
--------------------------------------------------------------------------------
/images/14.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/14.jpeg
--------------------------------------------------------------------------------
/images/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/2.jpeg
--------------------------------------------------------------------------------
/images/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/3.jpeg
--------------------------------------------------------------------------------
/images/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/4.jpeg
--------------------------------------------------------------------------------
/images/5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/5.jpeg
--------------------------------------------------------------------------------
/images/6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/6.jpeg
--------------------------------------------------------------------------------
/images/7.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/images/7.jpeg
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | import numpy as np
3 | import cv2 as cv
4 | import matplotlib.pyplot as plt
5 | from utility import *
6 |
7 |
8 | dir_path = "./images/"
9 |
10 | original_images =[]
11 | NUCE_images =[]
12 |
13 | img_w = 350 #image width
14 | img_h = 350 #image height
15 |
16 | for im in os.listdir(dir_path):
17 |
18 | img = cv.imread(dir_path+im,1)
19 | # img = cv.resize(img,(img_w,img_h))
20 | original_images.append(img)
21 |
22 | nuce_img = NUCE(img)
23 | NUCE_images.append(nuce_img)
24 |
25 | cv.imwrite("./results/"+im.split('/')[-1], nuce_img)
26 |
27 |
28 | fig, ax = plt.subplots(4,2,figsize=(6, 9), constrained_layout = False)
29 | ax[0][0].set_title("Original Image")
30 | ax[0][1].set_title("NUCE Image")
31 |
32 | for i in range(4):
33 |
34 | ax[i][0].imshow(cv.cvtColor(original_images[i], cv.COLOR_BGR2RGB),cmap='gray')
35 | ax[i][0].axis('off')
36 |
37 | ax[i][1].imshow(cv.cvtColor(NUCE_images[i], cv.COLOR_BGR2RGB), cmap='gray')
38 | ax[i][1].axis('off')
39 |
40 | fig.tight_layout()
41 | plt.savefig("./results/output.jpg")
42 | # plt.show()
43 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | numpy==1.21.5
2 | matplotlib==3.1.1
3 | opencv-python==3.4.8.29
4 |
--------------------------------------------------------------------------------
/results/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/1.jpeg
--------------------------------------------------------------------------------
/results/10.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/10.jpeg
--------------------------------------------------------------------------------
/results/11.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/11.jpeg
--------------------------------------------------------------------------------
/results/12.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/12.jpeg
--------------------------------------------------------------------------------
/results/13.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/13.jpeg
--------------------------------------------------------------------------------
/results/14.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/14.jpeg
--------------------------------------------------------------------------------
/results/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/2.jpeg
--------------------------------------------------------------------------------
/results/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/3.jpeg
--------------------------------------------------------------------------------
/results/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/4.jpeg
--------------------------------------------------------------------------------
/results/5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/5.jpeg
--------------------------------------------------------------------------------
/results/6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/6.jpeg
--------------------------------------------------------------------------------
/results/7.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/7.jpeg
--------------------------------------------------------------------------------
/results/8.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/8.jpeg
--------------------------------------------------------------------------------
/results/9.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/9.jpeg
--------------------------------------------------------------------------------
/results/output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/8160b42017abac8afd2cfb8014599c22e238d754/results/output.jpg
--------------------------------------------------------------------------------
/utility.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import cv2 as cv
3 | import matplotlib.pyplot as plt
4 | from PSO import *
5 |
6 | # shows histogram of all 3 channels
7 | def color_hist(img):
8 |
9 | y = np.linspace(0 ,256)
10 | fig , ax = plt.subplots(3,1)
11 | ax[0].hist(img[:,:,0].flatten().ravel(),color='blue',bins = 256)
12 | ax[1].hist(img[:,:,1].flatten().ravel(),color='green',bins = 256)
13 | ax[2].hist(img[:,:,2].flatten().ravel(),color='red',bins = 256)
14 |
15 | plt.show()
16 |
17 | def plot_hist(img):
18 |
19 | plt.hist(img.flatten(),bins = 150)
20 | plt.show()
21 |
22 | # stacking BGR channels in order after computation
23 | def image(input):
24 | val = list(input)
25 |
26 | for p in range(len(val)):
27 | if val[p][1]=="B":
28 | b = val[p][0]
29 | elif val[p][1]=="G":
30 | g = val[p][0]
31 | if val[p][1]=="R":
32 | r = val[p][0]
33 | img = np.dstack([b,g,r])
34 | img = np.array(img,dtype=np.uint8)
35 |
36 | return img
37 |
38 | # Indicating superior, inferior and intermediate channels based on mean of pixels in channel
39 | def superior_inferior_split(img):
40 |
41 | B, G, R = cv.split(img)
42 |
43 | pixel = {"B":np.mean(B) ,"G":np.mean(G),"R":np.mean(R)}
44 | pixel_ordered = dict(sorted(pixel.items(), key=lambda x: x[1], reverse=True))
45 |
46 | # Classifying Maximum, Minimum and Intermediate channels of image
47 | label =["Pmax","Pint","Pmin"]
48 | chanel={}
49 |
50 | for i,j in zip(range(len(label)),pixel_ordered.keys()):
51 | if j=="B":
52 | chanel[label[i]]=list([B,j])
53 |
54 | elif j=="G":
55 | chanel[label[i]]=list([G,j])
56 |
57 | else:
58 | chanel[label[i]]=list([R,j])
59 |
60 | return chanel
61 |
62 |
63 | def neutralize_image(img):
64 |
65 | track = superior_inferior_split(img)
66 |
67 | Pmax = track["Pmax"][0]
68 | Pint = track["Pint"][0]
69 | Pmin = track["Pmin"][0]
70 |
71 | #gain_factor Pint
72 | J = (np.sum(Pmax) - np.sum(Pint))/(np.sum(Pmax) + np.sum(Pint))
73 |
74 | #gain_factor Pmin
75 | K = (np.sum(Pmax) - np.sum(Pmin))/(np.sum(Pmax) + np.sum(Pmin))
76 |
77 | track["Pint"][0] = Pint + (J * Pmax)
78 | track["Pmin"][0] = Pmin + (K * Pmax)
79 |
80 | #neutralised image
81 | neu_img = image(track.values())
82 |
83 | return neu_img
84 |
85 |
86 | def Stretching(image):
87 |
88 | LSR_img = [] # for lower stretched image
89 | USR_img = [] # for upper stretched image
90 | height, width = image.shape[:2]
91 |
92 | for i in range(image.shape[2]):
93 | img_hist = image[:,:,i]
94 | max_P = np.max(img_hist)
95 | min_P = np.min(img_hist)
96 |
97 | mean_P = np.mean(img_hist)
98 | median_P = np.median(img_hist)
99 |
100 | avg_point = (mean_P + median_P)/2
101 |
102 | LS_img = np.zeros((height, width))
103 | US_img = np.zeros((height, width))
104 |
105 | for i in range(0, height):
106 | for j in range(0, width):
107 | if img_hist[i][j] < avg_point:
108 | LS_img[i][j] = int((( img_hist[i][j] - min_P) * ((255 - min_P) / (avg_point - min_P)) + min_P))
109 | US_img[i][j] = 0
110 | #array_upper_histogram_stretching[i][j] = p_out
111 | else:
112 | LS_img[i][j] = 255
113 | US_img[i][j] = int((( img_hist[i][j] - avg_point) * ((255) / (max_P - avg_point))))
114 |
115 | LSR_img.append(LS_img)
116 | USR_img.append(US_img)
117 |
118 | LS = np.array(np.dstack(LSR_img),dtype=np.uint8)
119 | US = np.array(np.dstack(USR_img),dtype=np.uint8)
120 |
121 | return LS,US
122 |
123 |
124 | def enhanced_image(img1, img2):
125 |
126 | #integration of dual intensity images to get Enhanced-constrast output image
127 | b1,g1,r1 = cv.split(img1)
128 | b2,g2,r2 = cv.split(img2)
129 |
130 | height, width = img1.shape[:2]
131 | dual_img=np.zeros((height, width,3),dtype=np.uint8)
132 |
133 | dual_img[:,:,0] = np.array(np.add(b1/2, b2/2),dtype = np.uint8)
134 | dual_img[:,:,1] = np.array(np.add(g1/2, g2/2),dtype = np.uint8)
135 | dual_img[:,:,2] = np.array(np.add(r1/2, r2/2),dtype = np.uint8)
136 |
137 | return dual_img
138 |
139 |
140 | def pso_image(img):
141 |
142 | group = superior_inferior_split(img)
143 |
144 | maxi = np.mean(group["Pmax"][0])
145 | inte = np.mean(group["Pint"][0])
146 | mini = np.mean(group["Pmin"][0])
147 |
148 | # Defining hyperparameters
149 | n = 50 # number of particles
150 | params = {"wmax" : 0.9, "wmin" : 0.4, "c1" : 2 , "c2" : 2}
151 | max_iteration = 100
152 |
153 | x = np.array([inte, mini])
154 |
155 | def func(X,P_sup = maxi):
156 | return np.square(P_sup - X[0])+np.square(P_sup - X[1])
157 |
158 | nVar= 2 # number of variables to optimize
159 | VarMin = 0 # lower bound of variables , you can use np.array() for different variables
160 | VarMax = 255 # upper bound of variables, you can use np.array() for different variables
161 |
162 | gbest = pso(func, max_iter=max_iteration, num_particles = n, dim = 2, vmin = VarMin, vmax = VarMax, params = params)
163 |
164 | #gamma correction for inferior color channels
165 | mean_colors = gbest['position']
166 | gamma = np.log(mean_colors/255)/np.log(x/255)
167 |
168 | group["Pint"][0] = np.array(255*np.power(group["Pint"][0]/255 , gamma[0]))
169 | group["Pmin"][0] = np.array(255*np.power(group["Pmin"][0]/255 , gamma[1]))
170 |
171 |
172 | pso_res = image(group.values())
173 |
174 | return pso_res
175 |
176 | def unsharp_masking(img):
177 |
178 | alpha = 0.2
179 | beta = 1 -alpha
180 | img_blur = cv.GaussianBlur(img, (1,1),sigmaX=1)
181 | unsharp_img = cv.addWeighted(img, alpha, img_blur, beta, 0.0)
182 |
183 | return unsharp_img
184 |
185 | def NUCE(img):
186 |
187 | #superior based underwater color cast neutralization
188 | neu_img = neutralize_image(img)
189 |
190 | #Dual-intensity images fusion based on average of mean and median values
191 | img1, img2 = Stretching(neu_img)
192 | dual_img = enhanced_image(img1, img2)
193 |
194 | #Swarm-intelligence based mean equalization
195 | pso_res = pso_image(dual_img)
196 |
197 | #Unsharp masking
198 | nuce_img = unsharp_masking(pso_res)
199 |
200 | return nuce_img
201 |
--------------------------------------------------------------------------------