void adjust_sigma(Simulator *sim, int steps, double step_size,
				  double factor)
{
	double original_sigma = sim->sigma;
	double best_sigma = sim->sigma;
	double best_error = barcode_error(sim);
	for (int step = -steps; step <= steps; step++) {
		if (step == 0)
			continue;
		sim->sigma = original_sigma + step * step_size;
		if (sim->sigma < 1.0)
			continue;
		compute_kernel(sim);
		convolve_1d(sim->kernel_width, sim->kernel,
					sim->width, sim->guess, sim->blur, 0, sim->width);
		double error = barcode_error(sim);
		// printf("sigma=%.2f error=%.2f\n", sim->sigma, error);
		if (error < best_error) {
			best_error = error;
			best_sigma = sim->sigma;
		}
	}
	sim->sigma = best_sigma * factor + original_sigma * (1.0 - factor);
	compute_kernel(sim);
	convolve_1d(sim->kernel_width, sim->kernel,
				sim->width, sim->guess, sim->blur, 0, sim->width);
}
int guess_digit(Simulator *sim, int *sections, int index,
				int choices_count, char *choices)
{
	// printf("guess_digit start=%d stop=%d\n", sections[0], sections[7]);
	int start = sim->changes_count;
	int best_choice = -1;
	double best_error = UNKNOWN;
	for (int choice = 0; choice < choices_count; choice++) {
		encode_bits(sim->width, sim->black, sim->white, sim->guess,
					sections, 7, choices[choice]);
		convolve_1d(sim->kernel_width, sim->kernel,
					sim->width, sim->guess, sim->blur,
					sections[0], sections[7]);
		double error = samples_error(sim, sections[0], sections[7]);
		if (error < best_error) {
			best_choice = choice;
			best_error = error;
		}
		sim->changes[sim->changes_count].error = error;
		sim->changes[sim->changes_count].index = index;
		sim->changes[sim->changes_count].digit = choice;
		sim->changes_count++;
	}
	// Make all changes relative to the best choice.
	for (int i = start; i < sim->changes_count; i++)
		sim->changes[i].error -= sim->changes[start + best_choice].error;
	// Remove the best choice from the changes array.
	if (best_choice < choices_count - 1)
		sim->changes[start + best_choice] =
			sim->changes[start + choices_count - 1];
	sim->changes_count--;
	return best_choice;
}
Exemple #3
0
Rle<double>
convolve_1d(Rle<double> &rle,
            std::vector<double> const& kernel,
            bool rescale, double eps) {
    std::vector<double> tmp = rle.expand();
    std::vector<double> result = convolve_1d(tmp, kernel, rescale);
    return Rle<double>(result, eps);
}
void simulate_range(Simulator *sim, int start, int stop)
{
	// printf("simulate_range start=%d stop=%d\n", start, stop);
	int x = start;
	int next_section = 0;
	while (next_section < 96 && x > sim->sections[next_section])
		next_section++;
	while (x < stop) {
		// printf("start=%d x=%d stop=%d sections[%d]=%d\n",
		//        start, x, stop, next_section, sim->sections[next_section]);
		if (next_section <= 0) {	// Left shoulder.
			for (; x < sim->sections[0]; x++)
				sim->guess[x] = sim->white[x];
			next_section = 1;
		} else if (next_section <= 3) {	// Left guard bars.
			encode_bits(sim->width, sim->black, sim->white, sim->guess,
						&sim->sections[0], 3, 0x5);
			next_section = 4;
		} else if (next_section <= 45) {	// Left six digits.
			int i = (next_section - 4) / 7;
			encode_bits(sim->width, sim->black, sim->white, sim->guess,
						&sim->sections[3 + 7 * i], 7,
						LG[(int)sim->digits[1 + i]]);
			next_section = 3 + 7 * i + 8;
		} else if (next_section <= 50) {	// Middle guard bars.
			encode_bits(sim->width, sim->black, sim->white, sim->guess,
						&sim->sections[45], 5, 0xa);
			next_section = 51;
		} else if (next_section <= 92) {	// Right six digits.
			int i = (next_section - 51) / 7;
			encode_bits(sim->width, sim->black, sim->white, sim->guess,
						&sim->sections[50 + 7 * i], 7,
						R[(int)sim->digits[7 + i]]);
			next_section = 50 + 7 * i + 8;
		} else if (next_section <= 95) {	// Right guard bars.
			encode_bits(sim->width, sim->black, sim->white, sim->guess,
						&sim->sections[92], 3, 0x5);
			next_section = 96;
		} else {				// Right shoulder.
			for (; x < stop; x++)
				sim->guess[x] = sim->white[x];
			break;
		}
		x = sim->sections[next_section - 1];
	}
	convolve_1d(sim->kernel_width, sim->kernel,
				sim->width, sim->guess, sim->blur, start, stop);
}
void correct_errors(Simulator *sim, int max_changes, int max_count)
{
	if (is_valid_barcode(sim->digits))
		return;
	qsort(sim->changes, sim->changes_count, sizeof(Change), compare_float);
	// for (int i = 0; i < 10; i++)
	//   printf("error=%.6f index=%d digit=%d\n",
	//          changes[i].error, changes[i].index, changes[i].digit);
	if (sim->changes_count > max_count)
		sim->changes_count = max_count;
	// Terminate search for valid candidate.
	sim->changes[sim->changes_count].index = -1;
	best_valid_barcode(sim->changes, max_changes, sim->digits);
	encode_ean13(sim->width, sim->black, sim->white, sim->guess,
				 sim->sections, sim->digits);
	convolve_1d(sim->kernel_width, sim->kernel,
				sim->width, sim->guess, sim->blur, 0, sim->width);
	sim->checksum = ean13_checksum(sim->digits);
}
void guess_digits(Simulator *sim)
{
	// printf("guess_digits...\n");
	sim->changes_count = 0;
	sim->digits[0] = 0;
	for (int i = 0; i < 6; i++) {
		sim->digits[1 + i] =
			guess_digit(sim, &sim->sections[3 + i * 7], 1 + i, i ? 20 : 10,
						LG);
		sim->digits[7 + i] =
			guess_digit(sim, &sim->sections[50 + i * 7], 7 + i, 10, R);
	}
	encode_ean13(sim->width, sim->black, sim->white, sim->guess,
				 sim->sections, sim->digits);
	convolve_1d(sim->kernel_width, sim->kernel,
				sim->width, sim->guess, sim->blur, 0, sim->width);
	sim->digits[0] = ean13_first_digit(sim->digits);
	sim->checksum = ean13_checksum(sim->digits);
	memcpy(sim->unchanged_digits, sim->digits, 13);
}