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_process_dynamic_stretch(ns_image_standard & im){
	unsigned char new_top(250),
				  new_bottom(155);
	unsigned char up(255-new_top);
	unsigned char diff(new_top - new_bottom);

	for (unsigned int y = 0; y < im.properties().height; y++){
		for (unsigned int x = 0; x < im.properties().width; x++){
			unsigned char c(255-im[y][x]);
			if (c>new_top)c=new_top;
			else if (c<new_bottom)c=new_bottom;
			im[y][x] = (ns_8_bit)((255*(long)(c-new_bottom))/diff);
		}
	}
}
Example #3
0
void ns_detected_object_manager::remove_objects_found_in_static_mask(const ns_image_standard & static_mask){
	
	vector<ns_detected_object *> objects_to_sort;
	objects_to_sort.assign(objects.begin(),objects.end());
	objects.resize(0);

	vector<ns_detected_object *> not_in_static_mask;
	not_in_static_mask.reserve(objects.size());
	try{

		for (unsigned int i = 0; i < objects_to_sort.size(); i++){
			unsigned int mask_overlay(0),
						 total_area(0);

			if (objects_to_sort[i]->size.x > objects_to_sort[i]->bitmap().properties().width
				|| objects_to_sort[i]->size.y > objects_to_sort[i]->bitmap().properties().height)
				throw ns_ex("Specified object: (position:") << objects_to_sort[i]->offset_in_source_image.x <<  "," << objects_to_sort[i]->offset_in_source_image.y << "; size: " 
								<< objects_to_sort[i]->size.x << "," << objects_to_sort[i]->size.y << ") is larger than it's bitmap " <<
								objects_to_sort[i]->bitmap().properties().width << "," << objects_to_sort[i]->bitmap().properties().height;

				if (objects_to_sort[i]->offset_in_source_image.x + objects_to_sort[i]->size.x > static_mask.properties().width
					|| objects_to_sort[i]->offset_in_source_image.y + objects_to_sort[i]->size.y > static_mask.properties().height)
						throw ns_ex("Specified object: (position:") << objects_to_sort[i]->offset_in_source_image.x <<  "," << objects_to_sort[i]->offset_in_source_image.y << "; size: " 
								<< objects_to_sort[i]->size.x << "," << objects_to_sort[i]->size.y << ") lies outside the static mask " <<
								objects_to_sort[i]->bitmap().properties().width << "," << objects_to_sort[i]->bitmap().properties().height;

			for (unsigned int y = 0; y < objects_to_sort[i]->size.y; y++){
				for (unsigned int x = 0; x < objects_to_sort[i]->size.x; x++){
					total_area+=objects_to_sort[i]->bitmap()[y][x];
					mask_overlay+= static_mask[y+objects_to_sort[i]->offset_in_source_image.y][x+objects_to_sort[i]->offset_in_source_image.x] 
									&& objects_to_sort[i]->bitmap()[y][x];
				}
			}
			if (10*mask_overlay > 5*total_area){
				//object is in the static mask.
				ns_safe_delete(objects_to_sort[i]);
			}
			else{
				not_in_static_mask.push_back(objects_to_sort[i]);
				objects_to_sort[i] = 0;
			}
		}
		objects_to_sort.clear();
		//put all the objects we want to keep back in the objects vector.
		objects.assign(not_in_static_mask.begin(),not_in_static_mask.end());
	}
	catch(...){
		//if we encounter a problem, put all the elements we've kept and all those we haven't looked at yet back into the object vector.
		objects.assign(not_in_static_mask.begin(),not_in_static_mask.end());
		for (vector<ns_detected_object *>::iterator p = objects_to_sort.begin(); p != objects_to_sort.end(); ++p){
			if (*p == 0) continue;
			objects.push_back(*p);
		}
	}

}
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_svg & svg){
	
	//draw grayscale
	svg.draw_rectangle(ns_vector_2d(0,0),ns_vector_2d(img.properties().width,img.properties().height)*svg_dx,ns_color_8(0,0,0),ns_color_8(0,0,0),1,false);
	svg.start_group();
	for (unsigned int y = 0; y < img.properties().height; y++)
		for (unsigned int x = 0; x < img.properties().width; x++)
			if (img[y][x]!=0)
			svg.draw_rectangle(ns_vector_2d(svg_dx*x,svg_dx*y),ns_vector_2d(svg_dx*(x+1),svg_dx*(y+1)),ns_color_8(img[y][x],img[y][x],img[y][x]),
																					   ns_color_8(img[y][x],img[y][x],img[y][x]),1,false);

	svg.end_group();
	ns_vector_2d vertex[2];
	for(unsigned int i = 0; i < seg.segments.size(); i++){
		if (seg.segments.size() == 0)continue;
		vector<ns_vector_2d> points(seg.segments[i]->nodes.size());
		for (unsigned int j = 0; j < seg.segments[i]->nodes.size(); j++)
			points[j] = seg.segments[i]->nodes[j].position*svg_dx;
		svg.draw_poly_line(points,ns_rainbow<ns_color_8>(((float)i+1)/(float)(seg.segments.size()+1))*.8);
	}

	unsigned int end_d(ns_worm_detection_constants::get(ns_worm_detection_constant::worm_end_node_margin,3200));

	//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){
		vector<ns_vector_2d> points(worm.nodes.size());
		for (unsigned int i = 0; i < worm.nodes.size(); i++)
			points[i] = worm.nodes[i]*svg_dx;
		svg.draw_poly_line(points,color);
	}
}
Example #5
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));
	}
}
Example #6
0
string ns_barcode_decode_done(const ns_image_standard & im, const string & debug_image_filename){
	//ns_save_image("c:\\bar_debug.tif",im);
	unsigned long c(im.properties().components);
	unsigned long w(im.properties().width);
	unsigned long h(im.properties().height);

	DmtxImage *image(dmtxImageMalloc(im.properties().width, im.properties().height));
	try{
		if (image == NULL)
			throw ns_ex("Could not persuade dmtxlib to allocate an image of dimentions ") << im.properties().width <<"x" << im.properties().height;
		if (image->height != im.properties().height || image->width != im.properties().width){
			throw ns_ex("Requested an image of dimentions ") << im.properties().width <<"x" << im.properties().height << "; dmtx produced an image of dimentions "
				<< image->width  << "x" << image->height;
			
		}
		for (unsigned int y = 0; y < h; y++)
			for (unsigned int x = 0; x < w; x++){
				image->pxl[y*w+x][0] = im[y][c*x];
				image->pxl[y*w+x][1] = im[y][c*x];
				image->pxl[y*w+x][2] = im[y][c*x];
			}
		string ret =  run_dmtx_decode(image);
		if (ret.size() != 0)
			return ret;
		//if we can't find a barcode, check to see if there has been a mirror-image reflection.
		for (unsigned int y = 0; y < h; y++)
			for (unsigned int x = 0; x < w; x++){
				image->pxl[y*w+x][0] = im[y][c*(w-x-1)];
				image->pxl[y*w+x][1] = im[y][c*(w-x-1)];
				image->pxl[y*w+x][2] = im[y][c*(w-x-1)];
			}
		string name(run_dmtx_decode(image));
		delete image;
		return name;
	}
	catch(...){
		delete image;
		throw;
	}
}
void ns_out_frame_count(ns_image_standard & im, const unsigned long number_of_frames_used_to_find_stationary_objects, const unsigned long frame_count){
	ns_xml_simple_writer xml;
	xml.add_header();
	xml.add_tag("frame_count",frame_count);
	xml.add_tag("number_of_frames_used_to_find_stationary_objects",number_of_frames_used_to_find_stationary_objects);
	xml.add_footer();
	im.set_description(xml.result());
	/*
	ns_32_bit time_points_l = (ns_32_bit)frame_count;
	if ((ns_32_bit)frame_count > ((ns_32_bit)0)-1)
		frame_count = ((ns_32_bit)0)-1;
	ns_8_bit * tp = reinterpret_cast<ns_8_bit *>(&time_points_l);
	//place number of frames used to calculate heat map in bitmap
	im[0][0] = tp[0];
	im[0][1] = tp[1];
	im[0][2] = tp[2];
	im[0][3] = tp[3];
	im[0][4] = tp[0];
	im[0][5] = tp[1];*/
}
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;
	
	const ns_color_8 excluded_color = ns_color_8(50,50,255);

	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,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];
			}
		}
	}

	//for debugging
	std::vector<char> locations_matched(representative_state_event_for_location.size(),0);
	unsigned long locations_with_matches(0);
	//for real use
	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{
						//for debugging
						locations_matched[i] = 1;
						locations_with_matches++;
						//for real use
						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_thick(pos,pos+ns_vector_2i(size.x,0),color,3);
			out.draw_line_color_thick(pos,pos+ns_vector_2i(0,size.y),color,3);
			out.draw_line_color_thick(pos+ns_vector_2i(0,size.y),pos+size,color,3);
			out.draw_line_color_thick(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 = excluded_color;
		}
		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);
			// use signed ints for x and y so that "x + dx" type expressions are also properly signed.
			for (int y = 0; y < detected_worms[w]->edge_bitmap().properties().height; y++){
				for (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]);
							}
					}
				}
			}

		}	
	}
	for (unsigned int i = 0; i < compiler_region.locations.size(); i++){
		if (representative_state_event_for_location[i] == 0 || locations_matched[i])
			continue;
		const ns_death_time_annotation & a(*representative_state_event_for_location[i]);
		if (compiler_region.locations[i].properties.inferred_animal_location){
			ns_color_8 color = ns_movement_colors::color(ns_movement_event_state(a.type));
			if (compiler_region.locations[i].properties.is_excluded())
				color = excluded_color;
			unsigned long thickness = 4;
			out.draw_line_color_thick(a.position,a.position + ns_vector_2i(a.size.x,0),color,thickness,.8);
			out.draw_line_color_thick(a.position,a.position + ns_vector_2i(0,a.size.y),color,thickness,.8);
			out.draw_line_color_thick(a.position+ns_vector_2i(a.size.x,0),a.position + ns_vector_2i(a.size.x,a.size.y),color,thickness,.6);
			out.draw_line_color_thick(a.position+ns_vector_2i(0,a.size.y),a.position + ns_vector_2i(a.size.x,a.size.y),color,thickness,.6);
		}
	}
}
void ns_movement_visualization_generator::create_survival_curve_for_capture_time(const long marker_time_t, const ns_region_metadata & metadata,
	const ns_survival_data_with_censoring & plate, const ns_survival_data_with_censoring & strain, const std::vector<unsigned long > & plate_time, 
	const std::vector<unsigned long> & strain_time,const std::string & title, const bool draw_dark,const bool optimize_for_small_graph, ns_image_standard & image,ns_graph & graph) const{
	//if (!data.set_is_on_common_time())
	//	throw ns_ex("ns_movement_visualization_generator::create_survival_curve_for_capture_time()::requires data to be on a common time set");
	
	unsigned long plate_last_death(0),strain_last_death(0);
	for (unsigned int i = 0; i < plate.data.number_of_animals_at_risk.size(); i++){
		plate_last_death = i;
		if (plate.data.number_of_animals_at_risk[i] == 0)
			break;
	}
	for (unsigned int i = 0; i < strain.data.number_of_animals_at_risk.size(); i++){
		strain_last_death = i;
		if (strain.data.number_of_animals_at_risk[i] == 0)
			break;
	}
	
	if (plate_time.size() == 0)
		throw ns_ex("ns_movement_visualization_generator::create_survival_curve_for_capture_time()::The supplied plate time vector is empty");

	unsigned long latest_time(plate_time[plate_last_death]);
	if (!strain_time.empty())
	if (latest_time < strain_time[strain_last_death])
		latest_time = strain_time[strain_last_death];

	unsigned long marker_time(marker_time_t);
	if (marker_time > latest_time)
		marker_time = latest_time;

	ns_graph_object	plate_survival(ns_graph_object::ns_graph_dependant_variable),
					strain_survival(ns_graph_object::ns_graph_dependant_variable),
					plate_marker(ns_graph_object::ns_graph_dependant_variable),
					strain_marker(ns_graph_object::ns_graph_dependant_variable),
					censored_markers(ns_graph_object::ns_graph_dependant_variable);

	plate_survival.y.resize(plate_last_death+1+1);
	plate_survival.x.resize(plate_last_death+1+1);
	strain_survival.y.resize(strain_last_death+1+1,0);
	strain_survival.x.resize(strain_last_death+1+1,0);
	//plate_marker.y.resize(plate_time.size()+1,-1);
	//plate_marker.x.resize(plate_time.size()+1,-1);
	//strain_marker.y.resize(strain_time.size()+1,-1);
	//strain_marker.x.resize(strain_time.size()+1,-1);
	unsigned long censored_size = plate_last_death;
	if (censored_size < strain_last_death)
		censored_size = strain_last_death;
	censored_markers.y.resize(censored_size+1+1,-1);
	censored_markers.x.resize(censored_size+1+1,-1);
	plate_marker.y.resize(1,-1);
	plate_marker.x.resize(1,-1);
	strain_marker.y.resize(1,-1);
	strain_marker.x.resize(1,-1);


	
	


	unsigned long plate_marker_index(0),
				  strain_marker_index(0);
	for (unsigned int i = 0; i <= plate_last_death; i++){
		if (marker_time >= plate_time[i]){
			plate_marker_index = i;
		}
		else break;
	}	
	for (unsigned int i = 0; i < strain_last_death; i++){
		if (marker_time >= strain_time[i]){
			strain_marker_index = i;

		}
		else break;
	}

	const unsigned long  total_strain_deaths(strain.data.total_number_of_deaths),
					total_plate_deaths(plate.data.total_number_of_deaths),
					total_strain_censored(strain.data.total_number_of_censoring_events),
					total_plate_censored(plate.data.total_number_of_censoring_events),
					number_of_strain_deaths((strain_marker_index<strain_time.size())?strain.data.cumulative_number_of_deaths[strain_marker_index]:0),
					number_of_plate_deaths((plate_marker_index<plate_time.size())?plate.data.cumulative_number_of_deaths[plate_marker_index]:0);

	const double plate_fraction_surviving((plate_marker_index<plate_time.size())?plate.data.probability_of_surviving_up_to_interval[plate_marker_index]:0),
			strain_fraction_surviving((strain_marker_index<strain_time.size())?strain.data.probability_of_surviving_up_to_interval[strain_marker_index]:0);
	unsigned long number_of_strain_censored(0),
				  number_of_plate_censored(0);
	if (strain_marker_index<= strain_last_death && !strain_time.empty()){
		for (unsigned int i = 0; i <= strain_marker_index; i++)
			number_of_strain_censored+=strain.data.number_of_censoring_events[i];
	}
	if (plate_marker_index<= plate_last_death){
		for (unsigned int i = 0; i <= plate_marker_index; i++)
			number_of_plate_censored+=plate.data.number_of_censoring_events[i];
	}


	plate_survival.y[0] = strain_survival.y[0] = 1;
	censored_markers.x[0] = plate_marker.x[0] = strain_marker.x[0] = plate_survival.x[0] = strain_survival.x[0] = 0;

	for (unsigned int i = 0; i < plate_survival.y.size()-1; i++){
		plate_survival.y[i+1] = plate.data.probability_of_surviving_up_to_interval[i];
		if (plate_survival.y[i] <= 0)
			plate_survival.y[i+1] = -1;
		plate_survival.x[i+1] = (plate_time[i]-metadata.time_at_which_animals_had_zero_age)/60.0/60.0/24.0;
		plate_marker.x[0] = (marker_time-metadata.time_at_which_animals_had_zero_age)/60.0/60.0/24.0;
		censored_markers.x[i+1] = (plate_time[i]-metadata.time_at_which_animals_had_zero_age)/60.0/60.0/24.0;
		if (i == plate_marker_index)
			plate_marker.y[0] = plate.data.probability_of_surviving_up_to_interval[i];
	}
	if (!strain_time.empty())
	for (unsigned int i = 0; i < strain_survival.y.size()-1; i++){
		strain_survival.y[i+1] = strain.data.probability_of_surviving_up_to_interval[i];
		if (strain_survival.y[i] <= 0)
			strain_survival.y[i+1] = -1;
		strain_survival.x[i+1] = (strain_time[i]-metadata.time_at_which_animals_had_zero_age)/60.0/60.0/24.0;
		strain_marker.x[0] = (marker_time-metadata.time_at_which_animals_had_zero_age)/60.0/60.0/24.0;
		if (i == strain_marker_index)
			strain_marker.y[0] = strain.data.probability_of_surviving_up_to_interval[i];
	}
	//for (unsigned int i = 0; i < strain_survival.y.size()-1; i++){
	//	if (strain.data.number_of_censoring_events[i] > 0)
	//		censored_markers.y[i+1] = strain.data.probability_of_surviving_up_to_interval[i];
	//}

	


	//kaplan meyer plots show the number of individuals left alive up to the time point measured.  Thus the marker should							  
	//be at the bottom of the vertical steps on the plot.
	
	

	

	plate_survival.properties.point.draw = false;
	plate_survival.properties.line.draw = true;
	plate_survival.properties.line.width = 4;
	plate_survival.properties.line_hold_order = ns_graph_properties::ns_zeroth;
	plate_survival.properties.draw_vertical_lines = ns_graph_properties::ns_outline;
	plate_survival.properties.draw_negatives = false;
	graph.x_axis_properties.text_decimal_places = 0;
	graph.y_axis_properties.text_decimal_places = 0;
	if (draw_dark){
		graph.x_axis_properties.line.color=ns_color_8(255,255,255);
		graph.x_axis_properties.text.color=ns_color_8(255,255,255);
		graph.x_axis_properties.text.draw = true;
		graph.x_axis_properties.point.color=ns_color_8(255,255,255);
		graph.x_axis_properties.area_fill.color=ns_color_8(0,0,0);
		graph.y_axis_properties = 
			graph.area_properties = 
			graph.title_properties = 
			graph.x_axis_properties;
		
	}
	if (optimize_for_small_graph){
		graph.x_axis_properties.text_size*=4;
		graph.y_axis_properties.text_size*=4;
		graph.area_properties.text_size*=4;
		graph.x_axis_properties.line.width*=4;
		graph.y_axis_properties.line.width*=4;
		graph.area_properties.line.width*=4;
		plate_survival.properties.line.width*=4;
	}
	strain_survival.properties = plate_survival.properties;
	if (draw_dark){
		plate_survival.properties.line.color=ns_color_8(255,255,0);
		strain_survival.properties.line.color=ns_color_8(200,0,0);
	}
	else{
		plate_survival.properties.line.color=ns_color_8(0,0,0);
		strain_survival.properties.line.color=ns_color_8(50,0,0);
	}

	plate_marker.properties = plate_survival.properties;
	plate_marker.properties.line.draw = 0;
	plate_marker.properties.area_fill.draw = 0;
	plate_marker.properties.point.draw = true;
	plate_marker.properties.point.color = plate_marker.properties.area_fill.color;
	plate_marker.properties.point.width = 15 + 10*(int)optimize_for_small_graph;
	plate_marker.properties.point.edge_width = plate_marker.properties.point.width/3;
	plate_marker.properties.point.edge_color = ns_color_8(255,255,255);
	plate_marker.properties.draw_negatives = false;
	censored_markers.properties = strain_marker.properties = plate_marker.properties;
	censored_markers.properties.point.color = plate_survival.properties.line.color;
	censored_markers.properties.point.point_shape = ns_graph_color_set::ns_vertical_line;

	ns_graph_object graph_x_axis(ns_graph_object::ns_graph_independant_variable);

	/*
	unsigned long index_at_which_all_plate_animals_are_dead(strain_survival.y.size());
	for (unsigned int i = 0; i < strain_survival.y.size(); i++){
		if (strain_survival.y[i] < .001){
			index_at_which_all_plate_animals_are_dead = i;
		}
	}
	index_at_which_all_plate_animals_are_dead=(5*index_at_which_all_plate_animals_are_dead)/4;
	if (index_at_which_all_plate_animals_are_dead>strain_survival.y.size())
		index_at_which_all_plate_animals_are_dead = strain_survival.y.size();

	graph_x_axis.x.resize(index_at_which_all_plate_animals_are_dead );
	strain_survival.y.resize(index_at_which_all_plate_animals_are_dead );
	strain_marker.y.resize(index_at_which_all_plate_animals_are_dead );
	plate_survival.y.resize(index_at_which_all_plate_animals_are_dead );
	plate_marker.y.resize(index_at_which_all_plate_animals_are_dead );
	*/

//	graph.contents.push_back(graph_x_axis);
	graph.contents.push_back(censored_markers);
	if (!strain_time.empty()){
		graph.contents.push_back(strain_survival);
		graph.contents.push_back(strain_marker);
	}
	graph.contents.push_back(plate_survival);
	graph.contents.push_back(plate_marker);

	
	if (image.properties().height > 0){
		const unsigned long number_of_lines(7);
		ns_font & font(font_server.default_font());
		font.set_height(image.properties().height/ number_of_lines);

		for (unsigned int y = 0; y <  image.properties().height; y++){
			for (unsigned int x = 0; x <  3*image.properties().width; x++){
				image[y][x] = 0;
			}
		}
		string text;
		text = "Age: ";
		const unsigned long seconds_since_birth(marker_time - metadata.time_at_which_animals_had_zero_age);
		float age = seconds_since_birth/(24*60*60.0);
		string units(" days");
		if (seconds_since_birth < 4*24*60*60){
			age = seconds_since_birth/(60*60.0);
			units = " hours";
		}
		unsigned long line_num(1);
		text += ns_to_string_short(age,2) + units;
		font.draw_color(8,line_num*image.properties().height/(number_of_lines-1),ns_color_8(255,255,255),text,image);
		line_num++;
		text = "Plate Survival: ";
		text += ns_to_string_short(plate_fraction_surviving,2);
		font.draw_color(8,line_num*image.properties().height/(number_of_lines-1),ns_color_8(255,255,255),text,image);
		line_num++;
		text = "Plate Dead: ";
		text += ns_to_string( number_of_strain_deaths);
		text += "/";
		text += ns_to_string( total_strain_deaths);
		font.draw_color(8,line_num*image.properties().height/(number_of_lines-1),ns_color_8(255,255,255),text,image);
		line_num++;
		text = "Plate Censored: ";
		text += ns_to_string( number_of_strain_censored);
		text += "/";
		text += ns_to_string( total_strain_censored);
		font.draw_color(8,line_num*image.properties().height/(number_of_lines-1),ns_color_8(255,255,255),text,image);
		line_num++;
		if (!strain_time.empty()){
			text = "Strain Survival: ";
			text += ns_to_string_short(strain_fraction_surviving,2);
			font.draw_color(8,line_num*image.properties().height/(number_of_lines-1),ns_color_8(255,255,255),text,image);
		}
	}

}
//A heat map is generated by summing all thresholded frames of a time series.  For the first
//third of the time series, treshold values are added to the red channel of the heat map.
//for the second third of the time series, threshold values are added to the green channel
//for the final, blue.
//This means we can roughly inspect which pixels are constantly bright for the biggining, middle, or end
//of the experiment.
//This function looks for pixels that were bright for a specified fraction of each third of the experiment.
//Such bright pixels, if situated in a region where at least one pixel was bright in the two other thirds
//of the experiment, are added to the output image.
//The output image can then be used to mask out unwanted "static" pixels that represent
//features such as the plate edge or dust.
void ns_worm_multi_frame_interpolation::generate_static_mask_from_heatmap(const ns_image_standard & im, ns_image_standard & out){
	const unsigned int	spatial_smudge_distance(ns_worm_detection_constants::get(ns_worm_detection_constant::allowed_drift_distance_for_objects_during_static_mask_creation)),
						early_strong_threshold(ns_worm_detection_constants::get(ns_worm_detection_constant::proportion_of_early_time_points_present_required_during_static_mask_creation)),  //out of 10
						middle_threshold(ns_worm_detection_constants::get(ns_worm_detection_constant::proportion_of_middle_time_points_present_required_during_static_mask_creation)), //out of 10
						late_threshold(ns_worm_detection_constants::get(ns_worm_detection_constant::proportion_of_late_time_points_present_required_during_static_mask_creation));  //out of 10
	if (im.properties().width < 2 || im.properties().height == 0)
		throw ns_ex("ns_worm_multi_frame_interpolation::Empty heat map was provided");

	
	ns_32_bit number_of_frames_used_to_make_heatmap(0);
	ns_32_bit number_of_frames_used_to_find_stationary_objects(0);

	ns_32_bit time_points_l = 0;
	if (im.properties().description.size() != 0){
		//load frame information from xml spec
		bool found_total(false),
			 found_begin_count(false);
		ns_xml_simple_object_reader xml;
		xml.from_string(im.properties().description);
		for (unsigned int i = 0; i < xml.objects.size(); i++){
			if (xml.objects[i].name == "frame_count"){
				number_of_frames_used_to_make_heatmap = atol(xml.objects[i].value.c_str());
				found_total = true;
			}
			else if (xml.objects[i].name =="number_of_frames_used_to_find_stationary_objects"){
				number_of_frames_used_to_find_stationary_objects = atol(xml.objects[i].value.c_str());
				found_begin_count = true;
			}
		}
		if (!found_total)
			throw ns_ex("ns_worm_multi_frame_interpolation::generate_static_mask_from_heatmap::Could not find total frame count specification in heat map");
		if (!found_begin_count)
			throw ns_ex("ns_worm_multi_frame_interpolation::generate_static_mask_from_heatmap::Could not find number_of_frames_used_to_find_stationary_objects specification in heat map");
	}
	else{
		throw ns_ex("Old style heat maps no longer supported!");
		//old style heatmaps stored pixel information in the first five pixels of the image.
		ns_8_bit a=im[0][0],
			b=im[0][1],
			c=im[0][2],
			d=im[0][3],
			e=im[0][4],
			f=im[0][5];
		if (im[0][0] != im[0][4] || im[0][1] != im[0][5])
			throw ns_ex("ns_worm_multi_frame_interpolation::Could not find watermark specifiying source frame count");	
		ns_8_bit * fr = reinterpret_cast<ns_8_bit *>(&number_of_frames_used_to_make_heatmap);
		fr[0] = im[0][0];
		fr[1] = im[0][1];
		fr[2] = im[0][2];
		fr[3] = im[0][3];
		if (number_of_frames_used_to_make_heatmap < 30)
			 number_of_frames_used_to_find_stationary_objects = number_of_frames_used_to_make_heatmap;
		else if (number_of_frames_used_to_make_heatmap < 90)
			number_of_frames_used_to_find_stationary_objects = number_of_frames_used_to_make_heatmap/3;
		number_of_frames_used_to_find_stationary_objects = number_of_frames_used_to_make_heatmap/9;
	}



	//number_of_frames_used_to_make_heatmap = 306;
	ns_number_of_frames_in_heatmap number_of_frames(number_of_frames_used_to_find_stationary_objects,number_of_frames_used_to_make_heatmap);

	/*cerr << number_of_frames_used_to_make_heatmap << " frames used in heat map, divided into " 
		<< number_of_frames.early << ", "<< number_of_frames.middle << ", and " << number_of_frames.late << "\n";
*/
	if (im.properties().components != 3)
		throw ns_ex("ns_image_server_calculate_heatmap_overlay::Heatmaps must be in color");
	ns_image_properties p(im.properties());
	p.components = 1;
	out.prepare_to_recieve_image(p);

	for (int y = 0; y < (int)p.height; y++){
		for (int x = 0; x < (int)p.width; x++){
			const bool	found_early(10*((unsigned int)im[y][3*x  ]) >= early_strong_threshold*number_of_frames.early),
						found_middle(10*((unsigned int)im[y][3*x+1]) >= middle_threshold*number_of_frames.middle),
						found_late(10*((unsigned int)im[y][3*x+2]) >= late_threshold*number_of_frames.late);
			if(!found_early &&!found_middle &&!found_late){
				out[y][x] = 0;
				continue;
			}

			int x0(x-spatial_smudge_distance),
				x1(x+spatial_smudge_distance),
				y0(y-spatial_smudge_distance),
				y1(y+spatial_smudge_distance);
			if (x0 < 0) x0 = 0;
			if (x1 >= (int)p.width) x1 = (int)p.width-1;
			if (y0 < 0) y0 = 0;
			if (y1 >= (int)p.height) y1 = (int)p.height-1;
			bool cont(true);
			out[y][x] = 0;

			for (int _y = y0; _y < y1 && cont; _y++){
				for (int _x = x0; _x < x1 && cont; _x++){
					if(	10*((unsigned int)im[_y][3*_x  ]) >= early_strong_threshold*number_of_frames.early ||
						(found_early && 
							(10*((unsigned int)im[_y][3*_x+1]) >= middle_threshold*number_of_frames.middle ||
							10*((unsigned int)im[_y][3*_x+2]) >= late_threshold*number_of_frames.late)
						)
					){

						out[y][x] = 255;
						cont = false;
					}
				}
			}
		}
	}
}
void ns_worm_multi_frame_interpolation::generate_heat_map(ns_image_standard & heat_map_out,const unsigned int number_of_frames_used_to_find_stationary_objects_,ns_sql & sql){
	if (time_points.size() == 0)
		throw ns_ex("ns_worm_multi_frame_interpolation::generate_heat_map::No time points available!");
	unsigned long number_of_frames_used_to_find_stationary_objects(number_of_frames_used_to_find_stationary_objects_);
	//0 indicates that the algorithm should choose the best number of points to use

	if (time_points.size() <= 2 && number_of_frames_used_to_find_stationary_objects != 1)
			throw ns_ex("Cannot calculate static mask for such a small number of frames:" ) << time_points.size();

	//if not stationary object frame count is specified, determine one automatically
	if (number_of_frames_used_to_find_stationary_objects_ == 0){
		//for very short experiments (ie heat shock) use a short time interval
		if (time_points.size() < 60)
			number_of_frames_used_to_find_stationary_objects = 3;
		else{
			if (number_of_frames_used_to_find_stationary_objects_ > time_points.size())
				number_of_frames_used_to_find_stationary_objects = time_points.size()/5;
		
			if (number_of_frames_used_to_find_stationary_objects==0)
				number_of_frames_used_to_find_stationary_objects = 2;
		}
	}

	//get image size for heatmap from first threshold
	bool size_loaded = false;
	ns_image_properties heat_map_size;
	for (unsigned int i = 0; i < time_points.size(); i++){
		try{
			//cerr << "Loading heat_map size from time_point " << i << "\n";
			time_points[i]->load_threshold(sql);
			heat_map_size = time_points[i]->threshold.properties();
			size_loaded = true;
			break;
		}
		catch(ns_ex & ex){
			cerr << "Could not open threshold frame for size info: " << ex.text() << "\n";
		}
	}
	if (!size_loaded)
		throw ns_ex("ns_worm_multi_frame_interpolation::generate_heat_map()::Sample region has no usable images!");

	heat_map_size.components = 3;
	heat_map_out.prepare_to_recieve_image(heat_map_size);
	
	for (unsigned int y = 0; y < heat_map_size.height; y++)
			for (unsigned int x = 0; x < 3*heat_map_size.width; x++)
				heat_map_out[y][x] = 0;
	unsigned int i = 0;
	for (std::vector<ns_worm_interpolation_timepoint *>::iterator p = time_points.begin();;){
		//stop at one element before the end.
		std::vector<ns_worm_interpolation_timepoint *>::iterator end_p = time_points.end();
		end_p--;
		if (p == end_p) break;
		try{

			cerr << "Processing frame " << i+1 << "/" << time_points.size() << "\n";
			if (i != 0)
				(*p)->load_threshold(sql);
		}
		catch(ns_ex & ex){
			cerr << ex.text() << "\n";
			p = time_points.erase(p);
			continue;
		}
		for (long y = 0; y < (long)(*p)->threshold.properties().height; y++){
			for (long  x = 0; x < (long)(*p)->threshold.properties().width; x++){
				long color = ns_get_division_from_frame_number(i,number_of_frames_used_to_find_stationary_objects,(unsigned int)time_points.size());
				if ((*p)->threshold[y][x] && heat_map_out[y][3*x+color] < 255)
					heat_map_out[y][3*x+color]++;
			}
		}
		(*p)->clear_threshold();
		p++;
		i++;
	}
	ns_out_frame_count(heat_map_out,number_of_frames_used_to_find_stationary_objects,(unsigned long)time_points.size());
	
}
Example #12
0
void ns_barcode_encoder::encode(const string & str, ns_image_standard & image, const unsigned int margin_size){
	#ifdef NS_USE_2D_SCANNER_BARCODES
		DmtxEncode encode;
		encode = dmtxEncodeStructInit();
		unsigned char * a(new unsigned char[str.size()+1]);
		try{
			for (unsigned int i = 0; i < str.size(); i++)
				a[i] = str[i];
			a[str.size()] = 0;
			cerr << "Encoding " << a << "\n";
			dmtxEncodeDataMatrix(&encode, (int)str.size(), a, DMTX_SYMBOL_SQUARE_AUTO);
			image.prepare_to_recieve_image(ns_image_properties(encode.image->height+2*margin_size,
															 encode.image->width+2*margin_size,
															 1,150));
			for (unsigned int y = 0; y < image.properties().height; y++)
				for (unsigned int x = 0; x < image.properties().width; x++)
					image[y][x] = 255;

			for (unsigned int y = margin_size; y < image.properties().height-margin_size; y++)
				for (unsigned int x = margin_size; x < image.properties().width-margin_size; x++)
					image[y][x] = encode.image->pxl[encode.image->width*(y-margin_size) + (x-margin_size)][0];

			ns_font & font(font_server.default_font());
			font.draw(margin_size+10,margin_size + encode.image->height + 10,ns_color_8(125,125,125),str,image);

			
			dmtxEncodeStructDeInit(&encode);
			delete[] a;
		}
		catch(...){
			
			dmtxEncodeStructDeInit(&encode);
			delete[] a;
			throw;
		}
	#else
	const unsigned w[3] = {3,6,12};
	const unsigned int spacing = w[1];

	vector <unsigned int> bar_widths;

	for (unsigned int i = 0; i < str.size(); i++){
		unsigned int v;
		if (str[i] == '_')
			v = 26;
		else v = str[i]-'a';
		bar_widths.push_back( w[(v/9)%3]);
		bar_widths.push_back( w[(v/3)%3]);
		bar_widths.push_back( w[(v  )%3]);
	}
	unsigned int total_width = 0;
	for(unsigned int i = 0; i < bar_widths.size(); i++)
		total_width += bar_widths[i] + spacing;
	ns_image_properties prop;
	prop.width = total_width + 2*margin_size;
	prop.height = height*2 + 2*margin_size;
	prop.components = 1;
	prop.resolution = 150;
	image.prepare_to_recieve_image(prop);
	for (unsigned int y = 0; y < prop.height; y++)
		for (unsigned int x = 0; x < prop.width; x++)
			image[y][x] = 255;
	unsigned int x = 0;
	for (unsigned int i = 0; i < bar_widths.size(); i++){
		for (unsigned int y = 0; y < height; y++)
			for (unsigned int dx = 0; dx < bar_widths[i]; dx++)
				image[y+margin_size][x+margin_size+dx] = 0;
		x += bar_widths[i];
		for (unsigned int y = 0; y < height; y++)
			for (unsigned int dx = 0; dx < spacing; dx++)
				image[y+margin_size][x+margin_size+dx] = 255;
		x += spacing;
	}
	font.draw(margin_size,height*3/2+margin_size,ns_color_8(0,0,0),str,image);
	#endif

}
Example #13
0
string ns_barcode_decode(const ns_image_standard & image, const string & debug_image_filename){
	unsigned char  c = image.properties().components;	
	ns_image_properties p(image.properties());

	/*ns_histogram<unsigned long,ns_8_bit> hist;
	for (unsigned int y = 0; y < p.height;  y++){
		for (unsigned int x = 0; x < p.width; x+=c){
			hist[ image[y][x] ]++;
		}
	}
	
	unsigned int max,min;
	for (min = 0; min < hist.size(); min++)
		if (hist[min] != 0)break;

	for (max = hist.size(); max > 1; max--)
		if (hist[max] != 0)break;*/
	unsigned char thresh = 125;

	//build the vertical intensity profile of the image
	//we're looking for the top and bottom of the barcode strip.
	vector<unsigned int> profile(p.height,0);
	for (unsigned int y = 0; y < p.height; y++)
		for (unsigned int x = 0; x < c*p.width; x+=c)
			profile[y]+=image[y][x] >= thresh;
	
	vector<unsigned int> profile_smoothed(p.height,0);
	ns_smooth_series<unsigned int, 48>(profile,profile_smoothed,0);
	
	int bottom(0), 
		top((int)profile_smoothed.size()-1);

	for (int i = (int)profile_smoothed.size()/2; i >=0; i--){
		if (profile[i] >= profile[bottom])
			bottom = i;
	}
	for (int i = (int)profile_smoothed.size()/2; i < (int)profile_smoothed.size(); i++){
		if (profile[i] >= profile[top])
			top = i;
	}
	unsigned int b_old(bottom),
				 t_old(top);
	if (b_old >= t_old)
		throw ns_ex("ns_barcode_decode::Could not register barcode (vertical)");

	bottom = b_old;//bottom + (t_old-b_old)/4;
	top = t_old;//top - (t_old-b_old)/4;

	unsigned int b_marge = bottom + (t_old-b_old)/4,
				 t_marge = top    - (t_old-b_old)/4;

	//calculate median intensity of bright area
	ns_histogram<unsigned long,ns_8_bit> hist;
	for (int y= bottom; y < top; y++)
		for (unsigned int x = 0; x < p.width; x++)
			hist[image[y][c*x]]++;
	hist.set_number_of_pixels((top-bottom)*p.width);
	ns_8_bit bright = (ns_8_bit)((3*(unsigned int)hist.median_from_histogram())/5);

	//calculate 10th percentile
	unsigned int tenth(0);
	unsigned int tenth_count(0);
	for (tenth = 0; tenth< hist.size(); tenth++){
		tenth_count+= hist[tenth] > 50;
		if (tenth_count > 10)
			break;
	}

	//bright = tenth;

	//find start of bright region at left
	unsigned int l_old(0),r_old(p.width);
	//find l_old edge
	for (unsigned int x = 0; x < p.width/2; x++){
		unsigned int sum = 0;
		for (unsigned int y = b_marge; y < t_marge; y++)
			sum+= image[y][c*x];
		if (sum >= bright*( t_marge-b_marge)){
			l_old = x;
			break;
		}
		if (l_old != 0) 
			break;
	}

	//find the end of the dark region (the barcode) at right
	unsigned int dark_cut = tenth*3*( t_marge-b_marge);
	for (int x = l_old; x < (int)p.width ; x++){
		unsigned int sum = 0;
		for (unsigned int y =  b_marge; y < t_marge; y++)
			sum+= image[y][c*x];
		if (sum <= dark_cut){
			r_old = x;
		}
	}

	//find r_old edge
	/*for (int x = (int)p.width-1; x > (int)p.width/2 ; x--){
		unsigned int sum = 0;
		for (unsigned int y =  b_marge; y < t_marge; y++)
			sum+= image[y][c*x];
		if (sum >= bright*( t_marge-b_marge)){
			r_old = x;
			break;
		}
		if (r_old != p.width)
			break;
	}*/

	/*for (unsignj
	unsigned long window = p.width/12;
	int start = l_old - window;
	int stop =  r_old + window;
	if (start < 0)
		start = window;
	if (stop > p.width)
		stop = p.width - window;

	vector<unsigned int> scores(stop-start);
	for (int x = start; x < stop; x++){
		unsigned int vertical_mean(0);
		unsigned int vertical_varience(0);
		
			for (unsigned int y = bottom; y < top; y++)
				vertical_mean+=image[y][x+window];
		vertical_mean/=((2*window+1)*(top-bottom));
	

	}*/

	
	unsigned int left = (11*l_old)/10,
	//			 right = r_old - ((11*(p.width-r_old))/10);
		right = r_old + (p.width-r_old)/25;
	if (left >= right)
		throw ns_ex("ns_barcode_decode::Could not register barcode (horizontal)");
	
	string dbg2_filename;
	if (debug_image_filename.size() != 0){
		ns_image_standard im;
		image.pump(im,1024);
		for (int y = bottom; y < top;  y++){
			im[y][left] = 255*(y%2);
			im[y][right] = 255*(y%2);
		}
		for (unsigned int x = left; x < right; x++){
			im[bottom][x] = 255*(x%2);
			im[top][x] = 255*(x%2);
		}
		/*
		ns_image_storage_reciever_handle<ns_8_bit> processing_out(image_server.image_storage.request_volatile_storage(debug_image_filename,1024,false));
		im.pump(processing_out.output_stream(),1024);	
		dbg2_filename = ns_dir::extract_filename_without_extension(debug_image_filename) + "2." + ns_dir::extract_extension(debug_image_filename);*/
	}
	


	ns_image_bitmap bmp;
	ns_image_properties bprop(p);
	bprop.components = 1;
	bprop.width = right-left;
	bprop.height = top-bottom;
	bmp.prepare_to_recieve_image(bprop);

	const unsigned int read_height(4);

	for (unsigned int y = 0; y < read_height;  y++)
		for (unsigned int x = 0; x < bprop.width; x++)
		bmp[y][x] = 0;

	for (unsigned int y = read_height; y < bprop.height-read_height;  y++){
		for (unsigned int x = 0; x < bprop.width; x++){
			const int b(y - read_height);
			const int t(y + read_height);
			int sum(0);
			for (int i = b; i < t; i++)
				sum+= image[i+bottom][c*left+c*x];
			bmp[y][x] = (sum <= (t-b)*thresh);

		}
	}
	for (unsigned int y = 0; y < read_height; y++)
		for (unsigned int x = 0; x < bprop.width; x++)
		bmp[bprop.height-1-y][x] = 0;


	return ns_barcode_decode(bmp,dbg2_filename);
}
Example #14
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];	
		}
	}
}