Matlab: Barcode scanner
-
05-03-2021 - |
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:
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 :
thx in advance !
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.