matlab实现zbar_scan_y

调试基本完成,主要错误原因是matlab无法实现宏定义,预先计算出的宏值和带入公式中计算的结果不一致,四舍五入和C中结果不一样,所以图中有的蓝线和黄线差±1个像素,中间还有两处错误,没找到原因。
matlab实现zbar_scan_y_第1张图片

%zbar_scan_test.m
%在有些位置 
function zbar_scan_test ()
clc;
ZBAR_FIXED = 5;
ROUND = bitshift(1, (ZBAR_FIXED - 1));
ZBAR_SCANNER_THRESH_MIN = 4;
ZBAR_SCANNER_THRESH_INIT_WEIGHT = 0.44;
THRESH_INIT = (((ZBAR_SCANNER_THRESH_INIT_WEIGHT ...      
    * (bitshift(1,ZBAR_FIXED + 1)) + 1) / 2));
ZBAR_SCANNER_THRESH_FADE = 8;
ZBAR_SCANNER_EWMA_WEIGHT = 0.78;
EWMA_WEIGHT = int32(((ZBAR_SCANNER_EWMA_WEIGHT ...             
                   * bitshift(1, (ZBAR_FIXED + 1)) + 1) / 2));
scn = struct('y1_min_thresh',ZBAR_SCANNER_THRESH_MIN, ...
    'x',1, ...
    'y1_sign',0, ...
    'y1_thresh',ZBAR_SCANNER_THRESH_MIN, ...
    'cur_edge',0, ...
    'last_edge',0, ...
    'width',0);            

Img = imread('pic/barcode.bmp');
data = double(Img(50,:));
len = length(data);

y = data(1);
y0 = zeros(1,len);
y0(1:4) = data(1:4);

edge = zeros(1,len);
load('edgeX.mat','edgeX');
edgeY = zeros(1,length(edgeX));
for i=1:length(edgeX)
    edgeY(i) = 100;
end
figure(1);
subplot(211);
plot(data);
hold on;
plot(y0);
stem(edgeX,edgeY);
hold off;
subplot(212);
stem(edge);

for x = 4:len
    scn.x = x - 1;
    y = data(x);
    y01 = y0(x-1);
    % update weighted moving average
    y00 = y01 + bitshift(int32((y-y01) * EWMA_WEIGHT), -ZBAR_FIXED,'int32');
    y0(x) = y00;
    y02 = y0(x-2);
    y03 = y0(x-3);
    % 1st differential @ x-1

    y11 = y01 - y02;
    y12 = y02 - y03;
    if ((abs(y11) <abs(y12)) && ...
        (y11 >= 0) == (y12 >= 0))
        y11 = y12;
    end
    % 2nd differentials @ x-1 & x-2
    y21 = y00 - (y01*2) + y02;
    y22 = y01 - (y02*2) + y03;
    X = sprintf('scan: x=%d y=%d y0=%d y1=%d y2=%d',...
        scn.x,y,y01,y11,y21);disp(X);
    % 2nd zero-crossing is 1st local min/max - could be edge
    y2_rev = ((y21>0)&&(y22<0)) || ((y21<0)&&(y22>0));
    if ((~y21) || ...
        y2_rev) && ...
        (calc_thresh <= abs(y11))
        %check for 1st sign change
        y1_rev = ((scn.y1_sign>0)&&(y11<0)) || ((scn.y1_sign<0)&&(y11>0));
        if y1_rev
            %intensity change reversal - finalize previous edge
           process_edge; 
        end
        if y1_rev || (abs(scn.y1_sign) < abs(y11))
            scn.y1_sign = y11;

            % adaptive thresholding
            % start at multiple of new min/max
            scn.y1_thresh = bitshift(int32(abs(y11)*THRESH_INIT+ROUND),...
                -ZBAR_FIXED,'int32');
            X = sprintf('thr=%d',scn.y1_thresh);disp(X);
            if(scn.y1_thresh < scn.y1_min_thresh)
                scn.y1_thresh = scn.y1_min_thresh;
            end
            % update current edge
            d = y21 - y22;
            scn.cur_edge = bitshift(1,ZBAR_FIXED);
            if ~d
                scn.cur_edge = bitshift(scn.cur_edge,-1);
            else if y21
                    % interpolate zero crossing
                    scn.cur_edge = scn.cur_edge - ...
                        (bitshift(y21,ZBAR_FIXED)+1) / d;
                end
            end
            scn.cur_edge = scn.cur_edge + bitshift(scn.x,ZBAR_FIXED);

            edge(bitshift(int32(scn.cur_edge),-ZBAR_FIXED)) = 50;

        end  
    end

end

figure(1);
subplot(211);
plot(data);
hold on;
plot(y0);
stem(edgeX,edgeY);
hold off;
subplot(212);
stem(edge);
hold on;
stem(edgeX,edgeY);
hold off;
%  nested functions clac_thresh
   function thresh = calc_thresh
        % threshold 1st to improve noise rejection 
        thresh = scn.y1_thresh;
        if(thresh <= scn.y1_min_thresh || ~scn.width)
            thresh = scn.y1_min_thresh;
            return;
        end
        % slowly return threshold to min 
        dx = bitshift(scn.x,ZBAR_FIXED) - scn.last_edge;
        t = thresh * dx;
        t = t / scn.width;
        t = t / ZBAR_SCANNER_THRESH_FADE;
        X = sprintf(' thr=%d t=%ld x=%d last=%d.%d (%d)', ...
            thresh,t,scn.x, ...
            bitshift(scn.last_edge,-ZBAR_FIXED), ...
            bitand(scn.last_edge,(bitshift(1,ZBAR_FIXED)-1)), ...
            dx);disp(X);
        if thresh > t
            thresh = thresh - t;
            if thresh > scn.y1_min_thresh;
                return
            end
        end
        scn.y1_thresh = scn.y1_min_thresh;
        thresh = scn.y1_min_thresh;
        return;          
   end  %end calc_thresh()

    function process_edge
        if ~scn.y1_sign
            scn.cur_edge = bitshift(1,ZBAR_FIXED)+ROUND;
            scn.last_edge = scn.cur_edge;
        else if ~scn.last_edge
                scn.last_edge = scn.cur_edge;
            end
        end
        scn.width = scn.cur_edge - scn.last_edge;
        X = sprintf('sgn=%d cur=%d.%d w=%d ', ...
            scn.y1_sign,bitshift(scn.cur_edge,-ZBAR_FIXED), ...
            bitand(scn.cur_edge,bitshift(1,ZBAR_FIXED)-1), ...
            scn.width);
        if sign(y11) > 0
            X = [X ,'SPACE'];
        else  X = [X, 'BAR'];
        end
        disp(X);
        scn.last_edge = scn.cur_edge;   
    end
end


你可能感兴趣的:(笔记)