Matlab: сканер штрих-кода

Я пытаюсь сделать сканер штрих-кода в Matlab. В штрих-коде каждая белая полоса равна 1, а каждая черная полоса равна 0. Я пытаюсь получить эти полосы. Но вот проблема:

введите здесь описание изображения

как вы можете видеть, полосы не имеют одинаковой ширины, один раз они составляют 3 пикселя ... затем 2 пикселя и т. д. ... И, что еще хуже, они также различаются по изображениям. Итак, мой вопрос. Как я могу получить значения этих баров, не зная ширины 1 бара. Или как мне дать им все одинаковую ширину. (2 одинаковых бара могут быть рядом друг с другом). Невозможно обнаружить переход между полосами, потому что возможен переход через определенное количество пикселей... а затем может быть другая полоса или та же полоса. Но поскольку невозможно узнать это определенное количество пикселей, невозможно обнаружить переход. Также невозможно работать с каким-либо окном, потому что полосы не имеют стандартной ширины. Итак, как я могу нормализовать это?

Штрих-код: введите здесь описание изображения

Спасибо заранее!


person Olivier_s_j    schedule 21.11.2011    source источник
comment
Можешь выложить полное изображение? или часть с большим количеством баров?   -  person yuk    schedule 21.11.2011
comment
Если ваша полоса имеет ширину в два пикселя, ваше разрешение слишком низкое для какой-либо осмысленной обработки.   -  person Phonon    schedule 22.11.2011
comment
Может быть, вы можете вычислить среднюю интенсивность M, а затем для каждого пикселя p проверить, равна ли его интенсивность I(p)>1.1*M или I(p)<0.9*M.   -  person cyborg    schedule 22.11.2011
comment
Я в настоящее время исправил это с помощью среднего, это дает достойный результат. Но я сомневаюсь, что это всегда даст правильный результат.   -  person Olivier_s_j    schedule 22.11.2011


Ответы (1)


Предположим, что столбики строго вертикальны (как в вашем примере). Вот возможный рабочий процесс:

%# read the file
filename = 'CW4li.jpg';
x = imread(filename);
%# convert to grayscale
x = rgb2gray(x);

%# get only the bars area
xend = find(diff(sum(x,2)),1);
x(xend:end,:) = [];

%# sum intensities along the bars
xsum = sum(x);

%# threshold the image by half of all pixels intensities
th = ( max(xsum)-min(xsum) ) / 2;
xth = xsum > th;

%# find widths
xstart = find(diff(xth)>0);
xstop = find(diff(xth)<0);
if xstart(1) > xstop(1)
    xstart = [1 xstart];
end
if xstart(end) > xstop(end)
    xstop = [xstop numel(xth)];
end

xwidth = xstop-xstart;

%# look at the histogram
hist(xwidth,1:12)

%# it's clear that single bar has 2 pixels (can be automated), so
barwidth = xwidth / 2;

ОБНОВЛЕНИЕ

Чтобы получить относительную ширину полосы, мы можем разделить ширину в пикселях на минимальную ширину полосы:

barwidth = xwidth ./ min(xwidth);

Я считаю хорошим предположением, что всегда будет полоса шириной 1.

Если вы не получите целочисленное значение (например, из-за шума), попробуйте округлить числа до ближайшего целого числа и получить остатки. Вы можете суммировать эти остатки, чтобы получить оценку качества распознавания.

Некоторый алгоритм кластеризации (например, кластеризация k-mean) также может работать хорошо.

person yuk    schedule 22.11.2011
comment
у меня есть что-то похожее, но есть изображения, на которых невозможно увидеть, составляет ли ширина 2 пикселя полосы, и они слишком сильно различаются. Я думаю, что замена 2 в последней строке на среднее значение будет решением. (Как работает мое решение) - person Olivier_s_j; 22.11.2011