├── 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 | ![](https://github.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/blob/main/NUCE_flowchart.png) 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 | ![](https://github.com/prashamsatalla/Underwater-image-color-enhancement-with-PSO-python-implementation/blob/main/results/output.jpg) 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 | --------------------------------------------------------------------------------