Question

I'm trying to make a barcode scanner in matlab. In a barcode every white bar is 1 and every black bar is 0. i'm trying to get these bars . But this is the problem:

enter image description here

as you can see the bars are not the same width one time they are 3 pixels ... then 2 pixels etc ... And to make it even worse they differ in images too. So my question is . How can i get the values of these bars without knowing the width of 1 bar. Or how do i give them all the same width. (2 of the same bars can be next to eachother). It's not possible to detect the transition between bars because a transition is possible after a certain amount of pixels ... and then there can be another bar or the same bar. But because it's not possible to know this certain amount of pixels it's not possible to detect a transition. It's also not possible to work with some kind of window because the bars have no standard width. So how can i normalize this ?

A barcode : enter image description here

thx in advance !

Was it helpful?

Solution

Let's assume that the bars are strictly vertical (as in your example). Here is a possible workflow:

%# 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;

UPDATE

To get relative bar width we can devide width in pixels to minimum bar width:

barwidth = xwidth ./ min(xwidth);

I believe it's good assumption that there always will be a bar on width 1.

If you won't get integer value (due to noise, for example), try to round the numbers to closest integer and get residuals. You can summarize those residuals to get quality assessment of recognition.

Some clustering algorithm (like k-mean clustering) might also work well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top