مرحبا بالجميع! في الآونة الأخيرة ، كان من الضروري كتابة تعليمات برمجية لتنفيذ تجزئة الصورة باستخدام طريقة k-الوسائل (الوسائل الإنجليزية k). حسنًا ، أول شيء تفعله Google هو المساعدة. لقد عثرت على الكثير من المعلومات ، مثل من وجهة نظر رياضية (جميع أنواع الخربشات الرياضية المعقدة هناك ، ستفهم ما هو مكتوب هناك) ، بالإضافة إلى بعض تطبيقات البرامج الموجودة على الإنترنت باللغة الإنجليزية. هذه الرموز جميلة بالتأكيد - لا شك ، ولكن من الصعب فهم جوهر الفكرة. بطريقة ما ، كل شيء معقد هناك ، مرتبك ، ومع ذلك ، باليد ، لن تكتب الرمز ، لن تفهم أي شيء. في هذه المقالة ، أريد أن أعرض تنفيذًا بسيطًا وليس منتجًا ، ولكن آمل أن يكون مفهوما لهذه الخوارزمية الرائعة. حسنًا ، لنذهب!
إذن ما هو التجمع من حيث تصوراتنا؟ دعني أعطيك مثالاً ، لنفترض أن هناك صورة جميلة بالزهور من منزل جدتك.

السؤال هو: لتحديد عدد المناطق في هذه الصورة المملوءة بنفس اللون تقريبًا. حسنًا ، الأمر ليس صعبًا على الإطلاق: بتلات بيضاء - واحدة ، مراكز صفراء - اثنان (أنا لست عالم أحياء ، لا أعرف ما يطلق عليهما) ، ثلاث خضر. تسمى هذه الأقسام العناقيد. الكتلة هي مجموعة من البيانات التي لها ميزات مشتركة (اللون والموضع وما إلى ذلك). تسمى عملية تحديد ووضع كل مكون من أي بيانات في هذه المجموعات - المقاطع التجميع.
هناك العديد من خوارزميات التجميع ، ولكن أبسطها هو k - متوسط ، والذي سيتم مناقشته لاحقًا. K-يعني خوارزمية بسيطة وفعالة يسهل تنفيذها باستخدام طريقة برمجية. البيانات التي سنقوم بتوزيعها في مجموعات هي بكسل. كما تعلم ، يحتوي بكسل الألوان على ثلاثة مكونات - الأحمر والأخضر والأزرق. فرض هذه المكونات وإنشاء لوحة من الألوان الموجودة.

