function [mat2]=halftone_color (type,mat,thresh,nois,serp,BNM_size,sharp) switch type case 1 mat2=(mat>thresh); case 2 white=round(255*rand(size(mat,1),size(mat,2),3)); h=fspecial('lagrangian'); m = conv2(mat(:,:,1),h); m=m(2:size(m)-1,2:size(m)-1); mat(:,:,1)=mat(:,:,1)-sharp*m; mat(:,:,1)=max(0,min(255,mat(:,:,1))); m = conv2(mat(:,:,2),h); m=m(2:size(m)-1,2:size(m)-1); mat(:,:,2)=mat(:,:,2)-sharp*m; mat(:,:,2)=max(0,min(255,mat(:,:,2))); m = conv2(mat(:,:,3),h); m=m(2:size(m)-1,2:size(m)-1); mat(:,:,3)=mat(:,:,3)-sharp*m; mat(:,:,3)=max(0,min(255,mat(:,:,3))); mat2=(mat>white); case 3 template=[[13 11 12 15];[4 3 2 9];[5 0 1 10];[8 6 7 14]]; template=[template (31-template)]; template=[template;(31-template)]; mat2(:,:,1)=temp(template,mat(:,:,1)); mat2(:,:,2)=temp(template,mat(:,:,2)); mat2(:,:,3)=temp(template,mat(:,:,3)); case 4 template=[[0 14 3 13];[8 4 11 7];[2 12 1 15];[10 6 9 5]]; mat2(:,:,1)=temp(template,mat(:,:,1)); mat2(:,:,2)=temp(template,mat(:,:,2)); mat2(:,:,3)=temp(template,mat(:,:,3)); case 5 mat2(:,:,1)=err_diff(mat(:,:,1),thresh,nois,serp); mat2(:,:,2)=err_diff(mat(:,:,2),thresh,nois,serp); mat2(:,:,3)=err_diff(mat(:,:,3),thresh,nois,serp); case 6 Jarvis = [0 0 0 7 5;3 5 7 5 3;1 3 5 3 1]; Jarvis = Jarvis/sum(sum(Jarvis)); mat2(:,:,1)=FloydSteinberg(Jarvis,thresh,mat(:,:,1)/255,nois); mat2(:,:,2)=FloydSteinberg(Jarvis,thresh,mat(:,:,2)/255,nois); mat2(:,:,3)=FloydSteinberg(Jarvis,thresh,mat(:,:,3)/255,nois); case 7 mat2=halftone_color(4,mat,thresh,nois,serp); mat2(:,:,1)=lsmb(mat2(:,:,1),mat(:,:,1)); mat2(:,:,2)=lsmb(mat2(:,:,1),mat(:,:,2)); mat2(:,:,3)=lsmb(mat2(:,:,1),mat(:,:,3)); case 8 mat2=halftone_color_visual(1,mat,thresh,nois,serp,BNM_size,sharp); case 9 mat2 = halftone_color_visual(5,mat,thresh,nois,serp,BNM_size,sharp); case 10 vc=process(BNM_size); h=fspecial('lagrangian'); m = conv2(mat(:,:,1),h); m=m(2:size(m)-1,2:size(m)-1); mat(:,:,1)=mat(:,:,1)-sharp*m; mat(:,:,1)=max(0,min(255,mat(:,:,1))); mat2(:,:,1)=temp(vc,mat(:,:,1)); vc=process(BNM_size); m = conv2(mat(:,:,2),h); m=m(2:size(m)-1,2:size(m)-1); mat(:,:,2)=mat(:,:,2)-sharp*m; mat(:,:,2)=max(0,min(255,mat(:,:,2))); mat2(:,:,2)=temp(vc,mat(:,:,2)); vc=process(BNM_size); m = conv2(mat(:,:,3),h); m=m(2:size(m)-1,2:size(m)-1); mat(:,:,3)=mat(:,:,3)-sharp*m; mat(:,:,3)=max(0,min(255,mat(:,:,3))); mat2(:,:,3)=temp(vc,mat(:,:,3)); case 11 mat2=halftone_color_visual(3,mat,thresh,nois,serp,BNM_size,sharp); otherwise mat2=mat; end function [mat2]=temp (template,mat) % nice tricks played so that one can provide template and images with any sizes % and it will still works its way out [b1 b2]=size(template); [l1 l2]=size(mat); mat0=mat; mat=zeros(b1*ceil(l1/b1),b2*ceil(l2/b2)); mat(1:l1,1:l2)=mat0; x=max(max(template)); for i=1:ceil(l1/b1) for j=1:ceil(l2/b2) mat2(((i-1)*b1+1):(i*b1),((j-1)*b2+1):(j*b2))=(mat(((i-1)*b1+1):(i*b1),((j-1)*b2+1):(j*b2))>((template+1/2/255*(x<1)+1/2*(x>=1))*255/x)); end end mat2=mat2(1:l1,1:l2); function [mat2]=err_diff(mat,thresh,nois,serp) [l1,l2]=size(mat); %serpentine order mat0=zeros(l1+2,l2+2); mat0(2:(l1+1),2:(l2+1))=mat; err=mat0; mat2=mat0; if nois noise=rand(l1,l2)-1/2; else noise=zeros(l1,l2); end a=7/16*(1+noise); b=1/16*(1+fliplr(noise)); c=5/16*(1+flipud(noise)); d=3/16*(1+fliplr(flipud(noise))); for i=2:(l1+1) if (2*floor(i/2)==i)|(~serp) for j=2:(l2+1) mat0(i,j)=mat0(i,j)+a(i-1,j-1)*err(i,j-1)+b(i-1,j-1)*err(i-1,j-1)+c(i-1,j-1)*err(i-1,j)+d(i-1,j-1)*err(i-1,j+1); mat2(i-1,j-1)=mat0(i,j)>thresh; err(i,j)=mat0(i,j)-mat2(i-1,j-1)*255; end else for j=(l2+1):-1:2 mat0(i,j)=mat0(i,j)+a(i-1,j-1)*err(i,j+1)+b(i-1,j-1)*err(i-1,j+1)+c(i-1,j-1)*err(i-1,j)+d(i-1,j-1)*err(i-1,j-1); mat2(i-1,j-1)=mat0(i,j)>thresh; err(i,j)=mat0(i,j)-mat2(i-1,j-1)*255; end end end mat2=mat2(1:l1,1:l2);