-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpb_kmeans.lua
executable file
·104 lines (87 loc) · 3.33 KB
/
pb_kmeans.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
return {init=function(_,_,_,_,_,_)
local function find_closest_centroid(r,g,b,centroids,count,colorspace)
local target_r,target_g,target_b = r,g,b
if colorspace then
target_r,target_g,target_b = colorspace(r,g,b)
end
local closest_distance = math.huge
local closest_index = nil
for centroid=1,count do
local centroid_source = centroids[centroid]
local centroid_a = centroid_source[1]
local centroid_b = centroid_source[2]
local centroid_c = centroid_source[3]
if colorspace then
centroid_a,centroid_b,centroid_c = colorspace(
centroid_a,centroid_b,centroid_c
)
end
local delta_a = target_r - centroid_a
local delta_b = target_g - centroid_b
local delta_c = target_b - centroid_c
-- ommiting sqrt
local centroid_distance = delta_a^2+delta_b^2+delta_c^2
if centroid_distance <= closest_distance then
closest_distance = centroid_distance
closest_index = centroid
end
end
return closest_index
end
local function kmeans_cluster(data_points,centroids,iterations,colorspace)
local color_sectors = {}
local centroid_count = #centroids
local distance_vectors = {}
for centroid_id=1,centroid_count do
color_sectors [centroid_id] = {
sum_red = 0,
sum_grn = 0,
sum_blu = 0,
c_count = 0
}
end
for iteration=1,iterations do
for pixel_index=1,#data_points do
local pixel = data_points[pixel_index]
local near_centroid = find_closest_centroid(
pixel[1],pixel[2],pixel[3],
centroids,centroid_count,
colorspace
)
local bucket = color_sectors[near_centroid]
bucket.sum_red = bucket.sum_red + pixel[1]
bucket.sum_grn = bucket.sum_grn + pixel[2]
bucket.sum_blu = bucket.sum_blu + pixel[3]
bucket.c_count = bucket.c_count + 1
end
for bucket_id=1,centroid_count do
local bucket = color_sectors[bucket_id]
local color_count = bucket.c_count
local average_r = bucket.sum_red / color_count
local average_g = bucket.sum_grn / color_count
local average_b = bucket.sum_blu / color_count
bucket.sum_red = 0
bucket.sum_grn = 0
bucket.sum_blu = 0
bucket.c_count = 0
local centroid = centroids[bucket_id]
centroid[1] = average_r
centroid[2] = average_g
centroid[3] = average_b
end
end
return centroids
end
return {kmeans = {
cluster = kmeans_cluster,
internal = {
find_closest_centroid = find_closest_centroid,
}
}},{}
end,
id = "PB_MODULE:kmeans",
name = "PB_KMeansCluster",
author = "9551",
contact = "https://devvie.cc/contact",
report_msg = "\n__name: module error, report issues at\n-> __contact"
}