Example #1
0
void ns_spine_drawer::draw_mesh(const vector<ns_triangle_d> & mesh, const ns_color_8 & color, const unsigned int resize_factor,ns_image_standard & output){
	//draw triangles
	for (unsigned int i = 0; i < mesh.size(); i++){
		ns_triangle_i val;
		for (unsigned int t = 0; t < 3; t++){
			val.vertex[t].x = (int)(resize_factor*mesh[i].vertex[t].x);
			val.vertex[t].y = (int)(resize_factor*mesh[i].vertex[t].y);
		}
		output.draw_line_color(val.vertex[0],val.vertex[1],color);
		output.draw_line_color(val.vertex[1],val.vertex[2],color);
		output.draw_line_color(val.vertex[2],val.vertex[0],color);
	}
}
Example #2
0
void ns_spine_drawer::draw_normals(const ns_worm_shape & worm, ns_image_standard & output, const unsigned int resize_factor){
	
	const unsigned int o(ns_worm_detection_constants::get(ns_worm_detection_constant::spine_visualization_output_resolution,output.properties().resolution));
	for (unsigned int j = 0; j < worm.nodes.size(); j+=o){
		ns_vector_2i nv[2] = { ns_vector_2i( (int)(worm.normal_0[j].x*resize_factor),
											 (int)(worm.normal_0[j].y*resize_factor)),
							   ns_vector_2i( (int)(worm.normal_1[j].x*resize_factor),
											 (int)(worm.normal_1[j].y*resize_factor))
							 };
		if (nv[0] == ns_vector_2i(0,0) || nv[1] == ns_vector_2i(0,0))
			continue;
		ns_vector_2i c((int)(worm.nodes[j].x*resize_factor),
					   (int)(worm.nodes[j].y*resize_factor));
		output.draw_line_color(c,nv[0]+c, ns_color_8(250,250,250));
		output.draw_line_color(c,nv[1]+c, ns_color_8(250,250,250));
	}
}
void ns_movement_visualization_generator::create_time_path_analysis_visualization(const ns_image_server_captured_image_region & region_image, const ns_death_time_annotation_compiler_region & compiler_region,const ns_image_standard & grayscale, ns_image_standard & out,ns_sql & sql){
	unsigned long thickness = 4;

	ns_image_properties prop(grayscale.properties());
	prop.components = 3;
	out.init(prop);
	for (unsigned int y = 0; y < prop.height; ++y){
		for (unsigned long x = 0; x < prop.width; ++x){
			out[y][3*x+0] = 255-grayscale[y][x];
			out[y][3*x+1] = 255-grayscale[y][x];
			out[y][3*x+2] = 255-grayscale[y][x];
		}
	}


/*	ns_death_time_annotation_set movement_annotations;
//	movement_annotations.events.reserve(death_time_annotations.size());
//	for (unsigned long i = 0; i < death_time_annotations.size(); i++){

		switch(death_time_annotations[i].type){
			case ns_fast_moving_worm_observed:
			case ns_slow_moving_worm_observed:
			case ns_posture_changing_worm_observed:
			case ns_stationary_worm_observed:
					movement_annotations.push_back(death_time_annotations[i]);
			}
	}
*/
	
	ns_image_worm_detection_results results;
	results.id = region_image.region_detection_results_id;
	results.load_from_db(false,sql);
	ns_image_server_captured_image_region region_t(region_image);
	results.load_images_from_db(region_t,sql);
	const std::vector<const ns_detected_worm_info *> detected_worms(results.actual_worm_list());
	ns_font & font(font_server.default_font());
	const unsigned long font_height(25);
	font.set_height(font_height);

	std::vector<const ns_death_time_annotation *> representative_state_event_for_location(compiler_region.locations.size(),0);
	for (unsigned int i = 0; i < compiler_region.locations.size(); i++){
		for (unsigned int j = 0; j < compiler_region.locations[i].annotations.size(); j++){
			if (ns_movement_event_is_a_state_observation(compiler_region.locations[i].annotations[j].type) && 
								compiler_region.locations[i].annotations[j].time.period_end == region_image.capture_time){
				if (representative_state_event_for_location[i] != 0){
					cerr << "Found multiple state events for a time!\n";
				}
				else representative_state_event_for_location[i] = &compiler_region.locations[i].annotations[j];
			}
		}
	}
	
	std::vector<const ns_death_time_annotation *> fast_moving_animal_matches(detected_worms.size(),0);
	for (unsigned int i = 0; i < compiler_region.fast_moving_animals.size(); i++){
		for (unsigned long w = 0; w < detected_worms.size(); w++){
			if (detected_worms[w]->region_size == compiler_region.fast_moving_animals[i].size &&
				detected_worms[w]->region_position_in_source_image == compiler_region.fast_moving_animals[i].position){
				fast_moving_animal_matches[w] = &compiler_region.fast_moving_animals[i];
			}
		}
	}

	
	std::vector<ns_death_time_annotation_compiler_region::ns_location_list::const_iterator> location_matches(detected_worms.size(),compiler_region.locations.end());
	unsigned long unmatched_detected_worms(0);
	for (unsigned long w = 0; w < detected_worms.size(); w++){
		for (unsigned int i = 0; i < representative_state_event_for_location.size(); i++){
			if (representative_state_event_for_location[i] == 0)
				continue;
			if (detected_worms[w]->region_size == representative_state_event_for_location[i]->size &&
				detected_worms[w]->region_position_in_source_image == representative_state_event_for_location[i]->position){
					if(location_matches[w] != compiler_region.locations.end()){
						cerr << "Found multiple locations that match detected worm!\n";
					}
					else{
						location_matches[w] = compiler_region.locations.begin()+i;
					}
			}
		}
		if (fast_moving_animal_matches[w] == 0 && location_matches[w]== compiler_region.locations.end())
			unmatched_detected_worms++;
	}
	if (unmatched_detected_worms > 0)
		cerr << "Could not match up " << unmatched_detected_worms << " of " << detected_worms.size() << " animals.\n";
	
	for (unsigned long w = 0; w < detected_worms.size(); w++){
		const ns_death_time_annotation_compiler_region::ns_location_list::const_iterator location(location_matches[w]);
		const ns_death_time_annotation * fast_animal_match(fast_moving_animal_matches[w]);
		const ns_vector_2i & pos = detected_worms[w]->region_position_in_source_image;
		//if we can't find info on the object, paint it white.
		if (fast_animal_match == 0 && location== compiler_region.locations.end()){
			const ns_color_8 color(255,255,255);
			ns_vector_2i size = detected_worms[w]->region_size;
			out.draw_line_color(pos,pos+ns_vector_2i(size.x,0),color,3);
			out.draw_line_color(pos,pos+ns_vector_2i(0,size.y),color,3);
			out.draw_line_color(pos+ns_vector_2i(0,size.y),pos+size,color,3);
			out.draw_line_color(pos+ns_vector_2i(size.x,0),pos+size,color,3);
			
			continue;
		}

		ns_color_8  color;
		if (location != compiler_region.locations.end()){
			color = (ns_movement_colors::color(ns_movement_event_state(representative_state_event_for_location[location-compiler_region.locations.begin()]->type)));
			if (location->properties.is_excluded())
			color = ns_color_8(50,50,255);
		}
		else color = ns_movement_colors::color(ns_movement_fast);


		for (unsigned int y = 0; y < detected_worms[w]->bitmap().properties().height; y++){
			for (unsigned int x = 0; x < detected_worms[w]->bitmap().properties().width; x++){
				if (detected_worms[w]->bitmap()[y][x]){
					out[pos.y + y][3*(pos.x + x)+0]
						= (ns_8_bit)(.75*color.x + .25*out[pos.y + y][3*(pos.x + x)+0]);
					out[pos.y + y][3*(pos.x + x)+1]
						= (ns_8_bit)(.75*color.y + .25*out[pos.y + y][3*(pos.x + x)+1]);
					out[pos.y + y][3*(pos.x + x)+2]
						= (ns_8_bit)(.75*color.z + .25*out[pos.y + y][3*(pos.x + x)+2]);
				}
			}
		}
		ns_color_8 edge_color(color);
		if (location != compiler_region.locations.end() &&
			location->properties.number_of_worms_at_location_marked_by_hand > 1){
		//	font.draw_color(pos.x + (detected_worms[w]->region_size.x*3)/4,pos.y+font_height,ns_color_8(255,255,255),std::string("") + 
		//		ns_to_string(location->properties.number_of_worms_at_location_marked_by_hand),out);
			edge_color = ns_color_8(255,180,120);
			const int edge_width(3);
			for (unsigned int y = 0; y < detected_worms[w]->edge_bitmap().properties().height; y++){
				for (unsigned int x = 0; x < detected_worms[w]->edge_bitmap().properties().width; x++){
					if (detected_worms[w]->edge_bitmap()[y][x]){
						for (int dx = -edge_width; dx <= edge_width; dx++)
							for (int dy = -edge_width; dy <= edge_width; dy++){
								if ( dx + dy > edge_width)
									continue; //round edges
								if (x + dx < 0 || x + dx >= detected_worms[w]->edge_bitmap().properties().width)
									continue;
								if (y + dy < 0 || y + dy >= detected_worms[w]->edge_bitmap().properties().height)
									continue;
								out[pos.y + y+dy][3*(pos.x + x+dx)+0]
									= (ns_8_bit)(.2*(ns_8_bit)(edge_color.x) + .8*out[pos.y + y+dy][3*(pos.x + x+dx)+0]);
								out[pos.y + y+dy][3*(pos.x + x+dx)+1]
									= (ns_8_bit)(.2*(ns_8_bit)(edge_color.y) + .8*out[pos.y + y+dy][3*(pos.x + x+dx)+1]);
								out[pos.y + y+dy][3*(pos.x + x+dx)+2]
									= (ns_8_bit)(.2*(ns_8_bit)(edge_color.z) + .8*out[pos.y + y+dy][3*(pos.x + x+dx)+2]);
							}
					}
				}
			}
		}		
	}
}
Example #4
0
void ns_spine_drawer::draw_spine(const ns_image_standard & img, const ns_segment_cluster & seg, const ns_worm_shape & worm, ns_image_standard & output, const unsigned int resize_factor){
	
	ns_image_standard im2;
	im2.init(img.properties());
	for (unsigned int y = 0; y < im2.properties().height; y++){
		for (unsigned int x = 0; x < im2.properties().components*im2.properties().width; x++){
			im2[y][x] = img[y][x];
		}
	}

	ns_image_properties outprop = im2.properties();
	outprop.height*=resize_factor;
	outprop.width*=resize_factor;
	outprop.resolution*=resize_factor;
	outprop.components = 3;
	
	//cerr << "Drawing spine RF:" << resize_factor << "(" << outprop.width << "," << outprop.height << ")\n";
	output.init(outprop);

	//enlarge bitmap.
	if (im2.properties().components == 1){
		//b&w image
		for (unsigned int y = 0; y < im2.properties().height; y++){
			for (unsigned int x = 0; x < im2.properties().width; x++)
				for (unsigned int r_y = 0; r_y < resize_factor; r_y++)
					for (unsigned int r_x = 0; r_x < resize_factor; r_x++){
						for (unsigned int c = 0; c < 3; c++)
							output[resize_factor*y + r_y][3*(resize_factor*x+r_x)+c] = im2[y][x];
						#ifdef NS_DRAW_BITMAP_EDGES
						if (edge_bitmap[y][x]!=0){
								output[resize_factor*y + r_y][3*(resize_factor*x+r_x)  ] = 255;
								output[resize_factor*y + r_y][3*(resize_factor*x+r_x)+1] = 0;
								output[resize_factor*y + r_y][3*(resize_factor*x+r_x)+2] = 255;
						}
						#endif
					}
		}
	}
	else{
		//color image
		for (unsigned int y = 0; y < im2.properties().height; y++){
			for (unsigned int x = 0; x < im2.properties().width; x++)
				for (unsigned int r_y = 0; r_y < resize_factor; r_y++)
					for (unsigned int r_x = 0; r_x < resize_factor; r_x++)
						for (unsigned int c = 0; c < 3; c++)
							output[resize_factor*y + r_y][3*(resize_factor*x+r_x)+c] = im2[y][3*x+c];
		}


	}


	#ifdef NS_DRAW_SPINE_NORMALS
	ns_color_8 dk_gray(60,70,80);
	#else
	ns_color_8 dk_gray(170,170,255);
	#endif
	ns_color_8 red(200,15,0);
	ns_color_8 yellow(255,255,30);
	ns_color_8 pink(200,0,200);

	//draw triangles
	//draw_mesh(mesh,dk_gray,resize_factor,output);

	ns_vector_2i vertex[2];
	for(unsigned int i = 0; i < seg.segments.size(); i++){
		if (seg.segments.size() == 0)continue;
		unsigned int j;
		vertex[0].x = (int)(seg.segments[i]->nodes[0].position.x * resize_factor);
		vertex[0].y = (int)(seg.segments[i]->nodes[0].position.y * resize_factor);
		for (j = 1; j < seg.segments[i]->nodes.size(); j++){
			vertex[1].x = (int)(seg.segments[i]->nodes[j].position.x * resize_factor);
			vertex[1].y = (int)(seg.segments[i]->nodes[j].position.y * resize_factor);
			output.draw_line_color(vertex[0],vertex[1], ns_rainbow<ns_color_8>(((float)i+1)/(float)(seg.segments.size()+1))*.8);
			vertex[0] = vertex[1];
		}
	}
	unsigned int end_d(ns_worm_detection_constants::get(ns_worm_detection_constant::worm_end_node_margin,im2.properties().resolution));

	//draw spines
	ns_color_8 end_color_offset(30,10,10);
	ns_color_8 shadow_offset(30,30,30);
	ns_vector_2i offset(1,0);

	ns_color_8 color = ns_rainbow<ns_color_8>(0,(float).05),
			   shadow = ns_color_8::safe_subtraction(color,shadow_offset);
	
	if (worm.nodes.size() != 0){
		vertex[0].x = (int)(worm.nodes[0].x * resize_factor);
		vertex[0].y = (int)(worm.nodes[0].y * resize_factor);
		for (unsigned int i = 0; i < (unsigned int )worm.nodes.size(); i++){
			vertex[1].x = (int)(worm.nodes[i].x * resize_factor);
			vertex[1].y = (int)(worm.nodes[i].y * resize_factor);
			if (i == 1 || i == worm.nodes.size() -1)
				output.draw_line_color(vertex[0],vertex[1], ns_color_8::safe_subtraction(color,end_color_offset),1); //draw endpoints a different color to allow loop disambiguation
			else 
				output.draw_line_color(vertex[0], vertex[1],color,1);
			vertex[0] = vertex[1];	
		}
	}
}