matlab实现zbar_scan_y

来源:互联网 发布:电视挂墙高度知乎 编辑:程序博客网 时间:2024/06/05 21:18

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

%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;endfigure(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      endendfigure(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;       endend
0 0