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); }