//! apply k-means classify to histogram void apply_k_means_classify(const histogram<double>& input, const std::vector<double>& mu, std::vector<int>& cls ) { int number_of_classes=mu.size(); int i,j,k; //calculate all the classes for(j=0;j<input.size();j++) { int best_k=0; double best_dist=0; for(k=0;k<number_of_classes;k++) { double dist=fabs(input.value(j)-mu[k]); if(dist<best_dist|| best_k==0) { best_dist=dist; best_k=k+1; } } cls[j]=best_k; } }
// Run skin-detection algorithm frame detect_skin(const frame& in) { dtn_frame = in; const rgb_byte ZERO = { }; for(int y = HEIGHT - 1; y; --y) { for(int x = WIDTH - 1; x; --x) { auto orig = dtn_frame.get_pixel(x, y); rgb hist_in = { orig[2], orig[1], orig[0] }; if(hist.value(hist_in) < tld) { orig[0] = orig[1] = orig[2] = 0; } } } return dtn_frame; }
//! estimate sample mu using discrete classes void estimate_mu(const histogram<double>& input, const std::vector<int>& cls, std::vector<double>& mu ) { int number_of_classes=mu.size(); int i,j,k; std::vector<double> _counts(number_of_classes,0); for(k=0;k<number_of_classes;k++) mu[k]=0; double _count=0; //1 calculate means for(j=0;j<cls.size();j++) { _count+=input[j]; int _c=cls[j]; if(!_c || _c>number_of_classes) continue; //only use classified voxel _c--; _counts[_c]+=input[j]; mu[_c]+=input[j]*input.value(j); } if(!_count) REPORT_ERROR("No voxels defined in ROI!"); for(k=0;k<number_of_classes;k++) { for(k=0;k<number_of_classes;k++) { if(_counts[k]>0) mu[k]/=_counts[k]; } } }