Example #1
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);
}