في ذاكرة الكمبيوتر ، يتميز كل مكون لون برقم من 0 إلى 255. أي أنه يجمع بين قيم مختلفة من الأحمر والأخضر والأزرق ، نحصل على لوحة ألوان على الشاشة.
باستخدام وحدات البكسل كمثال ، نقوم بتنفيذ الخوارزمية الخاصة بنا. K- يعني خوارزمية تكرارية ، أي أنها ستعطي النتيجة الصحيحة ، بعد عدد معين من التكرار لبعض الحسابات الرياضية.
خوارزمية
- يجب أن تعرف مقدمًا عدد المجموعات التي تحتاجها لتوزيع البيانات. يعد هذا عيبًا كبيرًا لهذه الطريقة ، ولكن يتم حل هذه المشكلة من خلال التطبيقات المحسنة للخوارزمية ، ولكن هذه ، كما يقولون ، قصة مختلفة تمامًا.
- نحن بحاجة إلى اختيار المراكز الأولية لمجموعاتنا. كيف؟ نعم بشكل عشوائي. لماذا؟ بحيث يمكنك انجذاب كل بكسل إلى مركز الكتلة. المركز مثل الملك ، حيث يتم تجميع رعاياه - بكسل. إن "المسافة" من المركز إلى البكسل هي التي تحدد لمن تطيعه كل بكسل.
- نحسب المسافة من كل مركز إلى كل بكسل. تعتبر هذه المسافة هي المسافة الإقليدية بين النقاط في الفضاء ، وفي حالتنا ، المسافة بين مكونات الألوان الثلاثة:$$ display $$ \ sqrt {(R_ {2} -R_ {1}) ^ 2 + (G_ {2} -G_ {1}) ^ 2 + (B_ {2} -B_ {1}) ^ 2} . $$ display $$ نحسب المسافة من البكسل الأول إلى كل مركز ونحدد أصغر مسافة بين هذه البكسل والمراكز. بالنسبة للمركز ، والمسافة التي هي أصغرها ، نقوم بإعادة حساب الإحداثيات كمتوسط حسابي بين كل مكون من عناصر البكسل - الملك والبكسل - للموضوع. يتغير مركزنا في الفضاء وفقًا للحسابات.
- بعد إعادة سرد جميع المراكز ، نقوم بتوزيع وحدات البكسل في مجموعات ، ومقارنة المسافة من كل بكسل إلى المراكز. يتم وضع البكسل في كتلة ، يكون مركزها أقرب منه إلى المراكز الأخرى.
- يبدأ كل شيء مرة أخرى ، طالما بقيت البكسل في نفس العناقيد. غالبًا ما لا يحدث هذا ، نظرًا لأن كمية كبيرة من البيانات ستتحرك المراكز في نصف قطر صغير ، وستقفز وحدات البكسل على طول حواف المجموعات إلى مجموعة أو أخرى. للقيام بذلك ، حدد الحد الأقصى لعدد التكرارات.
التنفيذ
سأقوم بتنفيذ هذا المشروع في C ++. الملف الأول هو "k_means.h" ، حيث قمت بتعريف أنواع البيانات الرئيسية والثوابت والفئة الرئيسية للعمل - "K_means".
لتمييز كل بكسل ، قم بإنشاء هيكل يتكون من ثلاثة مكونات بكسل ، اخترت النوع المزدوج لها لإجراء حسابات أكثر دقة ، كما حددت بعض الثوابت ليعمل البرنامج:
const int KK = 10;  
K_ يعني الصف نفسه:
 class K_means { private: std::vector<rgb> pixcel; int q_klaster; int k_pixcel; std::vector<rgb> centr; void identify_centers(); inline double compute(rgb k1, rgb k2) { return sqrt(pow((k1.r - k2.r),2) + pow((k1.g - k2.g), 2) + pow((k1.b - k2.b), 2)); } inline double compute_s(double a, double b) { return (a + b) / 2; }; public: K_means() : q_klaster(0), k_pixcel(0) {}; K_means(int n, rgb *mas, int n_klaster); K_means(int n_klaster, std::istream & os); void clustering(std::ostream & os); void print()const; ~K_means(); friend std::ostream & operator<<(std::ostream & os, const K_means & k); }; 
لنستعرض مكونات الفصل:
vectorpixcel - ناقل للبكسل ؛
q_klaster - عدد العناقيد ؛
k_pixcel - عدد البكسل ؛
Vectorcentr - متجه لمراكز التجميع ، يتم تحديد عدد العناصر فيه بواسطة q_klaster ؛
Ident_centers () - طريقة لاختيار المراكز الأولية عشوائيًا بين وحدات بكسل الإدخال ؛
compute () و compute_s () طريقتان مدمجتان لحساب المسافة بين البكسل ومراكز إعادة الحساب ، على التوالي ؛
ثلاثة مُنشئات: الأول بشكل افتراضي ، والثاني هو لتهيئة وحدات البكسل من مصفوفة ، والثالث لتهيئة وحدات البكسل من ملف نصي (في التطبيق الخاص بي ، يتم تعبئة الملف عن طريق الخطأ بالبيانات في البداية ، ثم تتم قراءة وحدات البكسل من هذا الملف لكي يعمل البرنامج ، لماذا لا مباشرة إلى المتجه - مطلوب فقط في حالتي) ؛
التجمع (std :: ostream & os) - طريقة التجميع ؛
طريقة وحمل بيان المخرجات الزائد لنشر النتائج.
تنفيذ الأسلوب:
 void K_means::identify_centers() { srand((unsigned)time(NULL)); rgb temp; rgb *mas = new rgb[q_klaster]; for (int i = 0; i < q_klaster; i++) { temp = pixcel[0 + rand() % k_pixcel]; for (int j = i; j < q_klaster; j++) { if (temp.r != mas[j].r && temp.g != mas[j].g && temp.b != mas[j].b) { mas[j] = temp; } else { i--; break; } } } for (int i = 0; i < q_klaster; i++) { centr.push_back(mas[i]); } delete []mas; } 
