Skip to content

Commit e60437e

Browse files
authored
Merge pull request #233 from rudrajit1729/master
Added Hierarchical Clustering and Median Filtering
2 parents 2d60c64 + d9da7bd commit e60437e

File tree

7 files changed

+499
-0
lines changed

7 files changed

+499
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#include<stdio.h>
2+
#include<string.h>
3+
#include<math.h>
4+
#include<time.h>
5+
#define W_MAX 1
6+
#define ROW 512
7+
#define COL 512
8+
#define T1 15
9+
#define T2 25
10+
11+
double P[50]; double img[700][700]; double orig[512][512];
12+
13+
// Utility Function - Creates input image matrix
14+
double getImg(char *s){
15+
FILE *fp;
16+
int i, j, r, c; double d, MSE = 0, dim = ROW * COL;
17+
fp = fopen(s, "r");
18+
// Create Matrix
19+
for(i = W_MAX; i < ROW+W_MAX; i++){
20+
for(j = W_MAX; j < COL+W_MAX; j++){
21+
fscanf(fp, "%lf ", &d);
22+
img[i][j] = d;
23+
MSE += pow((orig[i-W_MAX][j-W_MAX] - img[i][j]), 2);
24+
// Padding
25+
if (i == W_MAX){
26+
for(r = i-1; r >= i-W_MAX; r--) img[r][j] = img[i][j];
27+
}
28+
if(i == W_MAX + ROW - 1){
29+
for(r = i+1; r <= i+W_MAX; r++) img[r][j] = img[i][j];
30+
}
31+
if(j == W_MAX){
32+
for(c = j-1; c >= j-W_MAX; c--) img[i][c] = img[i][j];
33+
}
34+
if(j == W_MAX + COL - 1){
35+
for(c = j+1; c <= j+W_MAX; c++) img[i][c] = img[i][j];
36+
}
37+
}
38+
}
39+
// Corner Padding
40+
// Upper Corners
41+
for(i = 0; i < W_MAX; i++){
42+
// Left Corner
43+
for(j = 0; j < W_MAX; j++)
44+
img[i][j] = img[W_MAX][W_MAX];
45+
// Right Corner
46+
for(j = W_MAX+ COL; j< W_MAX+COL+W_MAX;j++)
47+
img[i][j] = img[W_MAX][W_MAX+COL-1];
48+
}
49+
// Lower Corners
50+
for(i = W_MAX+ROW; i < W_MAX+ROW+W_MAX; i++){
51+
// Left Corner
52+
for(j = 0; j < W_MAX; j++)
53+
img[i][j] = img[W_MAX+ROW-1][W_MAX];
54+
// Right Corner
55+
for(j = W_MAX+ COL; j< W_MAX+COL+W_MAX;j++)
56+
img[i][j] = img[W_MAX+ROW-1][W_MAX+COL-1];
57+
}
58+
59+
fclose(fp);
60+
MSE /= dim;
61+
return MSE;
62+
}
63+
64+
// Utility Function - Saves output image
65+
double saveImg(char *s){
66+
FILE *fp;
67+
fp = fopen(s, "w");
68+
// Change According to size
69+
fprintf(fp, "P2 512 512 255\n");
70+
int i, j; double MSE = 0, dim = ROW*COL;
71+
for(i = W_MAX; i < ROW + W_MAX; i++){
72+
for(j = W_MAX; j< COL + W_MAX; j++){
73+
MSE += pow((orig[i-W_MAX][j-W_MAX] - img[i][j]), 2);
74+
fprintf(fp, "%d ", (int)img[i][j]);
75+
}
76+
}
77+
fclose(fp);
78+
MSE /= dim;
79+
return MSE;
80+
}
81+
82+
// Calculates Structural Similarity Index of Images
83+
double getSSIM(){
84+
double C1 = pow(0.01*255, 2), C2 = pow(0.03*255, 2), dim = ROW * COL;
85+
double Vx = 0, Vy = 0, COV = 0, SSIM, o, e;
86+
int i, j, ux = 0, uy = 0;
87+
for(i = W_MAX; i < ROW + W_MAX; i++){
88+
for(j = W_MAX; j< COL + W_MAX; j++){
89+
ux += orig[i-W_MAX][j-W_MAX];
90+
uy += img[i][j];
91+
}
92+
}
93+
ux /= dim; uy /= dim;
94+
for(i = W_MAX; i < ROW + W_MAX; i++){
95+
for(j = W_MAX; j< COL + W_MAX; j++){
96+
o = orig[i-W_MAX][j-W_MAX];
97+
e = img[i][j];
98+
Vx += pow((o-ux),2);
99+
Vy += pow((e-uy), 2);
100+
COV += (o-ux)*(e-uy);
101+
}
102+
}
103+
Vx /= dim; Vy /= dim;
104+
COV /= dim;
105+
SSIM = ((2*ux*uy + C1) * (2*COV + C2))/((pow(ux, 2) + pow(uy, 2) + C1) * (Vx + Vy + C2));
106+
return SSIM;
107+
}
108+
109+
// Utility - Returns median of first n numbers in P
110+
double Median(int n){
111+
int i, d; double t, ans;
112+
// Sort the array - Insertion sort
113+
for(i = 1; i < n; i++){
114+
d = i;
115+
while (d > 0 && P[d] < P[d-1]){
116+
t = P[d];
117+
P[d] = P[d-1];
118+
P[d-1] = t;
119+
d--;
120+
}
121+
}
122+
// If n odd return mid element
123+
if (n&1)
124+
ans = P[n/2];
125+
// Else retuen
126+
else
127+
ans = (P[n/2 - 1] + P[n/2])/2;
128+
return ans;
129+
}
130+
131+
// Filter - Median Filtering
132+
double Filter(int r, int c){
133+
int cnt = 0, i, j, w=1; double M;
134+
for(i = r-w; i <= r+w; i++){
135+
for(j = c-w; j <= c+w; j++){
136+
P[cnt++] = img[i][j];
137+
}
138+
}
139+
M = Median(cnt);
140+
return M;
141+
}
142+
143+
// Standard Median Filtering
144+
double SMF(char *s){
145+
int i, j; double MSE;
146+
for(i = W_MAX; i < ROW + W_MAX; i++){
147+
for(j = W_MAX; j < COL + W_MAX; j++){
148+
// if(img[i][j]==0 || img[i][j]==255)
149+
img[i][j] = Filter(i, j);
150+
}
151+
}
152+
// Metric Calculation
153+
MSE = saveImg(s);
154+
return MSE;
155+
}
156+
157+
int main() {
158+
int i, j;
159+
clock_t start, end; double CPU_TIME;
160+
double MAXINT = pow(255, 2), RMSE, MSE1, MSE2, PSNR, d, IEF, SSIM;
161+
162+
// Get Original Image for PSNR calculation
163+
FILE *fp;
164+
fp = fopen("Original_Image.pgm", "r");
165+
for(i = 0; i < ROW; i++){
166+
for(j = 0; j < COL; j++){
167+
fscanf(fp, "%lf ", &d);
168+
orig[i][j] = d;
169+
}
170+
}
171+
fclose(fp);
172+
173+
start = clock();
174+
// Replace this with the src image name and the dest image name where the image needs to be saved
175+
MSE1 = getImg("Src Image");
176+
MSE2 = SMF("Dest Image");
177+
end = clock();
178+
CPU_TIME = ((double) (end - start)) / CLOCKS_PER_SEC;
179+
// Peak Signal to Noise Ratio
180+
PSNR = 10 * log10(MAXINT/MSE2);
181+
// MSE1 (orig, noisy), MSE2 (orig, enhanced)
182+
IEF = MSE1/MSE2;
183+
RMSE = pow(MSE2, 0.5);
184+
SSIM = getSSIM();
185+
printf("RMSE = %.4lf\tPSNR = %.4lf\tSSIM = %lf\tIEF = %.4lf\tTIME = %.2lfs\n", RMSE, PSNR, SSIM, IEF, CPU_TIME);
186+
}
187+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Median Filtering on Image(SMF)
2+
Median Filtering is a neighborhood filtering technique used in order to remove noise from images and enhance its quality.
3+
4+
Often during Image capturing and acquisition(specially in medical images) the image is disturbed by Salt and Pepper Noise(SPN)[Original pixel replaced by either maximum intenstiy pixel
5+
or minimum intensity pixel] which mainly occurs due to certain faults in sensors
6+
while capturing the image. Having noise in image makes it difficult for Computer Aided Detection(CAD). Nowadays, many Machine Learning and Deep Learning techniques are being applied on
7+
medical images for computer aided diagnosis to reduce human error. Image Preprocessing is an important stage before the image can be fed to the model. Not restricting to that itself,
8+
Image Enhancement plays an important role in improving the quality of images and removing errors/noises from them.
9+
10+
## Algorithm
11+
The main idea of the median filter is to run through the signal entry by entry, replacing each entry with the median of neighboring entries.
12+
The pattern of neighbors is called the "window", which slides, entry by entry, over the entire signal. For one-dimensional signals, the most obvious window is just the
13+
first few preceding and following entries, whereas for two-dimensional (or higher-dimensional) data the window
14+
must include all entries within a given radius or ellipsoidal region (i.e. the median filter is not a separable filter).
15+
16+
In Median filtering the edge detection becomes a bit difficult but that again is improved as we switch to fuzzy removal of noise. Median Filter is the most commonly used filter
17+
just for the fact that it is computationally faster than other existing techniques.
18+
19+
## Metric Calculation
20+
The popular metrics for judging the quality of enhancement technique are - RMSE, PSNR, SSIM, & IEF.
21+
22+
These are statistical measures that judge the quality of output relying on data and mathematics.
23+
24+
Check on the links to have a brief idea about the concepts. In *Median_Filter.c* these concepts are applied for images where each pixel acts as a data point.
25+
26+
1. Root Mean Squared Error(RMSE) - [Click To Know More](https://en.wikipedia.org/wiki/Root-mean-square_deviation)
27+
28+
2. Peak Signal to Noise Ratio(PSNR) - [Click To Know More](https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio)
29+
30+
3. Structural Similarity(SSIM) - [Click To Know More](https://en.wikipedia.org/wiki/Structural_similarity)
31+
32+
4. Image Enhancement Factor(IEF) - [Click To Know More](https://in.mathworks.com/matlabcentral/answers/450377-how-to-calculate-enhancement-factor-for-an-image)
33+
34+
## Results
35+
The SMF technique is used for removal of Salt and Pepper Noise but works well with other noises as well. SMF works well for upto 60% noise percentage. Above that it fails, new algorithms such as
36+
fuzzy median technique, Adaptive Weighted Mean Filtering technique and a lot more have been introduced as an add on of this algorithm and that works upto 85% noise.
50.5 KB
Loading
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#Hierarchical Clustering
2+
3+
#Importing the libraries
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
import pandas as pd
7+
8+
#Importing the mall dataset
9+
dataset = pd.read_csv('Mall_Customers.csv')
10+
X = dataset.iloc[:,[3, 4]].values
11+
12+
#Using the dendogram to find the optimal number of clusters
13+
import scipy.cluster.hierarchy as sch
14+
dendogram = sch.dendrogram(sch.linkage(X, method = 'ward'))# ward method minimizes within cluster variance
15+
plt.title('Dendogram')
16+
plt.xlabel('Customers')
17+
plt.ylabel('Eucledian Distances')
18+
plt.show()
19+
20+
#Fitting hierarchical clustering to the dataset
21+
from sklearn.cluster import AgglomerativeClustering
22+
hc = AgglomerativeClustering(n_clusters = 5, affinity = 'euclidean', linkage = 'ward')
23+
y_hc = hc.fit_predict(X)
24+
25+
#Visualizing the clusters
26+
plt.scatter(X[y_hc==0, 0], X[y_hc==0, 1], s = 100, c = 'red', label = 'Careful')
27+
plt.scatter(X[y_hc==1, 0], X[y_hc==1, 1], s = 100, c = 'blue', label = 'Standard')
28+
plt.scatter(X[y_hc==2, 0], X[y_hc==2, 1], s = 100, c = 'green', label = 'Target')
29+
plt.scatter(X[y_hc==3, 0], X[y_hc==3, 1], s = 100, c = 'cyan', label = 'Careless')
30+
plt.scatter(X[y_hc==4, 0], X[y_hc==4, 1], s = 100, c = 'magenta', label = 'Sensible')
31+
plt.title('Cluster of Clients')
32+
plt.xlabel('Annual Income(k$)')
33+
plt.ylabel('Spending Score(1-100)')
34+
plt.legend()
35+
plt.show()
36+
'''Analysing the graph
37+
RED - High income, low expenditure --> Careful
38+
BLUE - Average income, average expenditure --> Standard
39+
GREEN - High income, high expenditure --> Target
40+
CYAN - Low income, high expenditure --> Careless
41+
MAGENTA - Low income, low expenditure --> Sensible
42+
Changing the labels from Cluster"i" to the respective tags
43+
'''

0 commit comments

Comments
 (0)