class ImageCluster { public: void Reset(const Bitmap &bmp, const Vec2i &seed); void AddCoord(const Bitmap &bmp, const Vec2i &coord); Vec2i MassCentroid(const Vec2i &dimensions); Vec2i ColorCentroid(const Bitmap &bmp, const Vec2i &dimensions); double AssignmentError(const Bitmap &bmp, const Vec2i &coord); __forceinline const Vec2i& seed() { return _seed; } __forceinline const Vector& coords() { return _coords; } private: Vec2i _seed; Vector _coords; }; class ImageSegmenter { public: struct QueueEntry { double priority; Vec2i coord; UINT clusterIndex; }; void Segment(const Bitmap &bmp, UINT clusterCount, UINT iterationCount, Grid &clusterIDs); static void DrawClusterIDs(const Grid &clusterIDs, Bitmap &bmp); static void DrawClusterColors(const Bitmap &inputBmp, const Grid &clusterIDs, Bitmap &outputBmp); private: void InitializeClusters(const Bitmap &bmp); void AssignPixel(const Bitmap &bmp, const Vec2i &coord, UINT clusterIndex); void GrowClusters(const Bitmap &bmp); void RecenterClusters(const Bitmap &bmp); UINT _clusterSizeCutoff; Vec2i _dimensions; Vector _clusters; priority_queue _queue; Grid _assignments; }; __forceinline bool operator < (const ImageSegmenter::QueueEntry &a, const ImageSegmenter::QueueEntry &b) { return (a.priority < b.priority); }