هذه طريقة لاختيار مراكز التجميع الأولية وإضافتها إلى ناقل المركز. يتم إجراء فحص لتكرار المراكز واستبدالها في هذه الحالات.
 K_means::K_means(int n, rgb * mas, int n_klaster) { for (int i = 0; i < n; i++) { pixcel.push_back(*(mas + i)); } q_klaster = n_klaster; k_pixcel = n; identify_centers(); } 
تطبيق منشئ لتهيئة وحدات البكسل من صفيف.
 K_means::K_means(int n_klaster, std::istream & os) : q_klaster(n_klaster) { rgb temp; while (os >> temp.r && os >> temp.g && os >> temp.b) { pixcel.push_back(temp); } k_pixcel = pixcel.size(); identify_centers(); } 
نقوم بتمرير كائن إدخال إلى هذا المُنشئ حتى نتمكن من إدخال البيانات من كل من الملف ووحدة التحكم.
 void K_means::clustering(std::ostream & os) { os << "\n\n :" << std::endl;  std::vector<int> check_1(k_pixcel, -1); std::vector<int> check_2(k_pixcel, -2); int iter = 0;  while(true) { os << "\n\n----------------  №" << iter << " ----------------\n\n"; { for (int j = 0; j < k_pixcel; j++) { double *mas = new double[q_klaster];  for (int i = 0; i < q_klaster; i++) { *(mas + i) = compute(pixcel[j], centr[i]); os << "   " << j << "   #" << i << ": " << *(mas + i) << std::endl; }  double min_dist = *mas; int m_k = 0; for (int i = 0; i < q_klaster; i++) { if (min_dist > *(mas + i)) { min_dist = *(mas + i); m_k = i; } } os << "    #" << m_k << std::endl; os << "  #" << m_k << ": "; centr[m_k].r = compute_s(pixcel[j].r, centr[m_k].r); centr[m_k].g = compute_s(pixcel[j].g, centr[m_k].g); centr[m_k].b = compute_s(pixcel[j].b, centr[m_k].b); os << centr[m_k].r << " " << centr[m_k].g << " " << centr[m_k].b << std::endl; delete[] mas; }  int *mass = new int[k_pixcel]; os << "\n  : "<< std::endl; for (int k = 0; k < k_pixcel; k++) { double *mas = new double[q_klaster];  for (int i = 0; i < q_klaster; i++) { *(mas + i) = compute(pixcel[k], centr[i]); os << "   №" << k << "   #" << i << ": " << *(mas + i) << std::endl; }  double min_dist = *mas; int m_k = 0; for (int i = 0; i < q_klaster; i++) { if (min_dist > *(mas + i)) { min_dist = *(mas + i); m_k = i; } } mass[k] = m_k; os << " №" << k << "     #" << m_k << std::endl; }  os << "\n    : \n"; for (int i = 0; i < k_pixcel; i++) { os << mass[i] << " "; check_1[i] = *(mass + i); } os << std::endl << std::endl; os << " : " << std::endl; int itr = KK + 1; for (int i = 0; i < q_klaster; i++) { os << " #" << i << std::endl; for (int j = 0; j < k_pixcel; j++) { if (mass[j] == i) { os << pixcel[j].r << " " << pixcel[j].g << " " << pixcel[j].b << std::endl; mass[j] = ++itr; } } } delete[] mass;  os << " : \n" ; for (int i = 0; i < q_klaster; i++) { os << centr[i].r << " " << centr[i].g << " " << centr[i].b << " - #" << i << std::endl; } }  iter++; if (check_1 == check_2 || iter >= max_iterations) { break; } check_2 = check_1; } os << "\n\n ." << std::endl; } 
