wplist kmeans_clustering_method::get_cluster( size_t cluster_id, const wplist& points) const { if (cluster_id >= k_) { return wplist(); } return get_clusters(points)[cluster_id]; }
void process (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, void *ivoid, void *ovoid, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out) { // FIXME: this returns nan!! dt_iop_colortransfer_data_t *data = (dt_iop_colortransfer_data_t *)piece->data; float *in = (float *)ivoid; float *out = (float *)ovoid; const int ch = piece->colors; if(data->flag == ACQUIRE) { if(piece->pipe->type == DT_DEV_PIXELPIPE_PREVIEW) { // only get stuff from the preview pipe, rest stays untouched. int hist[HISTN]; // get histogram of L capture_histogram(in, roi_in, hist); // invert histogram of L invert_histogram(hist, data->hist); // get n clusters kmeans(in, roi_in, data->n, data->mean, data->var); // notify gui that commit_params should let stuff flow back! data->flag = ACQUIRED; dt_iop_colortransfer_params_t *p = (dt_iop_colortransfer_params_t *)self->params; p->flag = ACQUIRE2; } memcpy(out, in, sizeof(float)*ch*roi_out->width*roi_out->height); } else if(data->flag == APPLY) { // apply histogram of L and clustering of (a,b) int hist[HISTN]; capture_histogram(in, roi_in, hist); #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(roi_out,data,in,out,hist) #endif for(int k=0; k<roi_out->height; k++) { int j = ch*roi_out->width*k; for(int i=0; i<roi_out->width; i++) { // L: match histogram out[j] = data->hist[hist[(int)CLAMP(HISTN*in[j]/100.0, 0, HISTN-1)]]; out[j] = CLAMP(out[j], 0, 100); j+=ch; } } // cluster input buffer float mean[data->n][2], var[data->n][2]; kmeans(in, roi_in, data->n, mean, var); // get mapping from input clusters to target clusters int mapio[data->n]; get_cluster_mapping(data->n, mean, data->mean, mapio); // for all pixels: find input cluster, transfer to mapped target cluster #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(roi_out,data,mean,var,mapio,in,out) #endif for(int k=0; k<roi_out->height; k++) { float weight[MAXN]; int j = ch*roi_out->width*k; for(int i=0; i<roi_out->width; i++) { const float L = in[j]; const float Lab[3] = {L, in[j+1], in[j+2]}; // a, b: subtract mean, scale nvar/var, add nmean #if 0 // single cluster, gives color banding const int ki = get_cluster(in + j, data->n, mean); out[j+1] = 100.0/out[j] * ((Lab[1] - mean[ki][0])*data->var[mapio[ki]][0]/var[ki][0] + data->mean[mapio[ki]][0]); out[j+2] = 100.0/out[j] * ((Lab[2] - mean[ki][1])*data->var[mapio[ki]][1]/var[ki][1] + data->mean[mapio[ki]][1]); #else // fuzzy weighting get_clusters(in+j, data->n, mean, weight); out[j+1] = out[j+2] = 0.0f; for(int c=0; c<data->n; c++) { out[j+1] += weight[c] * ((Lab[1] - mean[c][0])*data->var[mapio[c]][0]/var[c][0] + data->mean[mapio[c]][0]); out[j+2] += weight[c] * ((Lab[2] - mean[c][1])*data->var[mapio[c]][1]/var[c][1] + data->mean[mapio[c]][1]); } #endif out[j+3] = in[j+3]; j+=ch; } } } else { memcpy(out, in, sizeof(float)*ch*roi_out->width*roi_out->height); } }
int save_map (const char* file_name) { int i,j; map_header cur_map_header; char * mem_map_header=(char *)&cur_map_header; object3d_io cur_3d_obj_io; int obj_3d_no=0; int obj_3d_io_size; obj_2d_io cur_2d_obj_io; int obj_2d_no=0; int obj_2d_io_size; light_io cur_light_io; int lights_no=0; int lights_io_size; particles_io cur_particles_io; int particles_no=0; int particles_io_size; #ifdef ZLIBW gzFile f = NULL; #else //ZLIBW FILE *f = NULL; #endif //ZLIBW #ifdef CLUSTER_INSIDES char* occupied = NULL; char* cluster_data = NULL; int cluster_data_len = 0; #endif //get the sizes of structures (they might change in the future) obj_3d_io_size=sizeof(object3d_io); obj_2d_io_size=sizeof(obj_2d_io); lights_io_size=sizeof(light_io); particles_io_size=sizeof(particles_io); //get the number of objects and lights for (i = 0; i < MAX_OBJ_3D; i++) if (objects_list[i]) obj_3d_no++; for (i = 0; i < MAX_OBJ_2D; i++) if (obj_2d_list[i]) obj_2d_no++; for (i = 0; i < MAX_LIGHTS; i++) if (lights_list[i] && !lights_list[i]->locked) lights_no++; // We ignore temporary particle systems (i.e. ones with a ttl) for (i = 0; i < MAX_PARTICLE_SYSTEMS; i++) if (particles_list[i] && particles_list[i]->def && particles_list[i]->def != &def) particles_no++; //ok, now build the header... //clear the header memset (mem_map_header, 0, sizeof (map_header)); //build the file signature cur_map_header.file_sig[0]='e'; cur_map_header.file_sig[1]='l'; cur_map_header.file_sig[2]='m'; cur_map_header.file_sig[3]='f'; cur_map_header.tile_map_x_len=tile_map_size_x; cur_map_header.tile_map_y_len=tile_map_size_y; cur_map_header.tile_map_offset=sizeof(map_header); cur_map_header.height_map_offset=cur_map_header.tile_map_offset+tile_map_size_x*tile_map_size_y; cur_map_header.obj_3d_struct_len=obj_3d_io_size; cur_map_header.obj_3d_no=obj_3d_no; cur_map_header.obj_3d_offset=cur_map_header.height_map_offset+tile_map_size_x*tile_map_size_y*6*6; cur_map_header.obj_2d_struct_len=obj_2d_io_size; cur_map_header.obj_2d_no=obj_2d_no; cur_map_header.obj_2d_offset=cur_map_header.obj_3d_offset+obj_3d_no*obj_3d_io_size; cur_map_header.lights_struct_len=lights_io_size; cur_map_header.lights_no=lights_no; cur_map_header.lights_offset=cur_map_header.obj_2d_offset+obj_2d_no*obj_2d_io_size; cur_map_header.dungeon=dungeon; #if defined CLUSTER_INSIDES || defined NEW_LIGHT_FORMAT cur_map_header.version = LATEST_MAP_VERSION; #endif cur_map_header.ambient_r=ambient_r; cur_map_header.ambient_g=ambient_g; cur_map_header.ambient_b=ambient_b; cur_map_header.particles_struct_len=particles_io_size; #ifdef EYE_CANDY eye_candy_done_adding_effect(); cur_map_header.particles_no=particles_no + get_eye_candy_count(); #else cur_map_header.particles_no=particles_no; #endif cur_map_header.particles_offset=cur_map_header.lights_offset+lights_no*lights_io_size; #ifdef CLUSTER_INSIDES cur_map_header.clusters_offset = cur_map_header.particles_offset + cur_map_header.particles_no * particles_io_size; #endif // ok, now let's open/create the file, and start writing the header... #ifdef ZLIBW { char gzfile_name[1024]; strcpy(gzfile_name, file_name); //strcat(gzfile_name, ".gz"); f= gzopen(gzfile_name, "wb"); } #else //ZLIBW f= fopen(file_name, "wb"); #endif //ZLIBW if (!f) { char msg[500]; snprintf (msg, sizeof(msg), "Could not open file for writing: %s", file_name); LOG_ERROR(msg); } else { #ifdef ZLIBW //write the header gzwrite(f, mem_map_header, sizeof(map_header)); //write the tiles map gzwrite(f, tile_map, tile_map_size_x*tile_map_size_y); //write the heights map gzwrite(f, height_map, tile_map_size_x*tile_map_size_y*6*6); #else //ZLIBW //write the header fwrite(mem_map_header, sizeof(map_header), 1, f); //write the tiles map fwrite(tile_map, tile_map_size_x*tile_map_size_y, 1, f); //write the heights map fwrite(height_map, tile_map_size_x*tile_map_size_y*6*6, 1, f); #endif //ZLIBW #ifdef CLUSTER_INSIDES // Allocate memory for the occupation map, and initialize // it with the tiles and height maps occupied = calloc (tile_map_size_x*tile_map_size_y*6*6, 1); update_occupied_with_tile_map (occupied, tile_map); update_occupied_with_height_map (occupied, height_map); #endif //write the 3d objects j=0; for (i = 0; i < MAX_OBJ_3D; i++) { if (j > obj_3d_no) break; if (objects_list[i]) { char* cur_3do_pointer = (char *) &cur_3d_obj_io; // clear the object memset (cur_3do_pointer, 0, sizeof (object3d_io)); snprintf (cur_3d_obj_io.file_name, sizeof (cur_3d_obj_io.file_name), "%s", objects_list[i]->file_name); cur_3d_obj_io.x_pos = objects_list[i]->x_pos; cur_3d_obj_io.y_pos = objects_list[i]->y_pos; cur_3d_obj_io.z_pos = objects_list[i]->z_pos; cur_3d_obj_io.x_rot = objects_list[i]->x_rot; cur_3d_obj_io.y_rot = objects_list[i]->y_rot; cur_3d_obj_io.z_rot = objects_list[i]->z_rot; cur_3d_obj_io.self_lit = objects_list[i]->self_lit; cur_3d_obj_io.blended = objects_list[i]->blended; cur_3d_obj_io.r = objects_list[i]->color[0]; cur_3d_obj_io.g = objects_list[i]->color[1]; cur_3d_obj_io.b = objects_list[i]->color[2]; #ifdef ZLIBW gzwrite (f, cur_3do_pointer, sizeof(object3d_io)); #else //ZLIBW fwrite (cur_3do_pointer, sizeof(object3d_io), 1, f); #endif //ZLIBW #ifdef CLUSTER_INSIDES update_occupied_with_3d (occupied, i); #endif j++; } } //write the 2d objects j = 0; for (i = 0; i < MAX_OBJ_2D; i++) { if (j > obj_2d_no) break; if (obj_2d_list[i]) { char* cur_2do_pointer = (char *) &cur_2d_obj_io; // clear the object memset (cur_2do_pointer, 0, sizeof (obj_2d_io)); snprintf (cur_2d_obj_io.file_name, sizeof (cur_2d_obj_io.file_name), "%s", obj_2d_list[i]->file_name); cur_2d_obj_io.x_pos = obj_2d_list[i]->x_pos; cur_2d_obj_io.y_pos = obj_2d_list[i]->y_pos; cur_2d_obj_io.z_pos = obj_2d_list[i]->z_pos; cur_2d_obj_io.x_rot = obj_2d_list[i]->x_rot; cur_2d_obj_io.y_rot = obj_2d_list[i]->y_rot; cur_2d_obj_io.z_rot = obj_2d_list[i]->z_rot; #ifdef ZLIBW gzwrite (f, cur_2do_pointer, sizeof (obj_2d_io)); #else //ZLIBW fwrite (cur_2do_pointer, sizeof (obj_2d_io), 1, f); #endif //ZLIBW #ifdef CLUSTER_INSIDES update_occupied_with_2d (occupied, i); #endif j++; } } //write the lights j=0; for (i = 0; i < MAX_LIGHTS; i++) { if (j > lights_no) break; if (lights_list[i] && !lights_list[i]->locked) { char* cur_light_pointer = (char *) &cur_light_io; // clear the object memset (cur_light_pointer, 0, sizeof (light_io)); cur_light_io.pos_x = lights_list[i]->pos_x; cur_light_io.pos_y = lights_list[i]->pos_y; cur_light_io.pos_z = lights_list[i]->pos_z; cur_light_io.r = lights_list[i]->r; cur_light_io.g = lights_list[i]->g; cur_light_io.b = lights_list[i]->b; #ifdef NEW_LIGHT_FORMAT // Insert default values for now cur_light_io.spec_r = 255; cur_light_io.spec_g = 255; cur_light_io.spec_b = 255; cur_light_io.light_dir_z_sign = 0; cur_light_io.quadric_attenuation = 0; cur_light_io.range = 0; cur_light_io.cutoff = -32768; cur_light_io.exponent = 0; cur_light_io.light_dir_x = 0; cur_light_io.light_dir_y = 0; #endif #ifdef ZLIBW gzwrite (f, cur_light_pointer, sizeof (light_io)); #else //ZLIBW fwrite (cur_light_pointer, sizeof (light_io), 1, f); #endif //ZLIBW j++; } } // Write the particle systems j = 0; for (i = 0; i < MAX_PARTICLE_SYSTEMS; i++) { if (j > particles_no) break; if (particles_list[i] && particles_list[i]->def && particles_list[i]->def != &def) { char *cur_particles_pointer = (char *) &cur_particles_io; memset (cur_particles_pointer, 0, sizeof (particles_io)); snprintf (cur_particles_io.file_name, sizeof (cur_particles_io.file_name), "%s", particles_list[i]->def->file_name); cur_particles_io.x_pos = particles_list[i]->x_pos; cur_particles_io.y_pos = particles_list[i]->y_pos; cur_particles_io.z_pos = particles_list[i]->z_pos; #ifdef ZLIBW gzwrite (f, cur_particles_pointer, sizeof (particles_io)); #else //ZLIBW fwrite (cur_particles_pointer, sizeof (particles_io), 1, f); #endif //ZLIBW j++; } } #ifdef EYE_CANDY // Write the eye candy effects for (i = 0; i < get_eye_candy_count (); i++) { char *cur_particles_pointer = (char *) &cur_particles_io; serialize_eye_candy_effect (i, &cur_particles_io); #ifdef ZLIBW gzwrite (f, cur_particles_pointer, sizeof (particles_io)); #else //ZLIBW fwrite (cur_particles_pointer, sizeof (particles_io), 1, f); #endif //ZLIBW } #endif #ifdef CLUSTER_INSIDES // Compute the clusters and save them compute_clusters (occupied); free (occupied); get_clusters (&cluster_data, &cluster_data_len); #ifdef ZLIBW gzwrite (f, cluster_data, cluster_data_len); #else fwrite (cluster_data, cluster_data_len, 1, f); #endif // ZLIBW free (cluster_data); #endif // CLUSTER_INSIDES #ifdef ZLIBW gzclose(f); #else //ZLIBW fclose(f); #endif //ZLIBW } return 1; }
wplist dbscan_clustering_method::get_cluster( const size_t cluster_id, const wplist& points) const { return get_clusters(points)[cluster_id]; }