الطريقة الرئيسية للتجميع.
 std::ostream & operator<<(std::ostream & os, const K_means & k) { os << " : " << std::endl; for (int i = 0; i < k.k_pixcel; i++) { os << k.pixcel[i].r << " " << k.pixcel[i].g << " " << k.pixcel[i].b << " - №" << i << std::endl; } os << std::endl << "   : " << std::endl; for (int i = 0; i < k.q_klaster; i++) { os << k.centr[i].r << " " << k.centr[i].g << " " << k.centr[i].b << " - #" << i << std::endl; } os << "\n : " << k.q_klaster << std::endl; os << " : " << k.k_pixcel << std::endl; return os; } 
إخراج البيانات الأولية.
مثال الإخراج
مثال الإخراجوحدات البكسل الأولية: 
255140 50 - رقم 0 
100 70 1 - رقم 1 
15020200 - رقم 2 
251 141 51 - رقم 3 
104 69 3 - رقم 4 
153 22 210 - رقم 5 
252 138 54 - رقم 6 
101 74 4 - رقم 7 
مراكز التجمعات العشوائية الأولية: 
15020200 - # 0 
104 69 3 - # 1 
100 70 1 - # 2 
عدد العناقيد: 3 
عدد البكسل: 8 
بداية الكتلة: 
رقم التكرار 0 
المسافة من بكسل 0 إلى المركز رقم 0: 218.918 
المسافة من بكسل 0 إلى المركز رقم 1: 173.352 
المسافة من بكسل 0 إلى المركز رقم 2: 176.992 
الحد الأدنى لمسافة المركز # 1 
إعادة حساب المركز # 1: 179.5 104.5 26.5 
المسافة من بكسل 1 إلى المركز رقم 0: 211.189 
المسافة من البكسل 1 إلى المركز رقم 1: 90.3369 
المسافة من بكسل 1 إلى المركز رقم 2: 0 
الحد الأدنى لمسافة المركز 2 
إعادة حساب المركز # 2: 100 70 1 
المسافة من بكسل 2 إلى المركز # 0: 0 
المسافة من بكسل 2 إلى المركز رقم 1: 195.225 
المسافة من بكسل 2 إلى المركز رقم 2: 211.189 
الحد الأدنى لمسافة المركز # 0 
عد المركز # 0: 150 20200 
المسافة من البكسل 3 إلى المركز رقم 0: 216.894 
المسافة من البكسل 3 إلى المركز رقم 1: 83.933 
المسافة من بكسل 3 إلى المركز رقم 2: 174.19 
الحد الأدنى لمسافة المركز # 1 
عد المركز # 1: 215.25 122.75 38.75 
المسافة من بكسل 4 إلى المركز رقم 0: 208.149 
المسافة من بكسل 4 إلى المركز رقم 1: 128.622 
المسافة من بيكسل 4 إلى المركز رقم 2: 4.58258 
الحد الأدنى لمسافة المركز 2 
عد المركز # 2: 102 69.5 2 
المسافة من بكسل 5 إلى المركز رقم 0: 10.6301 
المسافة من بكسل 5 إلى المركز رقم 1: 208.212 
المسافة من بكسل 5 إلى المركز رقم 2: 219.366 
الحد الأدنى لمسافة المركز # 0 
إعادة حساب المركز # 0: 151.5 21205 
المسافة من بكسل 6 إلى المركز رقم 0: 215.848 
المسافة من بكسل 6 إلى المركز رقم 1: 42.6109 
المسافة من بكسل 6 إلى المركز رقم 2: 172.905 
الحد الأدنى لمسافة المركز # 1 
إعادة حساب المركز # 1: 233.625 130.375 46.375 
المسافة من بيكسل 7 إلى المركز رقم 0: 213.916 
المسافة من بكسل 7 إلى المركز رقم 1: 150.21 
المسافة من بيكسل 7 إلى المركز رقم 2: 5.02494 
الحد الأدنى لمسافة المركز 2 
إعادة حساب المركز # 2: 101.5 71.75 3 
لنصنف وحدات البكسل: 
المسافة من البكسل رقم 0 إلى المركز # 0: 221.129 
المسافة من البكسل رقم 0 للمركز # 1: 23.7207 
المسافة من البكسل رقم 0 للمركز رقم 2: 174.44 
Pixel # 0 الأقرب إلى المركز رقم 1 
المسافة من البكسل رقم 1 للمركز # 0: 216.031 
المسافة من البكسل رقم 1 للمركز رقم 1: 153.492 
المسافة من البكسل رقم 1 للمركز رقم 2: 3.05164 
Pixel # 1 الأقرب إلى المركز رقم 2 
المسافة من البكسل رقم 2 للمركز # 0: 5.31507 
المسافة من البكسل رقم 2 للمركز رقم 1: 206.825 
المسافة من البكسل رقم 2 للمركز رقم 2: 209.378 
Pixel # 2 الأقرب إلى المركز رقم 0 
المسافة من البكسل رقم 3 للمركز # 0: 219.126 
المسافة من البكسل رقم 3 للمركز رقم 1: 20.8847 
المسافة من البكسل رقم 3 للمركز رقم 2: 171.609 
Pixel # 3 الأقرب إلى المركز رقم 1 
المسافة من البكسل رقم 4 للمركز # 0: 212.989 
المسافة من البكسل رقم 4 للمركز رقم 1: 149.836 
المسافة من البكسل رقم 4 للمركز رقم 2: 3.71652 
Pixel # 4 الأقرب إلى المركز رقم 2 
المسافة من البكسل رقم 5 للمركز # 0: 5.31507 
المسافة من البكسل رقم 5 للمركز # 1: 212.176 
المسافة من البكسل رقم 5 للمركز رقم 2: 219.035 
Pixel # 5 الأقرب إلى المركز رقم 0 
المسافة من البكسل رقم 6 للمركز # 0: 215.848 
المسافة من البكسل رقم 6 إلى المركز رقم 1: 21.3054 
المسافة من البكسل رقم 6 للمركز # 2: 172.164 
Pixel # 6 الأقرب إلى المركز رقم 1 
المسافة من البكسل رقم 7 إلى المركز # 0: 213.916 
المسافة من البكسل رقم 7 إلى المركز رقم 1: 150.21 
المسافة من البكسل رقم 7 للمركز رقم 2: 2.51247 
Pixel # 7 الأقرب إلى المركز رقم 2 
مجموعة من وحدات البكسل والمراكز المطابقة: 
1 2 0 1 2 0 1 2 
نتيجة التجميع: 
المجموعة رقم 0 
150 20200 
153 22 210 
المجموعة رقم 1 
255140 50 
251 141 51 
252 138 54 
المجموعة رقم 2 
100 70 1 
104 69 3 
101 74 4 
المراكز الجديدة: 
151.5 21 205 - # 0 
233.625 130.375 46.375 - # 1 
101.5 71.75 3 - # 2 
التكرار رقم 1 
المسافة من البكسل 0 إلى المركز # 0: 221.129 
المسافة من بكسل 0 إلى المركز رقم 1: 23.7207 
المسافة من بكسل 0 إلى المركز رقم 2: 174.44 
الحد الأدنى لمسافة المركز # 1 
عد المركز # 1: 244.313 135.188 48.1875 
المسافة من البكسل 1 إلى المركز رقم 0: 216.031 
المسافة من بكسل 1 إلى المركز رقم 1: 165.234 
المسافة من بكسل 1 إلى المركز رقم 2: 3.05164 
الحد الأدنى لمسافة المركز 2 
إعادة حساب المركز # 2: 100.75 70.875 2 
المسافة من بكسل 2 إلى المركز رقم 0: 5.31507 
المسافة من بكسل 2 إلى المركز رقم 1: 212.627 
المسافة من بكسل 2 إلى المركز رقم 2: 210.28 
الحد الأدنى لمسافة المركز # 0 
إعادة حساب المركز # 0: 150.75 20.5 202.5 
المسافة من بكسل 3 إلى المركز رقم 0: 217.997 
المسافة من البكسل 3 إلى المركز رقم 1: 9.29613 
المسافة من بكسل 3 إلى المركز رقم 2: 172.898 
الحد الأدنى لمسافة المركز # 1 
عد المركز # 1: 247.656 138.094 49.5938 
المسافة من بيكسل 4 إلى المركز رقم 0: 210.566 
المسافة من البكسل 4 إلى المركز رقم 1: 166.078 
المسافة من بيكسل 4 إلى المركز رقم 2: 3.88306 
الحد الأدنى لمسافة المركز 2 
عد المركز # 2: 102.375 69.9375 2.5 
المسافة من بكسل 5 إلى المركز رقم 0: 7.97261 
المسافة من بكسل 5 إلى المركز رقم 1: 219.471 
المسافة من بكسل 5 إلى المركز رقم 2: 218.9 
الحد الأدنى لمسافة المركز # 0 
عد المركز # 0: 151.875 21.25 206.25 
المسافة من بكسل 6 إلى المركز رقم 0: 216.415 
المسافة من بكسل 6 إلى المركز رقم 1: 6.18805 
المسافة من بكسل 6 إلى المركز رقم 2: 172.257 
الحد الأدنى لمسافة المركز # 1 
إعادة حساب المركز # 1: 249.828 138.047 51.7969 
المسافة من بكسل 7 إلى المركز رقم 0: 215.118 
المسافة من بيكسل 7 إلى المركز رقم 1: 168.927 
المسافة من بكسل 7 إلى المركز رقم 2: 4.54363 
الحد الأدنى لمسافة المركز 2 
إعادة حساب المركز # 2: 101.688 71.9688 3.25 
لنصنف وحدات البكسل: 
المسافة من البكسل رقم 0 إلى المركز # 0: 221.699 
المسافة من البكسل رقم 0 للمركز رقم 1: 5.81307 
المسافة من البكسل رقم 0 للمركز رقم 2: 174.122 
Pixel # 0 الأقرب إلى المركز رقم 1 
المسافة من البكسل رقم 1 للمركز # 0: 217.244 
المسافة من البكسل رقم 1 للمركز رقم 1: 172.218 
المسافة من البكسل رقم 1 للمركز رقم 2: 3.43309 
Pixel # 1 الأقرب إلى المركز رقم 2 
المسافة من البكسل رقم 2 للمركز # 0: 6.64384 
المسافة من البكسل رقم 2 للمركز رقم 1: 214.161 
المسافة من البكسل رقم 2 للمركز رقم 2: 209.154 
Pixel # 2 الأقرب إلى المركز رقم 0 
المسافة من البكسل رقم 3 للمركز # 0: 219.701 
المسافة من البكسل # 3 إلى المركز رقم 1: 3.27555 
المسافة من البكسل رقم 3 للمركز رقم 2: 171.288 
Pixel # 3 الأقرب إلى المركز رقم 1 
المسافة من البكسل رقم 4 إلى المركز # 0: 214.202 
المسافة من البكسل رقم 4 للمركز رقم 1: 168.566 
المسافة من البكسل رقم 4 للمركز رقم 2: 3.77142 
Pixel # 4 الأقرب إلى المركز رقم 2 
المسافة من البكسل رقم 5 للمركز # 0: 3.9863 
المسافة من البكسل رقم 5 للمركز # 1: 218.794 
المسافة من البكسل رقم 5 للمركز رقم 2: 218.805 
Pixel # 5 الأقرب إلى المركز رقم 0 
المسافة من البكسل رقم 6 للمركز # 0: 216.415 
المسافة من البكسل رقم 6 إلى المركز رقم 1: 3.09403 
المسافة من البكسل رقم 6 إلى المركز رقم 2: 171.842 
Pixel # 6 الأقرب إلى المركز رقم 1 
المسافة من البكسل رقم 7 إلى المركز # 0: 215.118 
المسافة من البكسل رقم 7 إلى المركز رقم 1: 168.927 
المسافة من البكسل رقم 7 إلى المركز رقم 2: 2.27181 
Pixel # 7 الأقرب إلى المركز رقم 2 
مجموعة من وحدات البكسل والمراكز المطابقة: 
1 2 0 1 2 0 1 2 
نتيجة التجميع: 
المجموعة رقم 0 
150 20200 
153 22 210 
المجموعة رقم 1 
255140 50 
251 141 51 
252 138 54 
المجموعة رقم 2 
100 70 1 
104 69 3 
101 74 4 
المراكز الجديدة: 
151.875 21.25 206.25 - # 0 
249.828 138.047 51.7969 - # 1 
101.688 71.9688 3.25 - # 2 
نهاية التكتل.
 تم التخطيط لهذا المثال مسبقًا ، ويتم تحديد وحدات البكسل خصيصًا للتوضيح. يكفي تكراران للبرنامج لتجميع البيانات في ثلاث مجموعات. بالنظر إلى مراكز التكررين الماضيين ، يمكنك أن ترى أنها بقيت في مكانها عمليًا.
أكثر إثارة للاهتمام هي حالات بكسل تم إنشاؤها بشكل عشوائي. بعد أن ولدت 50 نقطة يجب تقسيمها إلى 10 مجموعات ، حصلت على 5 تكرارات. بعد أن ولدت 50 نقطة يجب تقسيمها إلى 3 مجموعات ، حصلت على كل 100 تكرار كحد أقصى مسموح به. قد تلاحظ أنه كلما زاد عدد المجموعات ، كان من الأسهل على البرنامج العثور على وحدات البكسل الأكثر تشابهًا ودمجها في مجموعات أصغر ، والعكس صحيح - إذا كان هناك عدد قليل من المجموعات وهناك العديد من النقاط ، غالبًا ما تنتهي الخوارزمية فقط عندما يتم تجاوز الحد الأقصى لعدد التكرارات ، حيث تقفز بعض وحدات البكسل باستمرار من عنقود لآخر. ومع ذلك ، لا يزال الجزء الأكبر محددًا في مجموعاته بالكامل.
حسنًا ، الآن دعنا نتحقق من نتيجة التجميع. بأخذ نتيجة بعض المجموعات من مثال 50 نقطة لكل 10 مجموعات ، قمت بقيادة نتيجة هذه البيانات إلى Illustrator وهذا ما حدث:

يمكن ملاحظة أنه في كل مجموعة تسود أي ظلال من الألوان ، وهنا تحتاج إلى فهم أنه تم اختيار وحدات البكسل بشكل عشوائي ، فإن التناظرية لمثل هذه الصورة في الحياة الواقعية هي نوع من الصورة التي يتم رش جميع الألوان عليها عن طريق الخطأ ومن الصعب تحديد مناطق ذات ألوان متشابهة.
لنفترض أن لدينا مثل هذه الصورة. يمكننا تعريف الجزيرة على أنها كتلة واحدة ، ولكن مع زيادة نرى أنها تتكون من ظلال مختلفة من اللون الأخضر.

وهذه هي المجموعة 8 ، ولكن في نسخة أصغر ، تكون النتيجة متشابهة:

يمكن الاطلاع على النسخة الكاملة من البرنامج على 
GitHub .