├── Bias Correction(Li) ├── 5.bmp ├── A Level Set Method for Image Segmentation__in the Presence of Intensity Inhomogeneities__With Application to MRI.pdf ├── Demo.m ├── Demo_MultiPhase.m ├── Heaviside.m ├── MICO_v0 │ ├── MICO.pdf │ ├── MICO_2D │ │ ├── Demo_MICO.m │ │ ├── MICO.m │ │ ├── brainweb59.tif │ │ ├── brainweb64.tif │ │ ├── brainweb67.tif │ │ ├── brainweb72.tif │ │ ├── brainweb78.tif │ │ ├── brainweb79.tif │ │ ├── brainweb83.tif │ │ ├── brainweb90.tif │ │ ├── brainweb91.tif │ │ ├── brainweb92.tif │ │ ├── brainweb97.tif │ │ ├── getBasisOrder3.m │ │ ├── getBasisOrder4.m │ │ ├── get_energy.m │ │ ├── mprage171.tif │ │ ├── mprage178.tif │ │ ├── mprage271.tif │ │ ├── mprage276.tif │ │ ├── mprage371.tif │ │ ├── mprage381.tif │ │ ├── myBrain127.tif │ │ ├── myBrain135.tif │ │ ├── myBrain147.tif │ │ ├── myBrain78.bmp │ │ ├── myBrain89.bmp │ │ ├── myBrain_axial_78.bmp │ │ └── myBrain_coronal_89.bmp │ └── MICO_3D │ │ ├── MICO_3D.m │ │ ├── MICO_3Dseq.m │ │ ├── brainweb_byte_B3N1.nii │ │ ├── brainweb_byte_B3N2.nii │ │ ├── cropImg.m │ │ ├── demo_MICO_3D.m │ │ ├── load_nii_ext.m │ │ ├── load_nii_hdr.m │ │ ├── load_untouch0_nii_hdr.m │ │ ├── load_untouch_nii.m │ │ ├── load_untouch_nii_hdr.m │ │ ├── load_untouch_nii_img.m │ │ ├── make_nii.m │ │ ├── saveBasisOrder3_3D.m │ │ ├── save_nii.m │ │ ├── save_nii_hdr.m │ │ └── sortMemC.m ├── heart_ct.bmp ├── lse_bfe.m ├── lse_bfe_3Phase.m ├── myBrain_axial.bmp └── normalize01.m ├── CV Model(Li) ├── BoundMirrorEnsure.m ├── BoundMirrorExpand.m ├── BoundMirrorShrink.m ├── CV │ ├── CURVATURE.m │ ├── Demo_CV.m │ ├── EVOL_CV.m │ ├── binaryfit.m │ ├── sdf2circle.m │ ├── three.bmp │ ├── twocells.bmp │ └── vessel3.bmp ├── Delta.m ├── Heaviside.m ├── backward_gradient.m ├── binaryfit.m ├── curvature.m ├── evolution_cv.m ├── forward_gradient.m ├── get_contour.m ├── plotLevelSet.m ├── sdf2circle.m ├── signed_distance.m ├── test.asv ├── test.m ├── three.bmp ├── twocells.bmp └── vessel.bmp ├── DRLSE(Li) ├── DRLSE.pdf ├── demo_1.m ├── demo_2.m ├── drlse_edge.m ├── gourd.bmp ├── improved-drlse.m ├── twocells.bmp └── vessel.bmp ├── GAC ├── GACmodel │ ├── 3.bmp │ ├── Thumbs.db │ ├── calcspeed.m │ ├── createimage.m │ ├── init_u.m │ ├── isfront.m │ ├── levelset.m │ ├── main.m │ ├── re_init_u.m │ ├── stopfunction.m │ └── vessel.bmp └── Geodesic Active Contours1997IJCV.pdf ├── LBF(Li) ├── LBF │ ├── DemoLBF.m │ ├── EVOL_LBF.m │ ├── I5.bmp │ ├── LBF.pdf │ ├── cq2.jpg │ ├── mri_nonuniform.bmp │ ├── noisyNonUniform.bmp │ ├── plotLevelSet.m │ ├── vessel.bmp │ ├── vessel2.bmp │ ├── vessel3.bmp │ └── 灰度不均.jpg ├── RSF_v0.1 │ ├── Demo_fourImages.m │ ├── Demo_mri_nonuniform.m │ ├── Demo_noisySynthetic.m │ ├── Demo_vessel.m │ ├── LSE.dll │ ├── Readme.txt │ ├── Vessel2_initialLSF2.mat │ ├── Vessel3_initialLSF.mat │ ├── mri_nonuniform.bmp │ ├── mybrainC100b_initialLSF.mat │ ├── noisyNonUniform.bmp │ ├── noisyNonUniform_initialLSF.mat │ ├── nonhomo_initialLSF.mat │ ├── vessel2.bmp │ └── vessel3.bmp └── RSF_v0 │ ├── 1.bmp │ ├── 2.bmp │ ├── 3.bmp │ ├── 4.bmp │ ├── 5.bmp │ ├── 88.tif │ ├── Demo_RSF.m │ ├── Minimization of Region-Scalable Fitting Energy__for Image Segmentation.pdf │ ├── RSF.m │ └── Thumbs.db ├── LGIF ├── 03.jpg ├── 12.jpg ├── 3.jpg ├── Delta.m ├── Thumbs.db ├── backward_gradient.m ├── cq18.jpg ├── cq2.jpg ├── cq391.jpg ├── cq44.bmp ├── cqc.jpg ├── curvature.m ├── demo_LGIF.m ├── evolution_LGIF.m ├── forward_gradient.m ├── new_img.bmp ├── picturelab.bmp ├── plotLevelSet.m └── vessel.bmp ├── LIF ├── 1.bmp ├── 3c.bmp ├── Demo.m ├── LIF.pdf └── LIF_2D.m ├── LoG&RSF ├── 1.bmp ├── 2.bmp ├── 3.bmp ├── 4.bmp ├── 5.bmp ├── 6.bmp ├── ACM_LoG.m ├── Active contours driven by region-scalable fitting and optimized Laplacian of Gaussian energy for image segmentation.pdf └── Demo_ACM_LoG.m ├── Local Pre-fitting ├── 1.bmp ├── 2.bmp ├── 3.bmp ├── 4.bmp ├── 5.bmp ├── 6.bmp ├── ACM_LPF.m ├── Active contours driven by local pre-fitting energy for fast image segmentation.pdf ├── Demo_ACM_LPF.m └── LPF.m ├── LocalizedActiveContour ├── 1.bmp ├── 2.bmp ├── 3.bmp ├── Demo_LAC.m ├── local_AC_MS.m ├── local_AC_UM.m ├── readme.txt └── results.png ├── Multiphase_CV ├── A Multiphase Level Set Framework for Image Segmentation__Using the Mumford and Shah Model.pdf ├── CURVATURE_CV.m ├── Delta.m ├── Demo_multiphase_improved.m ├── Demo_multiphase_original.m ├── EVOLUTION_4PHASE.m ├── EVOLUTION_4PHASE_DR.asv ├── EVOLUTION_4PHASE_DR.m ├── Heaviside.m ├── backward_gradient.m ├── forward_gradient.m ├── fourblock_gray.bmp ├── get_contour.m ├── initial_sdf2circle.m ├── plotLevelSet.m └── quadrifit.m ├── Narrow band ├── NarrowBand_DLL │ ├── Demo_nband.m │ ├── initializeNB.dll │ ├── nband_v14.dll │ ├── printStats.m │ └── twoObjImg.bmp ├── calcspeed.m ├── edgestop.m ├── extendspeed.m ├── extendspeedband.m ├── initphi.m ├── isband.m ├── isfront.m ├── narrowbandEvolution.m ├── noisyImg.bmp ├── reinit_SD_ENO2.m └── test.m └── README.md /Bias Correction(Li)/5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/5.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/A Level Set Method for Image Segmentation__in the Presence of Intensity Inhomogeneities__With Application to MRI.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/A Level Set Method for Image Segmentation__in the Presence of Intensity Inhomogeneities__With Application to MRI.pdf -------------------------------------------------------------------------------- /Bias Correction(Li)/Demo.m: -------------------------------------------------------------------------------- 1 | 2 | % This code demonstrates the level set evolution (LSE) and bias field estimation 3 | % proposed in the following paper: 4 | % C. Li, R. Huang, Z. Ding, C. Gatenby, D. N. Metaxas, and J. C. Gore, 5 | % "A Level Set Method for Image Segmentation in the Presence of Intensity 6 | % Inhomogeneities with Application to MRI", IEEE Trans. Image Processing, 2011 7 | % 8 | 9 | % Note: 10 | % This code implements the two-phase formulation of the model in the above paper. 11 | % The two-phase formulation uses the signs of a level set function to represent 12 | % two disjoint regions, and therefore can be used to segment an image into two regions, 13 | % which are represented by (u>0) and (u<0), where u is the level set function. 14 | % 15 | % All rights researved by Chunming Li, who formulated the model, designed and 16 | % implemented the algorithm in the above paper. 17 | % 18 | % E-mail: lchunming@gmail.com 19 | % URL: http://www.engr.uconn.edu/~cmli/ 20 | % Copyright (c) by Chunming Li 21 | % Author: Chunming Li 22 | 23 | close all; 24 | clear all; 25 | Img=imread('5.bmp'); 26 | Img=double(Img(:,:,1)); 27 | A=255; 28 | Img=A*normalize01(Img); % rescale the image intensities 29 | nu=0.001*A^2; % coefficient of arc length term 30 | 31 | sigma = 4; % scale parameter that specifies the size of the neighborhood 32 | iter_outer=50; 33 | iter_inner=10; % inner iteration for level set evolution 34 | 35 | timestep=.1; 36 | mu=1; % coefficient for distance regularization term (regularize the level set function) 37 | 38 | c0=1; 39 | figure(1); 40 | imagesc(Img,[0, 255]); colormap(gray); axis off; axis equal 41 | 42 | % initialize level set function 43 | initialLSF = c0*ones(size(Img)); 44 | initialLSF(30:90,50:90) = -c0; 45 | u=initialLSF; 46 | 47 | hold on; 48 | contour(u,[0 0],'r'); 49 | title('Initial contour'); 50 | 51 | figure(2); 52 | imagesc(Img,[0, 255]); colormap(gray); axis off; axis equal 53 | hold on; 54 | contour(u,[0 0],'r'); 55 | title('Initial contour'); 56 | 57 | epsilon=1; 58 | b=ones(size(Img)); %%% initialize bias field 59 | 60 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % Gaussian kernel 61 | KI=conv2(Img,K,'same'); 62 | KONE=conv2(ones(size(Img)),K,'same'); 63 | 64 | [row,col]=size(Img); 65 | N=row*col; 66 | 67 | for n=1:iter_outer 68 | [u, b, C]= lse_bfe(u,Img, b, K,KONE, nu,timestep,mu,epsilon, iter_inner); 69 | 70 | if mod(n,2)==0 71 | pause(0.001); 72 | imagesc(Img,[0, 255]); colormap(gray); axis off; axis equal; 73 | hold on; 74 | contour(u,[0 0],'r'); 75 | iterNum=[num2str(n), ' iterations']; 76 | title(iterNum); 77 | hold off; 78 | end 79 | 80 | end 81 | Mask =(Img>10); 82 | Img_corrected=normalize01(Mask.*Img./(b+(b==0)))*255; 83 | 84 | figure(3); imagesc(b); colormap(gray); axis off; axis equal; 85 | title('Bias field'); 86 | 87 | figure(4); 88 | imagesc(Img_corrected); colormap(gray); axis off; axis equal; 89 | title('Bias corrected image'); 90 | 91 | 92 | -------------------------------------------------------------------------------- /Bias Correction(Li)/Demo_MultiPhase.m: -------------------------------------------------------------------------------- 1 | 2 | % This code demonstrates the three-phase formulation of the level set evolution (LSE) 3 | % and bias field estimation proposed in the following paper: 4 | % C. Li, R. Huang, Z. Ding, C. Gatenby, D. N. Metaxas, and J. C. Gore, 5 | % "A Level Set Method for Image Segmentation in the Presence of Intensity 6 | % Inhomogeneities with Application to MRI", IEEE Trans. Image Processing, 2011 7 | % 8 | % Note: 9 | % This code implements the three-phase formulation of the model in the above paper. 10 | % The three-phase formulation is used to segment an image into three regions. 11 | % The code for four-phase or other multi-phase formulation will be released later 12 | % in the website below. 13 | % 14 | % All rights researved by Chunming Li, who formulated the model, designed and 15 | % implemented the algorithm in the above paper. 16 | % 17 | % E-mail: lchunming@gmail.com 18 | % URL: http://www.engr.uconn.edu/~cmli/ 19 | % Copyright (c) by Chunming Li 20 | % Author: Chunming Li 21 | 22 | 23 | close all;clear all; 24 | 25 | 26 | Img=imread('myBrain_axial.bmp'); 27 | 28 | Iter_outer = 100; 29 | Iter_inner = 10; 30 | sigma = 4; % scale parameter 31 | timestep = .1; 32 | mu = 0.1/timestep; 33 | A=255; 34 | nu = 0.001*A^2; % weight of length term 35 | c0 = 1; 36 | epsilon = 1; 37 | 38 | Img = double(Img(:,:,1)); 39 | Img=normalize01(Img)*A; % rescale the image intensity to the interval [0,A] 40 | Mask=(Img>5); 41 | 42 | 43 | [nrow,ncol] = size(Img); 44 | 45 | numframe=0; 46 | 47 | figure; 48 | imagesc(Img,[0 255]);colormap(gray);hold on; axis off;axis equal; 49 | 50 | %%% initialization of bias field and level set function 51 | b=ones(size(Img)); 52 | initialLSF(:,:,1) = randn(size(Img)); % randomly initialize the level set functions 53 | initialLSF(:,:,2) = randn(size(Img)); % randomly initialize the level set functions 54 | initialLSF(:,:,1)= Mask; % remove the background outside the mask 55 | u = sign(initialLSF); 56 | 57 | [c,h] = contour(u(:,:,1),[0 0],'r'); 58 | [c,h] = contour(u(:,:,2),[0 0],'b'); 59 | 60 | hold off 61 | 62 | Ksigma=fspecial('gaussian',round(2*sigma)*2+1,sigma); % Gaussian kernel 63 | % disk_radius = 7; 64 | % Ksigma=fspecial('disk',disk_radius); % an alternative kernel as a truncated uniform function 65 | KONE=conv2(ones(size(Img)),Ksigma,'same'); 66 | 67 | 68 | pause(0.1) 69 | 70 | 71 | totaltime =0 72 | for n = 1:Iter_outer 73 | 74 | t0=cputime; 75 | [u, b, C]= lse_bfe_3Phase(u,Img,b,Ksigma,KONE, nu,timestep,mu,epsilon,Iter_inner); 76 | t1=cputime; 77 | totaltime = totaltime + t1-t0; 78 | 79 | if(mod(n,3) == 0) 80 | pause(0.01); 81 | imagesc(Img,[0 255]);colormap(gray);hold on; axis off;axis equal; 82 | [c,h] = contour(u(:,:,1),[0 0],'r'); 83 | [c,h] = contour(u(:,:,2),[0 0],'b'); 84 | iterNum=[num2str(n), ' iterations']; 85 | title(iterNum); 86 | hold off; 87 | 88 | end 89 | 90 | end 91 | totaltime 92 | 93 | H1 = Heaviside(u(:,:,1),epsilon ); 94 | H2 = Heaviside(u(:,:,2),epsilon ); 95 | M1=H1.*H2; 96 | M2=H1.*(1-H2); 97 | M3=(1-H1); 98 | 99 | Img_seg=C(1)*M1+C(2)*M2+C(3)*M3; % three regions are labeled with C1, C2, C3 100 | figure;imagesc(Img_seg); axis off; axis equal;title('Segmented regions'); 101 | colormap(gray); 102 | 103 | figure; 104 | imagesc(Img,[0 255]);colormap(gray);hold on; axis off;axis equal; 105 | [c,h] = contour(u(:,:,1),[0 0],'r','LineWidth',1); 106 | [c,h] = contour(u(:,:,2),[0 0],'b','LineWidth',1); 107 | 108 | figure; imagesc(Img, [0,255]);colormap(gray);hold on; axis off; axis equal; 109 | title('Original image'); 110 | 111 | img_corrected = normalize01(Mask.*Img./(b+(b==0)))*255; 112 | figure,imagesc(img_corrected, [0,255]);colormap(gray);hold on; axis off; axis equal; 113 | title('Bias corrected image'); 114 | 115 | figure; 116 | imshow(uint8(Mask.*normalize01(b)*200),[0 255]);colormap(gray);hold on; axis off; axis equal 117 | title('Estimated bias field (on the mask)'); 118 | 119 | figure; 120 | title('Histogram'); 121 | subplot(1,2,1) 122 | [N,X]=hist(Img(:),30); plot(X,N,'b');title('Histogram of original image');% text(50,2000,'Histogram of original image','FontSize',[10],'Color', 'k'); 123 | subplot(1,2,2) 124 | [N,X]=hist(img_corrected(:),30); plot(X,N,'b'); title('Histogram of bias corrected image');%text(50,2000,'Histogram of bias corrected image','FontSize',[10],'Color', 'k'); 125 | 126 | -------------------------------------------------------------------------------- /Bias Correction(Li)/Heaviside.m: -------------------------------------------------------------------------------- 1 | function h = Heaviside(x,epsilon) 2 | h=0.5*(1+(2/pi)*atan(x./epsilon)); -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO.pdf -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/Demo_MICO.m: -------------------------------------------------------------------------------- 1 | % This Matlab file demomstrates the method for simultaneous segmentation and bias field correction 2 | % in Chunming Li et al's paper: 3 | % "Multiplicative intrinsic component optimization (MICO) for MRI bias field estimation and tissue segmentation", 4 | % Magnetic Resonance Imaging, vol. 32 (7), pp. 913-923, 2014 5 | % Author: Chunming Li, all rights reserved 6 | % E-mail: li_chunming@hotmail.com 7 | % URL: http://imagecomputing.org/~cmli/ 8 | 9 | clc;close all;clear all; 10 | iterNum = 20; 11 | N_region=3; q=1; 12 | Img=imread('brainweb97.tif'); 13 | Img = double(Img(:,:,1)); 14 | %load ROI 15 | A=255; 16 | Img_original = Img; 17 | [nrow,ncol] = size(Img);n = nrow*ncol; 18 | 19 | ROI = (Img>5); ROI = double(ROI); 20 | 21 | tic 22 | 23 | Bas=getBasisOrder3(nrow,ncol); 24 | N_bas=size(Bas,3); 25 | for ii=1:N_bas 26 | ImgG{ii} = Img.*Bas(:,:,ii).*ROI; 27 | for jj=ii:N_bas 28 | GGT{ii,jj} = Bas(:,:,ii).*Bas(:,:,jj).*ROI; 29 | GGT{jj,ii} = GGT{ii,jj} ; 30 | end 31 | end 32 | 33 | 34 | energy_MICO = zeros(3,iterNum); 35 | 36 | b=ones(size(Img)); 37 | for ini_num = 1:1 38 | C=rand(3,1); 39 | C=C*A; 40 | M=rand(nrow,ncol,3); 41 | a=sum(M,3); 42 | for k = 1 : 3 43 | M(:,:,k)=M(:,:,k)./a; 44 | end 45 | 46 | [e_max,N_max] = max(M,[], 3); 47 | for kk=1:size(M,3) 48 | M(:,:,kk) = (N_max == kk); 49 | end 50 | 51 | M_old = M; chg=10000; 52 | energy_MICO(ini_num,1) = get_energy(Img,b,C,M,ROI,q); 53 | 54 | 55 | for n = 2:iterNum 56 | pause(0.1) 57 | 58 | [M, b, C]= MICO(Img,q,ROI,M,C,b,Bas,GGT,ImgG,1, 1); 59 | energy_MICO(ini_num,n) = get_energy(Img,b,C,M,ROI,q); 60 | 61 | figure(2), 62 | if(mod(n,1) == 0) 63 | PC=zeros(size(Img)); 64 | for k = 1 : N_region 65 | PC=PC+C(k)*M(:,:,k); 66 | end 67 | subplot(241),imshow(uint8(Img)),title('original') 68 | subplot(242),imshow(PC.*ROI,[]); colormap(gray); 69 | iterNums=['segmentation: ',num2str(n), ' iterations']; 70 | title(iterNums); 71 | subplot(243),imshow(b.*ROI,[]),title('bias field') 72 | img_debias = Img./b; 73 | subplot(244),imshow(uint8(img_debias.*ROI),[]),title('bias corrected') 74 | subplot(2,4,[5 6 7 8]),plot(energy_MICO(ini_num,:)) 75 | xlabel('iteration number'); 76 | ylabel('energy'); 77 | pause(0.1) 78 | end 79 | end 80 | end 81 | 82 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/MICO.m: -------------------------------------------------------------------------------- 1 | function [M_out, b_out, C_out]= MICO(Img,q,W,M,C,b,Bas,GGT,ImgG, Iter, iterCM) 2 | % This code implements the MICO algorithm for joint segmentation and bias field estimation 3 | % proposed in the following paper: 4 | % C. Li, J.C. Gore, and C. Davatzikos, 5 | % "Multiplicative intrinsic component optimization (MICO) for MRI bias field estimation and tissue segmentation", Magnetic Resonance 6 | % Imaging , vol. 32 (7), pp. 913-923, 2014 7 | % 8 | % All rights researved by Chunming Li 9 | % E-mail: li_chunming@hotmail.com 10 | % URL: http://imagecomputing.org/~cmli/ 11 | % Copyright (c) by Chunming Li 12 | % Author: Chunming Li 13 | 14 | for n = 1:Iter 15 | 16 | C = updateC(Img, W, b, M); 17 | for k=1:iterCM 18 | N_class=size(M,3); 19 | e=zeros(size(M)); 20 | for kk=1:N_class 21 | D(:,:,kk) = (Img-C(kk)*b).^2; 22 | end 23 | M = updateM(D,q); 24 | end 25 | end 26 | 27 | b_out = updateB(Img, q, C, M, Bas,GGT,ImgG); 28 | M_out=M; 29 | C_out=C; 30 | 31 | 32 | %%%%%%%%%%%%%%%%%% 33 | %%% update b %%% 34 | function b =updateB(Img, q, C, M, Bas,GGT,ImgG) 35 | 36 | PC2 = zeros(size(Img)); 37 | PC=PC2; 38 | 39 | N_class=size(M,3); 40 | for kk=1:N_class 41 | PC2=PC2+C(kk)^2*M(:,:,kk).^q; 42 | PC=PC+C(kk)*M(:,:,kk).^q; 43 | end 44 | 45 | N_bas=size(Bas,3); 46 | V=zeros(N_bas,1); 47 | for ii=1:N_bas 48 | ImgG_PC=ImgG{ii}.*PC; % Mask in ImgG 49 | V(ii)=sum(ImgG_PC(:)); % inner product 50 | for jj=ii:N_bas 51 | B = GGT{ii,jj}.*PC2; % Mask in GGT 52 | A(ii,jj)=sum(B(:)); % inner product 53 | A(jj,ii)=A(ii,jj); 54 | end 55 | end 56 | clear PC1; 57 | clear PC2; 58 | clear B; 59 | clear ImgG_PC; 60 | w=inv(A)*V; 61 | 62 | b=zeros(size(Img)); 63 | for kk=1:N_bas 64 | b=b+w(kk)*Bas(:,:,kk); 65 | end 66 | 67 | %%%%%%%%%%%%%%%%%% 68 | %%% update C %%% 69 | function C_new =updateC(Img, W,b, M) 70 | N_class=size(M,3); 71 | for nn=1:N_class 72 | N=b.*Img.*M(:,:,nn); 73 | D=(b.^2) .*M(:,:,nn); 74 | sN = sum(N(:).*W(:)); % inner product 75 | sD = sum(D(:).*W(:)); % inner product 76 | C_new(nn)=sN/(sD+(sD==0)); 77 | end 78 | 79 | clear N; 80 | clear D; 81 | 82 | %%%%%%%%%%%%%%%%%% 83 | %%% update M %%% 84 | function M = updateM(e, q) 85 | 86 | N_class=size(e,3); 87 | 88 | if q >1 89 | epsilon=0.000000000001; 90 | e=e+epsilon; %% avoid division by zero 91 | p = 1/(q-1); 92 | f = 1./(e.^p); 93 | f_sum = sum(f,3); 94 | for kk=1:N_class 95 | M(:,:,kk) = f(:,:,kk)./f_sum; 96 | end 97 | elseif q==1 98 | [e_min,N_min] = min(e,[], 3); 99 | for kk=1:N_class 100 | M(:,:,kk) = (N_min == kk); 101 | end 102 | else 103 | error('MICO: wrong fuzzifizer'); 104 | end 105 | 106 | 107 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb59.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb59.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb64.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb64.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb67.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb67.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb72.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb72.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb78.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb78.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb79.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb79.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb83.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb83.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb90.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb90.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb91.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb91.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb92.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb92.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/brainweb97.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/brainweb97.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/getBasisOrder3.m: -------------------------------------------------------------------------------- 1 | % Author: Chunming Li, all rights reserved 2 | % E-mail: li_chunming@hotmail.com 3 | % URL: http://imagecomputing.org/~cmli/ 4 | function B = getBasisOrder3(Height,Wide) 5 | 6 | for i =1:Height 7 | x(i,:) = -1:2/(Wide-1):1; 8 | end 9 | for i =1:Wide 10 | temp = -1:2/(Height-1):1; 11 | y(:,i) = temp'; 12 | end 13 | 14 | 15 | bais = zeros(Height,Wide,10); 16 | bais(:,:,1) = 1; 17 | bais(:,:,2) = x; 18 | bais(:,:,3) = (3.*x.*x - 1)./2; 19 | bais(:,:,4) = (5.*x.*x.*x - 3.*x)./2; 20 | bais(:,:,5) = y; 21 | bais(:,:,6) = x.*y; 22 | bais(:,:,7) = y.*(3.*x.*x -1)./2; 23 | bais(:,:,8) = (3.*y.*y -1)./2; 24 | bais(:,:,9) = (3.*y.*y -1).*x./2; 25 | bais(:,:,10) = (5.*y.*y.*y -3.*y)./2; 26 | 27 | 28 | B = bais; 29 | for kk=1:10 30 | A=bais(:,:,kk).^2; 31 | r = sqrt(sum(A(:))); 32 | B(:,:,kk)=bais(:,:,kk)/r; 33 | end 34 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/getBasisOrder4.m: -------------------------------------------------------------------------------- 1 | % Author: Chunming Li, all rights reserved 2 | % E-mail: li_chunming@hotmail.com 3 | % URL: http://imagecomputing.org/~cmli/ 4 | function B = getBasisOrder4(Height,Wide) 5 | 6 | for i =1:Height 7 | x(i,:) = -1:2/(Wide-1):1; 8 | end 9 | for i =1:Wide 10 | temp = -1:2/(Height-1):1; 11 | y(:,i) = temp'; 12 | end 13 | 14 | bais = zeros(Height,Wide,15); 15 | bais(:,:,1) = 1; 16 | bais(:,:,2) = x; 17 | bais(:,:,3) = (3.*x.*x - 1)./2; 18 | bais(:,:,4) = (5.*x.*x.*x - 3.*x)./2; 19 | bais(:,:,5) = (35.*x.*x.*x.*x - 30.*x.*x+3)./8; 20 | bais(:,:,6) = y; 21 | bais(:,:,7) = x.*y; 22 | bais(:,:,8) = (3.*x.*x - 1).*y./2; 23 | bais(:,:,9) = (5.*x.*x.*x - 3.*x).*y./2; 24 | bais(:,:,10) = (3.*y.*y - 1)./2; 25 | bais(:,:,11) = (3.*y.*y - 1).*x./2; 26 | bais(:,:,12) = (3.*x.*x - 1).*(3.*y.*y - 1)./4; 27 | bais(:,:,13) = (5.*y.*y.*y- 3.*y)./2; 28 | bais(:,:,14) = (5.*y.*y.*y- 3.*y).*x./2; 29 | bais(:,:,15) = (35.*y.*y.*y.*y - 30.*y.*y+3)./8; 30 | 31 | 32 | 33 | 34 | for kk=1:15 35 | A=bais(:,:,kk).^2; 36 | r = sqrt(sum(A(:))); 37 | B(:,:,kk)=bais(:,:,kk)/r; 38 | end 39 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/get_energy.m: -------------------------------------------------------------------------------- 1 | % Author: Chunming Li, all rights reserved 2 | % E-mail: li_chunming@hotmail.com 3 | % URL: http://imagecomputing.org/~cmli/ 4 | function energy = get_energy(Img,b,C,M,ROI,q) 5 | 6 | N = size(M,3); 7 | energy = 0; 8 | 9 | for k = 1 : N 10 | C_k=C(k)*ones(size(Img)); 11 | energy = energy + sum(sum((Img.*ROI - b.*C_k.*ROI).^2.*M(:,:,k).^q)); 12 | end -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/mprage171.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/mprage171.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/mprage178.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/mprage178.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/mprage271.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/mprage271.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/mprage276.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/mprage276.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/mprage371.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/mprage371.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/mprage381.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/mprage381.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain127.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain127.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain135.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain135.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain147.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain147.tif -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain78.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain78.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain89.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain89.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain_axial_78.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain_axial_78.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_2D/myBrain_coronal_89.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_2D/myBrain_coronal_89.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/MICO_3D.m: -------------------------------------------------------------------------------- 1 | % This function implements the MICO algorithm for joint segmentation and bias field estimation 2 | % proposed in the following paper: 3 | % C. Li, J.C. Gore, and C. Davatzikos, 4 | % "Multiplicative intrinsic component optimization (MICO) for MRI bias field estimation and tissue segmentation", Magnetic Resonance 5 | % Imaging , vol. 32 (7), pp. 913-923, 2014 6 | % 7 | % All rights researved by Chunming Li 8 | % E-mail: li_chunming@hotmail.com 9 | % URL: http://imagecomputing.org/~cmli/ 10 | % Copyright (c) by Chunming Li 11 | % Author: Chunming Li 12 | 13 | function [M, b, C]= MICO_3D(Img,W,M,C,b,Iter, iterCM,q) 14 | for n = 1:Iter 15 | for kk=1:iterCM 16 | C = updateC(Img, W, q, b, M); % Note: the order of updating C,M,and B can be changed. 17 | M = updateM(Img, W, C,b,q); 18 | end 19 | b = updateB(Img, C, M,q); 20 | end 21 | 22 | 23 | %%%%%%%%%%%%%%%%%% 24 | %%% update b %%% 25 | function b =updateB(Img, C, M,q) 26 | 27 | PC2 = zeros(size(Img)); 28 | PC=PC2; 29 | 30 | N_class=size(M,4); 31 | for kk=1:N_class 32 | Mq=M(:,:,:,kk).^q; 33 | PC2=PC2+C(kk)^2*Mq; 34 | PC=PC+C(kk)*Mq; 35 | end 36 | 37 | N_bas=20; 38 | 39 | D=zeros(N_bas,1); 40 | for i=1:N_bas 41 | filename = ['basis_',num2str(i),'.mat']; 42 | load(filename); 43 | basis_i = basis; 44 | A=Img.*basis_i.*PC; 45 | D(i)=sum(A(:)); 46 | for j=i:N_bas 47 | filename = ['basis_',num2str(j),'.mat']; 48 | load(filename); 49 | basis_j = basis; 50 | B = basis_i.*basis_j.*PC2; 51 | G(i,j)=sum(B(:)); 52 | G(j,i)=G(i,j); 53 | end 54 | end 55 | coeff=inv(G)*D; 56 | 57 | clear A; 58 | clear B; 59 | clear PC;clear PC2; 60 | 61 | 62 | b=zeros(size(Img)); 63 | for kk=1:N_bas 64 | filename = ['basis_',num2str(kk),'.mat']; 65 | load(filename); 66 | b=b+coeff(kk)*basis; 67 | end 68 | 69 | %%%%%%%%%%%%%%%%%% 70 | %%% update C %%% 71 | function C =updateC(Img, W, q, b, M) 72 | N_class=size(M,4); 73 | for nn=1:N_class 74 | Mq=M(:,:,:,nn).^q; 75 | N=b.*Img.*Mq.*W; 76 | D=(b.^2 ).*Mq.*W; 77 | sN = sum(N(:)); 78 | sD = sum(D(:)); 79 | C(nn)=sN/(sD+(sD==0)); 80 | end 81 | 82 | 83 | %%%%%%%%%%%%%%%%%% 84 | %%% update M %%% 85 | function M_out = updateM(Img, W, C,b,q) 86 | 87 | N_class=length(C); 88 | 89 | if q > 1 90 | epsilon=0.000000000001; 91 | 92 | p = -1/(q-1); 93 | f_sum = zeros(size(Img)); 94 | for kk=1:N_class 95 | f_sum = f_sum + (((Img-C(kk)*b).^2) + epsilon).^p; 96 | end 97 | 98 | for kk=1:N_class 99 | M_out(:,:,:,kk) = W.*(((Img-C(kk)*b).^2) + epsilon).^p./f_sum; 100 | end 101 | clear f_sum; 102 | 103 | elseif q==1 104 | for kk=1:N_class 105 | e(:,:,:,kk) = (Img-C(kk)*b).^2 ; 106 | end 107 | [e_min,N_min] = min(e,[], 4); 108 | clear e; 109 | for kk=1:N_class 110 | M_out(:,:,:,kk) = (N_min == kk); 111 | M_out(:,:,:,kk) = M_out(:,:,:,kk).*W; 112 | end 113 | clear e N_min; 114 | else 115 | error('MICO_3D: wrong fuzzifizer'); 116 | end 117 | 118 | clear Img b; 119 | 120 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/MICO_3Dseq.m: -------------------------------------------------------------------------------- 1 | % This Matlab function reads images in .nii format and calls the MICO 2 | % function to perform simultaneous segmentation and bias field correction in Chunming Li et al's paper: 3 | % "Multiplicative intrinsic component optimization (MICO) for MRI bias field estimation and tissue segmentation", 4 | % Magnetic Resonance Imaging, vol. 32 (7), pp. 913-923, 2014 5 | % Author: Chunming Li, all rights reserved 6 | % E-mail: li_chunming@hotmail.com 7 | % URL: http://imagecomputing.org/~cmli/ 8 | function MICO_3Dseq(str_vector, N_region, q, th_bg, iterNum_outer, Iter_b, iterCM, tissueLabel) 9 | 10 | N_scan = length(str_vector); 11 | for nn = 1:N_scan 12 | str=str_vector{nn}; 13 | data = load_untouch_nii(str); 14 | Img=data.img; 15 | Img = double(Img); 16 | save temp_info.mat data; 17 | clear data; 18 | 19 | [x1, x2, y1, y2, z1, z2] = cropImg(Img, th_bg); %% crop image 20 | [DimX1, DimY1, DimZ1]=size(Img); 21 | x1 = max(1,x1-2); x2 = min(DimX1,x2+2); 22 | y1 = max(1,y1-2); y2 = min(DimY1,y2+2); 23 | z1 = max(1,z1-2); z2 = min(DimZ1,z2+2); 24 | 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | Img3D=Img(x1:x2,y1:y2,z1:z2); 27 | clear Img; 28 | [DimX, DimY, DimZ] = size(Img3D); 29 | ROI = (Img3D>th_bg); 30 | saveBasisOrder3_3D(ROI); 31 | Img3D = Img3D.*ROI; 32 | %%%%%%%%%%%%%%%%%%%%%% Initialization 33 | 34 | A=max(Img3D(:)); 35 | C= linspace(0.1,0.9,N_region)*A; 36 | b=ones(size(Img3D)); 37 | 38 | 39 | M=rand(DimX, DimY, DimZ,N_region); 40 | a=sum(M,4); 41 | for k = 1 : N_region 42 | M(:,:,:,k)=M(:,:,:,k)./a; 43 | end 44 | clear a; 45 | 46 | 47 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 48 | 49 | totaltime = 0; 50 | M_old = M; chg=10000; 51 | save M_old M_old 52 | clear M_old; 53 | 54 | C_old =C; 55 | for n_iter= 1:iterNum_outer 56 | n_iter 57 | tic 58 | [M, b, C]= MICO_3D(Img3D,ROI,M,C,b,Iter_b,iterCM,q); 59 | 60 | totaltime = totaltime + toc 61 | 62 | [M, C]=sortMemC(M, C); 63 | PC2d=zeros(size(Img3D(:,:,1))); 64 | PC3d=zeros(DimX1, DimY1, DimZ1); 65 | N_slc=90; 66 | for k=1:N_region 67 | PC2d = PC2d + tissueLabel(k)*M(:,:,N_slc,k); 68 | end 69 | pause(0.1); 70 | figure(1); 71 | subplot(1,2,1); 72 | imagesc(Img3D(:,:,N_slc));colormap(gray); 73 | subplot(1,2,2); 74 | imagesc(PC2d);colormap(gray); 75 | C_new = C/norm(C); 76 | 77 | chg= max(abs(C_new(:)-C_old(:))); 78 | C_old = C_new; 79 | if chg<0.0001 % check convergence 80 | break 81 | end 82 | end 83 | clear Img3D; 84 | 85 | %[U, C]=sortMemC(M, C); 86 | U=maxMembership(M); 87 | clear M; 88 | Membership = zeros(DimX1, DimY1, DimZ1,N_region); 89 | Membership(x1:x2,y1:y2,z1:z2,:)=U; 90 | for k=1:N_region 91 | PC3d(:,:,:)=PC3d(:,:,:)+tissueLabel(k)*Membership(:,:,:,k); 92 | end 93 | pc3d=make_nii(PC3d); 94 | save_nii(pc3d,[str,'_seg.nii']); 95 | Bias = zeros(DimX1, DimY1, DimZ1); 96 | Bias(x1:x2,y1:y2,z1:z2)=b; clear b; 97 | bias=make_nii(Bias); 98 | save_nii(bias,[str,'_bc.nii']); 99 | 100 | 101 | clear Membership Bias U; 102 | 103 | for basis_index=1:20 % delete basis files 104 | filename = ['basis_',num2str(basis_index),'.mat']; 105 | delete(filename); 106 | end 107 | delete M_old.mat temp_info.mat; 108 | 109 | end 110 | 111 | % sort the constants c1, c2, ..., and change the order of the membership 112 | % functions accordingly. 113 | function [M_out, C_out]=sortMemC(M, C) 114 | 115 | [C_out IDX]=sort(C); 116 | 117 | for k = 1 : length(C) 118 | M_out(:,:,:,k) = M(:,:,:,IDX(k)); 119 | end 120 | 121 | % This Matlab function binarizes a fuzzy membership function 122 | function M_out = maxMembership(M) 123 | 124 | if size(M,4)==1 125 | 126 | N_class=size(M,3); 127 | ROI = (sum(M,3)>0); 128 | 129 | M_out = zeros(size(M)); 130 | 131 | [e_min,N_min] = max(M,[], 3); % do not consider 2 minimum in this version 132 | for kk=1:N_class 133 | M_out(:,:,kk) = ROI.*(N_min == kk); 134 | end 135 | 136 | elseif size(M,4)>1 137 | N_class=size(M,4); 138 | ROI = (sum(M,4)>0); 139 | 140 | 141 | [e_min,N_min] = max(M,[], 4); % do not consider 2 minimum in this version 142 | for kk=1:N_class 143 | M_out(:,:,:,kk) = ROI.*(N_min == kk); 144 | end 145 | else 146 | error('wrong dimension: maxMembership'); 147 | end 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/brainweb_byte_B3N1.nii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_3D/brainweb_byte_B3N1.nii -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/brainweb_byte_B3N2.nii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/MICO_v0/MICO_3D/brainweb_byte_B3N2.nii -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/cropImg.m: -------------------------------------------------------------------------------- 1 | function [x1 x2 y1 y2 z1 z2] = cropImg(Img, th) 2 | 3 | [Nx, Ny, Nz]=size(Img); 4 | 5 | xx=[]; 6 | yy=[]; 7 | zz=[]; 8 | 9 | 10 | x1=Nx; 11 | x2=1; 12 | y1=Ny; 13 | y2=1; 14 | z1=Nz; 15 | z2=1; 16 | 17 | zz=[]; 18 | 19 | for z=1:Nz 20 | Img2D=Img(:,:,z); 21 | [xx,yy]=find(Img2D>th); 22 | if length(xx)>0 23 | zz=[zz,z]; 24 | x1=min(x1,min(xx)); 25 | x2=max(x2,max(xx)); 26 | y1=min(y1, min(yy)); 27 | y2=max(y2, max(yy)); 28 | end 29 | 30 | 31 | 32 | end 33 | 34 | z1=min(zz); 35 | z2=max(zz); 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/demo_MICO_3D.m: -------------------------------------------------------------------------------- 1 | % This Matlab file demomstrates the method for simultaneous segmentation and bias field correction 2 | % in Chunming Li et al's paper: 3 | % "Multiplicative intrinsic component optimization (MICO) for MRI bias field estimation and tissue segmentation", 4 | % Magnetic Resonance Imaging, vol. 32 (7), pp. 913-923, 2014 5 | % Author: Chunming Li, all rights reserved 6 | % E-mail: li_chunming@hotmail.com 7 | % URL: http://imagecomputing.org/~cmli/ 8 | clear all; 9 | close all; 10 | 11 | iterNum_outer=15; % outer iteration 12 | iterCM=2; % inner interation for C and M 13 | iter_b=1; % inner iteration for bias 14 | 15 | A = 255; 16 | q = 1.5; 17 | 18 | tissueLabel=[1, 2, 3]; 19 | 20 | th_bg = 5; %% threshold for removing background 21 | N_region = 3; %% number of tissues, e.g. WM, GM, CSF 22 | 23 | str_vector{1} = 'brainweb_byte_B3N2.nii'; % input a sequence of image file names 24 | % str_vector{2} = 'brainweb_byte_B3N1.nii'; 25 | 26 | 27 | MICO_3Dseq(str_vector, N_region, q, th_bg, iterNum_outer, iter_b, iterCM, tissueLabel); 28 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/load_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI header extension after its header is loaded using load_nii_hdr. 2 | % 3 | % Usage: ext = load_nii_ext(filename) 4 | % 5 | % filename - NIFTI file name. 6 | % 7 | % Returned values: 8 | % 9 | % ext - Structure of NIFTI header extension, which includes num_ext, 10 | % and all the extended header sections in the header extension. 11 | % Each extended header section will have its esize, ecode, and 12 | % edata, where edata can be plain text, xml, or any raw data 13 | % that was saved in the extended header section. 14 | % 15 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 16 | % 17 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 18 | % 19 | function ext = load_nii_ext(fileprefix) 20 | 21 | if ~exist('fileprefix','var'), 22 | error('Usage: ext = load_nii_ext(filename)'); 23 | end 24 | 25 | machine = 'ieee-le'; 26 | new_ext = 0; 27 | 28 | if findstr('.nii',fileprefix) 29 | new_ext = 1; 30 | fileprefix = strrep(fileprefix,'.nii',''); 31 | end 32 | 33 | if findstr('.hdr',fileprefix) 34 | fileprefix = strrep(fileprefix,'.hdr',''); 35 | end 36 | 37 | if findstr('.img',fileprefix) 38 | fileprefix = strrep(fileprefix,'.img',''); 39 | end 40 | 41 | if new_ext 42 | fn = sprintf('%s.nii',fileprefix); 43 | 44 | if ~exist(fn) 45 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 46 | error(msg); 47 | end 48 | else 49 | fn = sprintf('%s.hdr',fileprefix); 50 | 51 | if ~exist(fn) 52 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 53 | error(msg); 54 | end 55 | end 56 | 57 | fid = fopen(fn,'r',machine); 58 | vox_offset = 0; 59 | 60 | if fid < 0, 61 | msg = sprintf('Cannot open file %s.',fn); 62 | error(msg); 63 | else 64 | fseek(fid,0,'bof'); 65 | 66 | if fread(fid,1,'int32') == 348 67 | if new_ext 68 | fseek(fid,108,'bof'); 69 | vox_offset = fread(fid,1,'float32'); 70 | end 71 | 72 | ext = read_extension(fid, vox_offset); 73 | fclose(fid); 74 | else 75 | fclose(fid); 76 | 77 | % first try reading the opposite endian to 'machine' 78 | % 79 | switch machine, 80 | case 'ieee-le', machine = 'ieee-be'; 81 | case 'ieee-be', machine = 'ieee-le'; 82 | end 83 | 84 | fid = fopen(fn,'r',machine); 85 | 86 | if fid < 0, 87 | msg = sprintf('Cannot open file %s.',fn); 88 | error(msg); 89 | else 90 | fseek(fid,0,'bof'); 91 | 92 | if fread(fid,1,'int32') ~= 348 93 | 94 | % Now throw an error 95 | % 96 | msg = sprintf('File "%s" is corrupted.',fn); 97 | error(msg); 98 | end 99 | 100 | if new_ext 101 | fseek(fid,108,'bof'); 102 | vox_offset = fread(fid,1,'float32'); 103 | end 104 | 105 | ext = read_extension(fid, vox_offset); 106 | fclose(fid); 107 | end 108 | end 109 | end 110 | 111 | return % load_nii_ext 112 | 113 | 114 | %--------------------------------------------------------------------- 115 | function ext = read_extension(fid, vox_offset) 116 | 117 | ext = []; 118 | 119 | if vox_offset 120 | end_of_ext = vox_offset; 121 | else 122 | fseek(fid, 0, 'eof'); 123 | end_of_ext = ftell(fid); 124 | end 125 | 126 | if end_of_ext > 352 127 | fseek(fid, 348, 'bof'); 128 | ext.extension = fread(fid,4)'; 129 | end 130 | 131 | if isempty(ext) | ext.extension(1) == 0 132 | ext = []; 133 | return; 134 | end 135 | 136 | i = 1; 137 | 138 | while(ftell(fid) < end_of_ext) 139 | ext.section(i).esize = fread(fid,1,'int32'); 140 | ext.section(i).ecode = fread(fid,1,'int32'); 141 | ext.section(i).edata = char(fread(fid,ext.section(i).esize-8)'); 142 | i = i + 1; 143 | end 144 | 145 | ext.num_ext = length(ext.section); 146 | 147 | return % read_extension 148 | 149 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/load_untouch0_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function hdr = load_nii_hdr(fileprefix, machine) 6 | 7 | fn = sprintf('%s.hdr',fileprefix); 8 | fid = fopen(fn,'r',machine); 9 | 10 | if fid < 0, 11 | msg = sprintf('Cannot open file %s.',fn); 12 | error(msg); 13 | else 14 | fseek(fid,0,'bof'); 15 | hdr = read_header(fid); 16 | fclose(fid); 17 | end 18 | 19 | return % load_nii_hdr 20 | 21 | 22 | %--------------------------------------------------------------------- 23 | function [ dsr ] = read_header(fid) 24 | 25 | % Original header structures 26 | % struct dsr 27 | % { 28 | % struct header_key hk; /* 0 + 40 */ 29 | % struct image_dimension dime; /* 40 + 108 */ 30 | % struct data_history hist; /* 148 + 200 */ 31 | % }; /* total= 348 bytes*/ 32 | 33 | dsr.hk = header_key(fid); 34 | dsr.dime = image_dimension(fid); 35 | dsr.hist = data_history(fid); 36 | 37 | return % read_header 38 | 39 | 40 | %--------------------------------------------------------------------- 41 | function [ hk ] = header_key(fid) 42 | 43 | fseek(fid,0,'bof'); 44 | 45 | % Original header structures 46 | % struct header_key /* header key */ 47 | % { /* off + size */ 48 | % int sizeof_hdr /* 0 + 4 */ 49 | % char data_type[10]; /* 4 + 10 */ 50 | % char db_name[18]; /* 14 + 18 */ 51 | % int extents; /* 32 + 4 */ 52 | % short int session_error; /* 36 + 2 */ 53 | % char regular; /* 38 + 1 */ 54 | % char hkey_un0; /* 39 + 1 */ 55 | % }; /* total=40 bytes */ 56 | % 57 | % int sizeof_header Should be 348. 58 | % char regular Must be 'r' to indicate that all images and 59 | % volumes are the same size. 60 | 61 | v6 = version; 62 | if str2num(v6(1))<6 63 | directchar = '*char'; 64 | else 65 | directchar = 'uchar=>char'; 66 | end 67 | 68 | hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! 69 | hk.data_type = deblank(fread(fid,10,directchar)'); 70 | hk.db_name = deblank(fread(fid,18,directchar)'); 71 | hk.extents = fread(fid, 1,'int32')'; 72 | hk.session_error = fread(fid, 1,'int16')'; 73 | hk.regular = fread(fid, 1,directchar)'; 74 | hk.hkey_un0 = fread(fid, 1,directchar)'; 75 | 76 | return % header_key 77 | 78 | 79 | %--------------------------------------------------------------------- 80 | function [ dime ] = image_dimension(fid) 81 | 82 | %struct image_dimension 83 | % { /* off + size */ 84 | % short int dim[8]; /* 0 + 16 */ 85 | % /* 86 | % dim[0] Number of dimensions in database; usually 4. 87 | % dim[1] Image X dimension; number of *pixels* in an image row. 88 | % dim[2] Image Y dimension; number of *pixel rows* in slice. 89 | % dim[3] Volume Z dimension; number of *slices* in a volume. 90 | % dim[4] Time points; number of volumes in database 91 | % */ 92 | % char vox_units[4]; /* 16 + 4 */ 93 | % char cal_units[8]; /* 20 + 8 */ 94 | % short int unused1; /* 28 + 2 */ 95 | % short int datatype; /* 30 + 2 */ 96 | % short int bitpix; /* 32 + 2 */ 97 | % short int dim_un0; /* 34 + 2 */ 98 | % float pixdim[8]; /* 36 + 32 */ 99 | % /* 100 | % pixdim[] specifies the voxel dimensions: 101 | % pixdim[1] - voxel width, mm 102 | % pixdim[2] - voxel height, mm 103 | % pixdim[3] - slice thickness, mm 104 | % pixdim[4] - volume timing, in msec 105 | % ..etc 106 | % */ 107 | % float vox_offset; /* 68 + 4 */ 108 | % float roi_scale; /* 72 + 4 */ 109 | % float funused1; /* 76 + 4 */ 110 | % float funused2; /* 80 + 4 */ 111 | % float cal_max; /* 84 + 4 */ 112 | % float cal_min; /* 88 + 4 */ 113 | % int compressed; /* 92 + 4 */ 114 | % int verified; /* 96 + 4 */ 115 | % int glmax; /* 100 + 4 */ 116 | % int glmin; /* 104 + 4 */ 117 | % }; /* total=108 bytes */ 118 | 119 | v6 = version; 120 | if str2num(v6(1))<6 121 | directchar = '*char'; 122 | else 123 | directchar = 'uchar=>char'; 124 | end 125 | 126 | dime.dim = fread(fid,8,'int16')'; 127 | dime.vox_units = deblank(fread(fid,4,directchar)'); 128 | dime.cal_units = deblank(fread(fid,8,directchar)'); 129 | dime.unused1 = fread(fid,1,'int16')'; 130 | dime.datatype = fread(fid,1,'int16')'; 131 | dime.bitpix = fread(fid,1,'int16')'; 132 | dime.dim_un0 = fread(fid,1,'int16')'; 133 | dime.pixdim = fread(fid,8,'float32')'; 134 | dime.vox_offset = fread(fid,1,'float32')'; 135 | dime.roi_scale = fread(fid,1,'float32')'; 136 | dime.funused1 = fread(fid,1,'float32')'; 137 | dime.funused2 = fread(fid,1,'float32')'; 138 | dime.cal_max = fread(fid,1,'float32')'; 139 | dime.cal_min = fread(fid,1,'float32')'; 140 | dime.compressed = fread(fid,1,'int32')'; 141 | dime.verified = fread(fid,1,'int32')'; 142 | dime.glmax = fread(fid,1,'int32')'; 143 | dime.glmin = fread(fid,1,'int32')'; 144 | 145 | return % image_dimension 146 | 147 | 148 | %--------------------------------------------------------------------- 149 | function [ hist ] = data_history(fid) 150 | 151 | %struct data_history 152 | % { /* off + size */ 153 | % char descrip[80]; /* 0 + 80 */ 154 | % char aux_file[24]; /* 80 + 24 */ 155 | % char orient; /* 104 + 1 */ 156 | % char originator[10]; /* 105 + 10 */ 157 | % char generated[10]; /* 115 + 10 */ 158 | % char scannum[10]; /* 125 + 10 */ 159 | % char patient_id[10]; /* 135 + 10 */ 160 | % char exp_date[10]; /* 145 + 10 */ 161 | % char exp_time[10]; /* 155 + 10 */ 162 | % char hist_un0[3]; /* 165 + 3 */ 163 | % int views /* 168 + 4 */ 164 | % int vols_added; /* 172 + 4 */ 165 | % int start_field; /* 176 + 4 */ 166 | % int field_skip; /* 180 + 4 */ 167 | % int omax; /* 184 + 4 */ 168 | % int omin; /* 188 + 4 */ 169 | % int smax; /* 192 + 4 */ 170 | % int smin; /* 196 + 4 */ 171 | % }; /* total=200 bytes */ 172 | 173 | v6 = version; 174 | if str2num(v6(1))<6 175 | directchar = '*char'; 176 | else 177 | directchar = 'uchar=>char'; 178 | end 179 | 180 | hist.descrip = deblank(fread(fid,80,directchar)'); 181 | hist.aux_file = deblank(fread(fid,24,directchar)'); 182 | hist.orient = fread(fid, 1,'char')'; 183 | hist.originator = fread(fid, 5,'int16')'; 184 | hist.generated = deblank(fread(fid,10,directchar)'); 185 | hist.scannum = deblank(fread(fid,10,directchar)'); 186 | hist.patient_id = deblank(fread(fid,10,directchar)'); 187 | hist.exp_date = deblank(fread(fid,10,directchar)'); 188 | hist.exp_time = deblank(fread(fid,10,directchar)'); 189 | hist.hist_un0 = deblank(fread(fid, 3,directchar)'); 190 | hist.views = fread(fid, 1,'int32')'; 191 | hist.vols_added = fread(fid, 1,'int32')'; 192 | hist.start_field = fread(fid, 1,'int32')'; 193 | hist.field_skip = fread(fid, 1,'int32')'; 194 | hist.omax = fread(fid, 1,'int32')'; 195 | hist.omin = fread(fid, 1,'int32')'; 196 | hist.smax = fread(fid, 1,'int32')'; 197 | hist.smin = fread(fid, 1,'int32')'; 198 | 199 | return % data_history 200 | 201 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/load_untouch_nii.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI or ANALYZE dataset, but not applying any appropriate affine 2 | % geometric transform or voxel intensity scaling. 3 | % 4 | % Although according to NIFTI website, all those header information are 5 | % supposed to be applied to the loaded NIFTI image, there are some 6 | % situations that people do want to leave the original NIFTI header and 7 | % data untouched. They will probably just use MATLAB to do certain image 8 | % processing regardless of image orientation, and to save data back with 9 | % the same NIfTI header. 10 | % 11 | % Since this program is only served for those situations, please use it 12 | % together with "save_untouch_nii.m", and do not use "save_nii.m" or 13 | % "view_nii.m" for the data that is loaded by "load_untouch_nii.m". For 14 | % normal situation, you should use "load_nii.m" instead. 15 | % 16 | % Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... 17 | % [dim7_idx], [old_RGB], [slice_idx]) 18 | % 19 | % filename - NIFTI or ANALYZE file name. 20 | % 21 | % img_idx (optional) - a numerical array of image volume indices. 22 | % Only the specified volumes will be loaded. All available image 23 | % volumes will be loaded, if it is default or empty. 24 | % 25 | % The number of images scans can be obtained from get_nii_frame.m, 26 | % or simply: hdr.dime.dim(5). 27 | % 28 | % dim5_idx (optional) - a numerical array of 5th dimension indices. 29 | % Only the specified range will be loaded. All available range 30 | % will be loaded, if it is default or empty. 31 | % 32 | % dim6_idx (optional) - a numerical array of 6th dimension indices. 33 | % Only the specified range will be loaded. All available range 34 | % will be loaded, if it is default or empty. 35 | % 36 | % dim7_idx (optional) - a numerical array of 7th dimension indices. 37 | % Only the specified range will be loaded. All available range 38 | % will be loaded, if it is default or empty. 39 | % 40 | % old_RGB (optional) - a scale number to tell difference of new RGB24 41 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 42 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 43 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 44 | % each slices. If the image that you view is garbled, try to set 45 | % old_RGB variable to 1 and try again, because it could be in 46 | % old RGB24. It will be set to 0, if it is default or empty. 47 | % 48 | % slice_idx (optional) - a numerical array of image slice indices. 49 | % Only the specified volumes will be loaded. All available image 50 | % slices will be loaded, if it is default or empty. 51 | % 52 | % Returned values: 53 | % 54 | % nii structure: 55 | % 56 | % hdr - struct with NIFTI header fields. 57 | % 58 | % filetype - Analyze format .hdr/.img (0); 59 | % NIFTI .hdr/.img (1); 60 | % NIFTI .nii (2) 61 | % 62 | % fileprefix - NIFTI filename without extension. 63 | % 64 | % machine - machine string variable. 65 | % 66 | % img - 3D (or 4D) matrix of NIFTI data. 67 | % 68 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 69 | % 70 | function nii = load_untouch_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... 71 | old_RGB, slice_idx) 72 | 73 | if ~exist('filename','var') 74 | error('Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [slice_idx])'); 75 | end 76 | 77 | if ~exist('img_idx','var') | isempty(img_idx) 78 | img_idx = []; 79 | end 80 | 81 | if ~exist('dim5_idx','var') | isempty(dim5_idx) 82 | dim5_idx = []; 83 | end 84 | 85 | if ~exist('dim6_idx','var') | isempty(dim6_idx) 86 | dim6_idx = []; 87 | end 88 | 89 | if ~exist('dim7_idx','var') | isempty(dim7_idx) 90 | dim7_idx = []; 91 | end 92 | 93 | if ~exist('old_RGB','var') | isempty(old_RGB) 94 | old_RGB = 0; 95 | end 96 | 97 | if ~exist('slice_idx','var') | isempty(slice_idx) 98 | slice_idx = []; 99 | end 100 | 101 | % Read the dataset header 102 | % 103 | [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); 104 | 105 | if nii.filetype == 0 106 | nii.hdr = load_untouch0_nii_hdr(nii.fileprefix,nii.machine); 107 | nii.ext = []; 108 | else 109 | nii.hdr = load_untouch_nii_hdr(nii.fileprefix,nii.machine,nii.filetype); 110 | 111 | % Read the header extension 112 | % 113 | nii.ext = load_nii_ext(filename); 114 | end 115 | 116 | % Read the dataset body 117 | % 118 | [nii.img,nii.hdr] = load_untouch_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... 119 | nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx); 120 | 121 | % Perform some of sform/qform transform 122 | % 123 | % nii = xform_nii(nii, tolerance, preferredForm); 124 | 125 | nii.untouch = 1; 126 | 127 | return % load_untouch_nii 128 | 129 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/load_untouch_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function hdr = load_nii_hdr(fileprefix, machine, filetype) 6 | 7 | if filetype == 2 8 | fn = sprintf('%s.nii',fileprefix); 9 | 10 | if ~exist(fn) 11 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 12 | error(msg); 13 | end 14 | else 15 | fn = sprintf('%s.hdr',fileprefix); 16 | 17 | if ~exist(fn) 18 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 19 | error(msg); 20 | end 21 | end 22 | 23 | fid = fopen(fn,'r',machine); 24 | 25 | if fid < 0, 26 | msg = sprintf('Cannot open file %s.',fn); 27 | error(msg); 28 | else 29 | fseek(fid,0,'bof'); 30 | hdr = read_header(fid); 31 | fclose(fid); 32 | end 33 | 34 | return % load_nii_hdr 35 | 36 | 37 | %--------------------------------------------------------------------- 38 | function [ dsr ] = read_header(fid) 39 | 40 | % Original header structures 41 | % struct dsr 42 | % { 43 | % struct header_key hk; /* 0 + 40 */ 44 | % struct image_dimension dime; /* 40 + 108 */ 45 | % struct data_history hist; /* 148 + 200 */ 46 | % }; /* total= 348 bytes*/ 47 | 48 | dsr.hk = header_key(fid); 49 | dsr.dime = image_dimension(fid); 50 | dsr.hist = data_history(fid); 51 | 52 | % For Analyze data format 53 | % 54 | if ~strcmp(dsr.hist.magic, 'n+1') & ~strcmp(dsr.hist.magic, 'ni1') 55 | dsr.hist.qform_code = 0; 56 | dsr.hist.sform_code = 0; 57 | end 58 | 59 | return % read_header 60 | 61 | 62 | %--------------------------------------------------------------------- 63 | function [ hk ] = header_key(fid) 64 | 65 | fseek(fid,0,'bof'); 66 | 67 | % Original header structures 68 | % struct header_key /* header key */ 69 | % { /* off + size */ 70 | % int sizeof_hdr /* 0 + 4 */ 71 | % char data_type[10]; /* 4 + 10 */ 72 | % char db_name[18]; /* 14 + 18 */ 73 | % int extents; /* 32 + 4 */ 74 | % short int session_error; /* 36 + 2 */ 75 | % char regular; /* 38 + 1 */ 76 | % char dim_info; % char hkey_un0; /* 39 + 1 */ 77 | % }; /* total=40 bytes */ 78 | % 79 | % int sizeof_header Should be 348. 80 | % char regular Must be 'r' to indicate that all images and 81 | % volumes are the same size. 82 | 83 | v6 = version; 84 | if str2num(v6(1))<6 85 | directchar = '*char'; 86 | else 87 | directchar = 'uchar=>char'; 88 | end 89 | 90 | hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! 91 | hk.data_type = deblank(fread(fid,10,directchar)'); 92 | hk.db_name = deblank(fread(fid,18,directchar)'); 93 | hk.extents = fread(fid, 1,'int32')'; 94 | hk.session_error = fread(fid, 1,'int16')'; 95 | hk.regular = fread(fid, 1,directchar)'; 96 | hk.dim_info = fread(fid, 1,'uchar')'; 97 | 98 | return % header_key 99 | 100 | 101 | %--------------------------------------------------------------------- 102 | function [ dime ] = image_dimension(fid) 103 | 104 | % Original header structures 105 | % struct image_dimension 106 | % { /* off + size */ 107 | % short int dim[8]; /* 0 + 16 */ 108 | % /* 109 | % dim[0] Number of dimensions in database; usually 4. 110 | % dim[1] Image X dimension; number of *pixels* in an image row. 111 | % dim[2] Image Y dimension; number of *pixel rows* in slice. 112 | % dim[3] Volume Z dimension; number of *slices* in a volume. 113 | % dim[4] Time points; number of volumes in database 114 | % */ 115 | % float intent_p1; % char vox_units[4]; /* 16 + 4 */ 116 | % float intent_p2; % char cal_units[8]; /* 20 + 4 */ 117 | % float intent_p3; % char cal_units[8]; /* 24 + 4 */ 118 | % short int intent_code; % short int unused1; /* 28 + 2 */ 119 | % short int datatype; /* 30 + 2 */ 120 | % short int bitpix; /* 32 + 2 */ 121 | % short int slice_start; % short int dim_un0; /* 34 + 2 */ 122 | % float pixdim[8]; /* 36 + 32 */ 123 | % /* 124 | % pixdim[] specifies the voxel dimensions: 125 | % pixdim[1] - voxel width, mm 126 | % pixdim[2] - voxel height, mm 127 | % pixdim[3] - slice thickness, mm 128 | % pixdim[4] - volume timing, in msec 129 | % ..etc 130 | % */ 131 | % float vox_offset; /* 68 + 4 */ 132 | % float scl_slope; % float roi_scale; /* 72 + 4 */ 133 | % float scl_inter; % float funused1; /* 76 + 4 */ 134 | % short slice_end; % float funused2; /* 80 + 2 */ 135 | % char slice_code; % float funused2; /* 82 + 1 */ 136 | % char xyzt_units; % float funused2; /* 83 + 1 */ 137 | % float cal_max; /* 84 + 4 */ 138 | % float cal_min; /* 88 + 4 */ 139 | % float slice_duration; % int compressed; /* 92 + 4 */ 140 | % float toffset; % int verified; /* 96 + 4 */ 141 | % int glmax; /* 100 + 4 */ 142 | % int glmin; /* 104 + 4 */ 143 | % }; /* total=108 bytes */ 144 | 145 | dime.dim = fread(fid,8,'int16')'; 146 | dime.intent_p1 = fread(fid,1,'float32')'; 147 | dime.intent_p2 = fread(fid,1,'float32')'; 148 | dime.intent_p3 = fread(fid,1,'float32')'; 149 | dime.intent_code = fread(fid,1,'int16')'; 150 | dime.datatype = fread(fid,1,'int16')'; 151 | dime.bitpix = fread(fid,1,'int16')'; 152 | dime.slice_start = fread(fid,1,'int16')'; 153 | dime.pixdim = fread(fid,8,'float32')'; 154 | dime.vox_offset = fread(fid,1,'float32')'; 155 | dime.scl_slope = fread(fid,1,'float32')'; 156 | dime.scl_inter = fread(fid,1,'float32')'; 157 | dime.slice_end = fread(fid,1,'int16')'; 158 | dime.slice_code = fread(fid,1,'uchar')'; 159 | dime.xyzt_units = fread(fid,1,'uchar')'; 160 | dime.cal_max = fread(fid,1,'float32')'; 161 | dime.cal_min = fread(fid,1,'float32')'; 162 | dime.slice_duration = fread(fid,1,'float32')'; 163 | dime.toffset = fread(fid,1,'float32')'; 164 | dime.glmax = fread(fid,1,'int32')'; 165 | dime.glmin = fread(fid,1,'int32')'; 166 | 167 | return % image_dimension 168 | 169 | 170 | %--------------------------------------------------------------------- 171 | function [ hist ] = data_history(fid) 172 | 173 | % Original header structures 174 | % struct data_history 175 | % { /* off + size */ 176 | % char descrip[80]; /* 0 + 80 */ 177 | % char aux_file[24]; /* 80 + 24 */ 178 | % short int qform_code; /* 104 + 2 */ 179 | % short int sform_code; /* 106 + 2 */ 180 | % float quatern_b; /* 108 + 4 */ 181 | % float quatern_c; /* 112 + 4 */ 182 | % float quatern_d; /* 116 + 4 */ 183 | % float qoffset_x; /* 120 + 4 */ 184 | % float qoffset_y; /* 124 + 4 */ 185 | % float qoffset_z; /* 128 + 4 */ 186 | % float srow_x[4]; /* 132 + 16 */ 187 | % float srow_y[4]; /* 148 + 16 */ 188 | % float srow_z[4]; /* 164 + 16 */ 189 | % char intent_name[16]; /* 180 + 16 */ 190 | % char magic[4]; % int smin; /* 196 + 4 */ 191 | % }; /* total=200 bytes */ 192 | 193 | v6 = version; 194 | if str2num(v6(1))<6 195 | directchar = '*char'; 196 | else 197 | directchar = 'uchar=>char'; 198 | end 199 | 200 | hist.descrip = deblank(fread(fid,80,directchar)'); 201 | hist.aux_file = deblank(fread(fid,24,directchar)'); 202 | hist.qform_code = fread(fid,1,'int16')'; 203 | hist.sform_code = fread(fid,1,'int16')'; 204 | hist.quatern_b = fread(fid,1,'float32')'; 205 | hist.quatern_c = fread(fid,1,'float32')'; 206 | hist.quatern_d = fread(fid,1,'float32')'; 207 | hist.qoffset_x = fread(fid,1,'float32')'; 208 | hist.qoffset_y = fread(fid,1,'float32')'; 209 | hist.qoffset_z = fread(fid,1,'float32')'; 210 | hist.srow_x = fread(fid,4,'float32')'; 211 | hist.srow_y = fread(fid,4,'float32')'; 212 | hist.srow_z = fread(fid,4,'float32')'; 213 | hist.intent_name = deblank(fread(fid,16,directchar)'); 214 | hist.magic = deblank(fread(fid,4,directchar)'); 215 | 216 | return % data_history 217 | 218 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/make_nii.m: -------------------------------------------------------------------------------- 1 | % Make NIfTI structure specified by an N-D matrix. Usually, N is 3 for 2 | % 3D matrix [x y z], or 4 for 4D matrix with time series [x y z t]. 3 | % Optional parameters can also be included, such as: voxel_size, 4 | % origin, datatype, and description. 5 | % 6 | % Once the NIfTI structure is made, it can be saved into NIfTI file 7 | % using "save_nii" command (for more detail, type: help save_nii). 8 | % 9 | % Usage: nii = make_nii(img, [voxel_size], [origin], [datatype], [description]) 10 | % 11 | % Where: 12 | % 13 | % img: Usually, img is a 3D matrix [x y z], or a 4D 14 | % matrix with time series [x y z t]. However, 15 | % NIfTI allows a maximum of 7D matrix. When the 16 | % image is in RGB format, make sure that the size 17 | % of 4th dimension is always 3 (i.e. [R G B]). In 18 | % that case, make sure that you must specify RGB 19 | % datatype, which is either 128 or 511. 20 | % 21 | % voxel_size (optional): Voxel size in millimeter for each 22 | % dimension. Default is [1 1 1]. 23 | % 24 | % origin (optional): The AC origin. Default is [0 0 0]. 25 | % 26 | % datatype (optional): Storage data type: 27 | % 2 - uint8, 4 - int16, 8 - int32, 16 - float32, 28 | % 32 - complex64, 64 - float64, 128 - RGB24, 29 | % 256 - int8, 511 - RGB96, 512 - uint16, 30 | % 768 - uint32, 1792 - complex128 31 | % Default will use the data type of 'img' matrix 32 | % For RGB image, you must specify it to either 128 33 | % or 511. 34 | % 35 | % description (optional): Description of data. Default is ''. 36 | % 37 | % e.g.: 38 | % origin = [33 44 13]; datatype = 64; 39 | % nii = make_nii(img, [], origin, datatype); % default voxel_size 40 | % 41 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 42 | % 43 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 44 | % 45 | function nii = make_nii(varargin) 46 | 47 | nii.img = varargin{1}; 48 | dims = size(nii.img); 49 | dims = [length(dims) dims ones(1,8)]; 50 | dims = dims(1:8); 51 | 52 | voxel_size = [0 ones(1,7)]; 53 | origin = zeros(1,5); 54 | descrip = ''; 55 | 56 | switch class(nii.img) 57 | case 'uint8' 58 | datatype = 2; 59 | case 'int16' 60 | datatype = 4; 61 | case 'int32' 62 | datatype = 8; 63 | case 'single' 64 | if isreal(nii.img) 65 | datatype = 16; 66 | else 67 | datatype = 32; 68 | end 69 | case 'double' 70 | if isreal(nii.img) 71 | datatype = 64; 72 | else 73 | datatype = 1792; 74 | end 75 | case 'int8' 76 | datatype = 256; 77 | case 'uint16' 78 | datatype = 512; 79 | case 'uint32' 80 | datatype = 768; 81 | otherwise 82 | error('Datatype is not supported by make_nii.'); 83 | end 84 | 85 | if nargin > 1 & ~isempty(varargin{2}) 86 | voxel_size(2:4) = double(varargin{2}); 87 | end 88 | 89 | if nargin > 2 & ~isempty(varargin{3}) 90 | origin(1:3) = double(varargin{3}); 91 | end 92 | 93 | if nargin > 3 & ~isempty(varargin{4}) 94 | datatype = double(varargin{4}); 95 | 96 | if datatype == 128 | datatype == 511 97 | dims(5) = []; 98 | dims(1) = dims(1) - 1; 99 | dims = [dims 1]; 100 | end 101 | end 102 | 103 | if nargin > 4 & ~isempty(varargin{5}) 104 | descrip = varargin{5}; 105 | end 106 | 107 | if ndims(nii.img) > 7 108 | error('NIfTI only allows a maximum of 7 Dimension matrix.'); 109 | end 110 | 111 | maxval = round(double(max(nii.img(:)))); 112 | minval = round(double(min(nii.img(:)))); 113 | 114 | nii.hdr = make_header(dims, voxel_size, origin, datatype, ... 115 | descrip, maxval, minval); 116 | 117 | switch nii.hdr.dime.datatype 118 | case 2 119 | nii.img = uint8(nii.img); 120 | case 4 121 | nii.img = int16(nii.img); 122 | case 8 123 | nii.img = int32(nii.img); 124 | case 16 125 | nii.img = single(nii.img); 126 | case 32 127 | nii.img = single(nii.img); 128 | case 64 129 | nii.img = double(nii.img); 130 | case 128 131 | nii.img = uint8(nii.img); 132 | case 256 133 | nii.img = int8(nii.img); 134 | case 511 135 | img = double(nii.img(:)); 136 | img = single((img - min(img))/(max(img) - min(img))); 137 | nii.img = reshape(img, size(nii.img)); 138 | nii.hdr.dime.glmax = double(max(img)); 139 | nii.hdr.dime.glmin = double(min(img)); 140 | case 512 141 | nii.img = uint16(nii.img); 142 | case 768 143 | nii.img = uint32(nii.img); 144 | case 1792 145 | nii.img = double(nii.img); 146 | otherwise 147 | error('Datatype is not supported by make_nii.'); 148 | end 149 | 150 | return; % make_nii 151 | 152 | 153 | %--------------------------------------------------------------------- 154 | function hdr = make_header(dims, voxel_size, origin, datatype, ... 155 | descrip, maxval, minval) 156 | 157 | hdr.hk = header_key; 158 | hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); 159 | hdr.hist = data_history(origin, descrip); 160 | 161 | return; % make_header 162 | 163 | 164 | %--------------------------------------------------------------------- 165 | function hk = header_key 166 | 167 | hk.sizeof_hdr = 348; % must be 348! 168 | hk.data_type = ''; 169 | hk.db_name = ''; 170 | hk.extents = 0; 171 | hk.session_error = 0; 172 | hk.regular = 'r'; 173 | hk.dim_info = 0; 174 | 175 | return; % header_key 176 | 177 | 178 | %--------------------------------------------------------------------- 179 | function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) 180 | 181 | dime.dim = dims; 182 | dime.intent_p1 = 0; 183 | dime.intent_p2 = 0; 184 | dime.intent_p3 = 0; 185 | dime.intent_code = 0; 186 | dime.datatype = datatype; 187 | 188 | switch dime.datatype 189 | case 2, 190 | dime.bitpix = 8; precision = 'uint8'; 191 | case 4, 192 | dime.bitpix = 16; precision = 'int16'; 193 | case 8, 194 | dime.bitpix = 32; precision = 'int32'; 195 | case 16, 196 | dime.bitpix = 32; precision = 'float32'; 197 | case 32, 198 | dime.bitpix = 64; precision = 'float32'; 199 | case 64, 200 | dime.bitpix = 64; precision = 'float64'; 201 | case 128 202 | dime.bitpix = 24; precision = 'uint8'; 203 | case 256 204 | dime.bitpix = 8; precision = 'int8'; 205 | case 511 206 | dime.bitpix = 96; precision = 'float32'; 207 | case 512 208 | dime.bitpix = 16; precision = 'uint16'; 209 | case 768 210 | dime.bitpix = 32; precision = 'uint32'; 211 | case 1792, 212 | dime.bitpix = 128; precision = 'float64'; 213 | otherwise 214 | error('Datatype is not supported by make_nii.'); 215 | end 216 | 217 | dime.slice_start = 0; 218 | dime.pixdim = voxel_size; 219 | dime.vox_offset = 0; 220 | dime.scl_slope = 0; 221 | dime.scl_inter = 0; 222 | dime.slice_end = 0; 223 | dime.slice_code = 0; 224 | dime.xyzt_units = 0; 225 | dime.cal_max = 0; 226 | dime.cal_min = 0; 227 | dime.slice_duration = 0; 228 | dime.toffset = 0; 229 | dime.glmax = maxval; 230 | dime.glmin = minval; 231 | 232 | return; % image_dimension 233 | 234 | 235 | %--------------------------------------------------------------------- 236 | function hist = data_history(origin, descrip) 237 | 238 | hist.descrip = descrip; 239 | hist.aux_file = 'none'; 240 | hist.qform_code = 0; 241 | hist.sform_code = 0; 242 | hist.quatern_b = 0; 243 | hist.quatern_c = 0; 244 | hist.quatern_d = 0; 245 | hist.qoffset_x = 0; 246 | hist.qoffset_y = 0; 247 | hist.qoffset_z = 0; 248 | hist.srow_x = zeros(1,4); 249 | hist.srow_y = zeros(1,4); 250 | hist.srow_z = zeros(1,4); 251 | hist.intent_name = ''; 252 | hist.magic = ''; 253 | hist.originator = origin; 254 | 255 | return; % data_history 256 | 257 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/saveBasisOrder3_3D.m: -------------------------------------------------------------------------------- 1 | function saveBasisOrder3_3D(ROI) 2 | 3 | [DimX, DimY,DimZ]=size(ROI); 4 | % x = zeros(Height,Wide,Z); 5 | % y = zeros(Height,Wide,Z); 6 | % z = zeros(Height,Wide,Z); 7 | 8 | tempX = -1:2/(DimX-1):1; 9 | tempY = -1:2/(DimY-1):1; 10 | tempZ = -1:2/(DimZ-1):1; 11 | 12 | [x y z]=meshgrid(tempY, tempX, tempZ); 13 | basis=ones(size(x)); 14 | for basis_index = 1:20 15 | 16 | switch basis_index 17 | case 1 18 | basis = ROI; 19 | case 2 20 | basis = ROI.*z; 21 | case 3 22 | basis = ROI.*(3*z.*z - 1)/2; 23 | case 4 24 | basis = ROI.*(5*z.*z.*z - 3*z)/2; 25 | case 5 26 | basis = ROI.*y; 27 | case 6 28 | basis = ROI.*y.*z; 29 | case 7 30 | basis = ROI.*y.*(3*z.*z - 1)/2; 31 | 32 | case 8 33 | basis = ROI.*(3*y.*y - 1)/2; 34 | case 9 35 | basis = ROI.*z.*(3*y.*y - 1)/2; 36 | 37 | case 10 38 | basis = ROI.*(5*y.*y.*y - 3*y)/2; 39 | 40 | case 11 41 | basis = ROI.*x; 42 | case 12 43 | basis = ROI.*x.*z; 44 | case 13 45 | basis = ROI.*x.*(3*z.*z-1)/2; 46 | 47 | case 14 48 | basis = ROI.*x.*y; 49 | case 15 50 | basis = ROI.*x.*y.*z; 51 | 52 | case 16 53 | basis = ROI.*x.*(3*y.*y-1)/2; 54 | 55 | case 17 56 | basis = ROI.*(3*x.*x-1)/2; 57 | case 18 58 | basis = ROI.*z.*(3*x.*x-1)/2; 59 | 60 | case 19 61 | basis = ROI.*y.*(3*x.*x-1)/2; 62 | 63 | case 20 64 | basis = ROI.*(5*x.*x.*x-3*x)/2; 65 | end 66 | 67 | A=basis.^2; 68 | s = sum(A(:)); 69 | basis=basis/s; 70 | clear A s; 71 | 72 | filename = ['basis_',num2str(basis_index),'.mat']; 73 | save(filename,'basis'); 74 | 75 | end 76 | 77 | clear x y z basis; 78 | 79 | -------------------------------------------------------------------------------- /Bias Correction(Li)/MICO_v0/MICO_3D/sortMemC.m: -------------------------------------------------------------------------------- 1 | function [M_out, C_out]=sortMemC(M, C) 2 | 3 | [C_out IDX]=sort(C); 4 | 5 | for k = 1 : length(C) 6 | M_out(:,:,:,k) = M(:,:,:,IDX(k)); 7 | end 8 | 9 | -------------------------------------------------------------------------------- /Bias Correction(Li)/heart_ct.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/heart_ct.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/lse_bfe.m: -------------------------------------------------------------------------------- 1 | function [u, b, C]= lse_bfe(u0,Img, b, Ksigma,KONE, nu,timestep,mu,epsilon, iter_lse) 2 | % This code implements the level set evolution (LSE) and bias field estimation 3 | % proposed in the following paper: 4 | % C. Li, R. Huang, Z. Ding, C. Gatenby, D. N. Metaxas, and J. C. Gore, 5 | % "A Level Set Method for Image Segmentation in the Presence of Intensity 6 | % Inhomogeneities with Application to MRI", IEEE Trans. Image Processing, 2011 7 | % 8 | % Note: 9 | % This code implements the two-phase formulation of the model in the above paper. 10 | % The two-phase formulation uses the signs of a level set function to represent 11 | % two disjoint regions, and therefore can be used to segment an image into two regions, 12 | % which are represented by (u>0) and (u<0), where u is the level set function. 13 | % 14 | % All rights researved by Chunming Li, who formulated the model, designed and 15 | % implemented the algorithm in the above paper. 16 | % 17 | % E-mail: lchunming@gmail.com 18 | % URL: http://www.engr.uconn.edu/~cmli/ 19 | % Copyright (c) by Chunming Li 20 | % Author: Chunming Li 21 | 22 | u=u0; 23 | KB1 = conv2(b,Ksigma,'same'); 24 | KB2 = conv2(b.^2,Ksigma,'same'); 25 | C =updateC(Img, u, KB1, KB2, epsilon); 26 | 27 | KONE_Img = Img.^2.*KONE; 28 | u = updateLSF(Img,u, C, KONE_Img, KB1, KB2, mu, nu, timestep, epsilon, iter_lse); 29 | 30 | Hu=Heaviside(u,epsilon); 31 | M(:,:,1)=Hu; 32 | M(:,:,2)=1-Hu; 33 | b =updateB(Img, C, M, Ksigma); 34 | 35 | 36 | % update level set function 37 | function u = updateLSF(Img, u0, C, KONE_Img, KB1, KB2, mu, nu, timestep, epsilon, iter_lse) 38 | u=u0; 39 | Hu=Heaviside(u,epsilon); 40 | M(:,:,1)=Hu; 41 | M(:,:,2)=1-Hu; 42 | N_class=size(M,3); 43 | e=zeros(size(M)); 44 | u=u0; 45 | for kk=1:N_class 46 | e(:,:,kk) = KONE_Img - 2*Img.*C(kk).*KB1 + C(kk)^2*KB2; 47 | end 48 | 49 | for kk=1:iter_lse 50 | u=NeumannBoundCond(u); 51 | K=curvature_central(u); % div() 52 | DiracU=Dirac(u,epsilon); 53 | ImageTerm=-DiracU.*(e(:,:,1)-e(:,:,2)); 54 | penalizeTerm=mu*(4*del2(u)-K); 55 | lengthTerm=nu.*DiracU.*K; 56 | u=u+timestep*(lengthTerm+penalizeTerm+ImageTerm); 57 | end 58 | 59 | % update b 60 | function b =updateB(Img, C, M, Ksigma) 61 | 62 | PC1=zeros(size(Img)); 63 | PC2=PC1; 64 | N_class=size(M,3); 65 | for kk=1:N_class 66 | PC1=PC1+C(kk)*M(:,:,kk); 67 | PC2=PC2+C(kk)^2*M(:,:,kk); 68 | end 69 | KNm1 = conv2(PC1.*Img,Ksigma,'same'); 70 | KDn1 = conv2(PC2,Ksigma,'same'); 71 | 72 | b = KNm1./KDn1; 73 | 74 | % Update C 75 | function C_new =updateC(Img, u, Kb1, Kb2, epsilon) 76 | Hu=Heaviside(u,epsilon); 77 | M(:,:,1)=Hu; 78 | M(:,:,2)=1-Hu; 79 | N_class=size(M,3); 80 | for kk=1:N_class 81 | Nm2 = Kb1.*Img.*M(:,:,kk); 82 | Dn2 = Kb2.*M(:,:,kk); 83 | C_new(kk) = sum(Nm2(:))/sum(Dn2(:)); 84 | end 85 | 86 | 87 | 88 | % Make a function satisfy Neumann boundary condition 89 | function g = NeumannBoundCond(f) 90 | [nrow,ncol] = size(f); 91 | g = f; 92 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 93 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 94 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 95 | 96 | function k = curvature_central(u) 97 | % compute curvature for u with central difference scheme 98 | [ux,uy] = gradient(u); 99 | normDu = sqrt(ux.^2+uy.^2+1e-10); 100 | Nx = ux./normDu; 101 | Ny = uy./normDu; 102 | [nxx,junk] = gradient(Nx); 103 | [junk,nyy] = gradient(Ny); 104 | k = nxx+nyy; 105 | 106 | function h = Heaviside(x,epsilon) 107 | h=0.5*(1+(2/pi)*atan(x./epsilon)); 108 | 109 | function f = Dirac(x, epsilon) 110 | f=(epsilon/pi)./(epsilon^2.+x.^2); 111 | 112 | -------------------------------------------------------------------------------- /Bias Correction(Li)/lse_bfe_3Phase.m: -------------------------------------------------------------------------------- 1 | function [u, b, C]= lse_bfe_3Phase(u,Img,b,Ksigma,KONE, nu,timestep,mu, epsilon,Iter) 2 | % This code implements the level set evolution (LSE) and bias field estimation 3 | % proposed in the following paper: 4 | % C. Li, R. Huang, Z. Ding, C. Gatenby, D. N. Metaxas, and J. C. Gore, 5 | % "A Level Set Method for Image Segmentation in the Presence of Intensity 6 | % Inhomogeneities with Application to MRI", IEEE Trans. Image Processing, 2011 7 | % 8 | % Note: 9 | % This code implements the three-phase formulation of the model in the above paper. 10 | % The three-phase formulation is used to segment an image into three regions. 11 | % The code for four-phase or other multi-phase formulation will be released later 12 | % in the website below. 13 | % 14 | % All rights researved by Chunming Li, who formulated the model, designed and 15 | % implemented the algorithm in the above paper. 16 | % 17 | % E-mail: lchunming@gmail.com 18 | % URL: http://www.engr.uconn.edu/~cmli/ 19 | % Copyright (c) by Chunming Li 20 | % Author: Chunming Li 21 | 22 | 23 | N_class = 3; % three-phase 24 | KB1 = conv2(b,Ksigma,'same'); 25 | KB2 = conv2(b.^2,Ksigma,'same'); 26 | H1 = Heaviside(u(:,:,1),epsilon ); 27 | H2 = Heaviside(u(:,:,2),epsilon ); 28 | M(:,:,1)=H1.*H2; % membership function 1 29 | M(:,:,2)=H1.*(1-H2); % membership function 2 30 | M(:,:,3)=(1-H1); % membership function 3 31 | C = updateC(Img, KB1, KB2, M); 32 | 33 | KONE_Img = Img.^2.*KONE; 34 | u = updateLSF(Img,u, C, N_class, KONE_Img, KB1, KB2, mu, nu, timestep, epsilon, Iter); 35 | 36 | b =updateB(Img, C, M, Ksigma); 37 | 38 | 39 | % 40 | function u = updateLSF(Img,u, C, N_class, KONE_Img, KB1, KB2, mu, nu, timestep, epsilon, Iter) 41 | u(:,:,1)=NeumannBoundCond(u(:,:,1)); 42 | Curv(:,:,1)=curvature_central(u(:,:,1)); 43 | H1 = Heaviside(u(:,:,1),epsilon ); 44 | Delta(:,:,1) = Dirac(u(:,:,1),epsilon); 45 | 46 | u(:,:,2)=NeumannBoundCond(u(:,:,2)); 47 | Curv(:,:,2)=curvature_central(u(:,:,2)); 48 | H2 = Heaviside(u(:,:,2),epsilon ); 49 | Delta(:,:,2) = Dirac(u(:,:,2),epsilon); 50 | 51 | e=zeros([size(Img),N_class]); 52 | for kk=1:N_class 53 | e(:,:,kk) = KONE_Img - 2*Img.*C(kk).*KB1 + C(kk)^2*KB2; 54 | end 55 | 56 | A1 = - Delta(:,:,1).*(e(:,:,1).*H2 + e(:,:,2).*(1-H2) - e(:,:,3)); 57 | P1=mu*(4*del2(u(:,:,1))-Curv(:,:,1)); 58 | L1=nu.*Delta(:,:,1).*Curv(:,:,1); 59 | u(:,:,1) = u(:,:,1)+timestep*(L1+P1+A1); % update u1 60 | 61 | 62 | A2 = - Delta(:,:,2).*H1.*(e(:,:,1)-e(:,:,2)); 63 | P2=mu*(4*del2(u(:,:,2))-Curv(:,:,2)); 64 | L2=nu.*Delta(:,:,2).*Curv(:,:,2); 65 | u(:,:,2) = u(:,:,2)+timestep*(L2+P2+A2); % update u2 66 | 67 | % 68 | 69 | function C=updateC(Img, Kb1, Kb2, M) 70 | 71 | N_class = size(M,3); 72 | for kk=1:N_class 73 | N2 = Kb1.*Img.*M(:,:,kk); 74 | D2 = Kb2.*M(:,:,kk); 75 | sN2 = sum(N2(:)); 76 | sD2 = sum(D2(:)); 77 | C(kk)=sN2/(sD2+(sD2==0)); 78 | end 79 | 80 | %%%%%%%%%%%%%%%%% 81 | 82 | function b=updateB(Img, C, M, Ksigma) 83 | PC1=zeros(size(Img)); 84 | PC2=PC1; 85 | N_class=size(M,3); 86 | for kk=1:N_class 87 | PC1=PC1+C(kk)*M(:,:,kk); 88 | PC2=PC2+C(kk)^2*M(:,:,kk); 89 | end 90 | KNm1 = conv2(PC1.*Img,Ksigma,'same'); 91 | KDn1 = conv2(PC2,Ksigma,'same'); 92 | 93 | b = KNm1./KDn1; 94 | 95 | 96 | 97 | 98 | function h = Heaviside(x,epsilon) % function (11) 99 | h=0.5*(1+(2/pi)*atan(x./epsilon)); 100 | 101 | function f = Dirac(x, epsilon) % function (12) 102 | f=(epsilon/pi)./(epsilon^2.+x.^2); 103 | 104 | function K_curvature = curvature_central(u); 105 | [ux,uy] = gradient(u); 106 | normDu = sqrt(ux.^2+uy.^2+1e-20); 107 | Nx = ux./normDu; 108 | Ny = uy./normDu; 109 | [nxx,junk] = gradient(Nx); 110 | [junk,nyy] = gradient(Ny); 111 | K_curvature = nxx+nyy; 112 | 113 | function g = NeumannBoundCond(f) 114 | % Make a function satisfy Neumann boundary condition 115 | [nrow,ncol] = size(f); 116 | g = f; 117 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 118 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 119 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /Bias Correction(Li)/myBrain_axial.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Bias Correction(Li)/myBrain_axial.bmp -------------------------------------------------------------------------------- /Bias Correction(Li)/normalize01.m: -------------------------------------------------------------------------------- 1 | function f=normalize01(f); 2 | % Normalize to the range of [0,1] 3 | 4 | fmin = min(f(:)); 5 | fmax = max(f(:)); 6 | f = (f-fmin)/(fmax-fmin); % Normalize f to the range [0,1] -------------------------------------------------------------------------------- /CV Model(Li)/BoundMirrorEnsure.m: -------------------------------------------------------------------------------- 1 | function B = BoundMirrorEnsure(A) 2 | 3 | [m,n] = size(A); 4 | 5 | if (m<3 | n<3) 6 | error('either the number of rows or columns is smaller than 3'); 7 | end 8 | 9 | yi = 2:m-1; 10 | xi = 2:n-1; 11 | B = A; 12 | B([1 m],[1 n]) = B([3 m-2],[3 n-2]); % mirror corners 13 | B([1 m],xi) = B([3 m-2],xi); % mirror left and right boundary 14 | B(yi,[1 n]) = B(yi,[3 n-2]); % mirror top and bottom boundary 15 | -------------------------------------------------------------------------------- /CV Model(Li)/BoundMirrorExpand.m: -------------------------------------------------------------------------------- 1 | function B = BoundMirrorExpand(A) 2 | 3 | [m,n] = size(A); 4 | yi = 2:m+1; 5 | xi = 2:n+1; 6 | B = zeros(m+2,n+2); 7 | B(yi,xi) = A; 8 | B([1 m+2],[1 n+2]) = B([3 m],[3 n]); % mirror corners 9 | B([1 m+2],xi) = B([3 m],xi); % mirror left and right boundary 10 | B(yi,[1 n+2]) = B(yi,[3 n]); % mirror top and bottom boundary 11 | -------------------------------------------------------------------------------- /CV Model(Li)/BoundMirrorShrink.m: -------------------------------------------------------------------------------- 1 | function B = BoundMirrorShrink(A) 2 | [m,n] = size(A); 3 | yi = 2:m-1; 4 | xi = 2:n-1; 5 | B = A(yi,xi); 6 | 7 | -------------------------------------------------------------------------------- /CV Model(Li)/CV/CURVATURE.m: -------------------------------------------------------------------------------- 1 | function K = CURVATURE(f,diff_scheme) 2 | % CURVATURE computes curvature 3 | % Author: Chunming Li, all rights reserved. 4 | % Email: li_chunming@hotmail.com 5 | % URL: http://www.engr.uconn.edu/~cmli/ 6 | 7 | epsilon=1e-10; 8 | 9 | if strcmp(diff_scheme, 'fcb') 10 | [fx,fy]=gradient(f); % central difference 11 | fx_f = Dx_forward(f); % forward difference 12 | ax = fx_f./sqrt(fx_f.^2+ fy.^2+epsilon); 13 | axx = Dx_backward(ax); % backward difference 14 | fy_f = Dy_forward(f); 15 | ay = fy_f./sqrt(fx.^2 + fy_f.^2 + epsilon); 16 | ayy = Dy_backward(ay); 17 | K = axx + ayy; 18 | 19 | elseif strcmp(diff_scheme, 'fb') % forward difference followed by a backward difference 20 | 21 | fx_f = Dx_forward(f); 22 | fy_f = Dy_forward(f); 23 | ax = fx_f./sqrt(fx_f.^2+ fy_f.^2+epsilon); 24 | ay = fy_f./sqrt(fx_f.^2 + fy_f.^2 + epsilon); 25 | axx = Dx_backward(ax); 26 | ayy = Dy_backward(ay); 27 | K = axx + ayy; 28 | elseif strcmp(diff_scheme, 'bf') % forward difference followed by a backward difference 29 | 30 | fx_f = Dx_backward(f); 31 | fy_f = Dy_backward(f); 32 | ax = fx_f./sqrt(fx_f.^2+ fy_f.^2+epsilon); 33 | ay = fy_f./sqrt(fx_f.^2 + fy_f.^2 + epsilon); 34 | axx = Dx_forward(ax); 35 | ayy = Dy_forward(ay); 36 | K = axx + ayy; 37 | elseif strcmp(diff_scheme, 'cc') % central difference followed by a central difference 38 | [fx, fy]= gradient(f); % central difference 39 | ax = fx./sqrt(fx.^2+ fy.^2+epsilon); 40 | ay = fy./sqrt(fx.^2 + fy.^2 + epsilon); 41 | [axx, axy] = gradient(ax); % central difference 42 | [ayx, ayy] = gradient(ay); 43 | K = axx + ayy; 44 | else 45 | disp('Wrong difference scheme: CURVATURE.m'); 46 | return; 47 | end 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /CV Model(Li)/CV/Demo_CV.m: -------------------------------------------------------------------------------- 1 | % Matlad code implementing Chan-Vese model in the paper 'Active Contours Without Edges' 2 | % Author: Chunming Li, all right reserved 3 | % email: li_chunming@hotmail.com 4 | % URL: http://www.engr.uconn.edu/~cmli 5 | 6 | clear all; 7 | close all; 8 | Img=imread('three.bmp'); 9 | % Img=imread('vessel3.bmp'); % Note: this an example of images with intensity inhomogeneity. 10 | % CV model does not work for this image. 11 | Img=double(Img(:,:,1)); 12 | 13 | % get the size 14 | [nrow,ncol] =size(Img); 15 | 16 | ic=nrow/2; 17 | jc=ncol/2; 18 | r=20; 19 | initialLSF = sdf2circle(nrow,ncol,ic,jc,r); 20 | u=initialLSF; 21 | 22 | 23 | numIter = 150; 24 | timestep = 0.1; 25 | lambda_1=1; 26 | lambda_2=1; 27 | h = 1; 28 | epsilon=1; 29 | nu = 0.001*255*255; % tune this parameter for different images 30 | 31 | figure; 32 | imagesc(Img,[0 255]);colormap(gray) 33 | hold on; 34 | contour(u,[0 0],'r'); 35 | 36 | 37 | % start level set evolution 38 | for k=1:numIter 39 | u=EVOL_CV(Img, u, nu, lambda_1, lambda_2, timestep, epsilon, 1); % update level set function 40 | if mod(k,10)==0 41 | pause(.1); 42 | imagesc(Img,[0 255]);colormap(gray) 43 | hold on; 44 | contour(u,[0 0],'r'); 45 | hold off; 46 | end 47 | end; 48 | -------------------------------------------------------------------------------- /CV Model(Li)/CV/EVOL_CV.m: -------------------------------------------------------------------------------- 1 | function phi = EVOL_CV(I, phi0, nu, lambda_1, lambda_2, timestep, epsilon, numIter); 2 | % This function updates the level set function according to the CV model 3 | % input: 4 | % I: input image 5 | % phi0: level set function to be updated 6 | % mu: weight for length term 7 | % nu: weight for area term, default value 0 8 | % lambda_1: weight for c1 fitting term 9 | % lambda_2: weight for c2 fitting term 10 | % muP: weight for level set regularization term 11 | % timestep: time step 12 | % epsilon: parameter for computing smooth Heaviside and dirac function 13 | % numIter: number of iterations 14 | % output: 15 | % phi: updated level set function 16 | % 17 | % created on 04/26/2004 18 | % Author: Chunming Li, all right reserved 19 | % email: li_chunming@hotmail.com 20 | % URL: http://www.engr.uconn.edu/~cmli/research/ 21 | 22 | phi=phi0; 23 | for k=1:numIter 24 | phi=NeumannBoundCond(phi); 25 | diracPhi=Delta(phi,epsilon); 26 | Hphi=Heaviside(phi, epsilon); 27 | kappa = CURVATURE(phi,'cc'); 28 | [C1,C2]=binaryfit(I,Hphi); 29 | % updating the phi function 30 | phi=phi+timestep*(diracPhi.*(nu-lambda_1*(I-C1).^2+lambda_2*(I-C2).^2)); 31 | end 32 | 33 | 34 | function H = Heaviside(phi,epsilon) 35 | H = 0.5*(1+ (2/pi)*atan(phi./epsilon)); 36 | 37 | function Delta_h = Delta(phi, epsilon) 38 | Delta_h=(epsilon/pi)./(epsilon^2+ phi.^2); 39 | 40 | function g = NeumannBoundCond(f) 41 | % Make a function satisfy Neumann boundary condition 42 | [nrow,ncol] = size(f); 43 | g = f; 44 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 45 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 46 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /CV Model(Li)/CV/binaryfit.m: -------------------------------------------------------------------------------- 1 | function [C1,C2]= binaryfit(Img,H_phi) 2 | % [C1,C2]= binaryfit(phi,U,epsilon) computes c1 c2 for optimal binary fitting 3 | % input: 4 | % Img: input image 5 | % phi: level set function 6 | % epsilon: parameter for computing smooth Heaviside and dirac function 7 | % output: 8 | % C1: a constant to fit the image U in the region phi>0 9 | % C2: a constant to fit the image U in the region phi<0 10 | % 11 | % Author: Chunming Li, all right reserved 12 | % email: li_chunming@hotmail.com 13 | % URL: http://www.engr.uconn.edu/~cmli/research/ 14 | 15 | a= H_phi.*Img; 16 | numer_1=sum(a(:)); 17 | denom_1=sum(H_phi(:)); 18 | C1 = numer_1/denom_1; 19 | 20 | b=(1-H_phi).*Img; 21 | numer_2=sum(b(:)); 22 | c=1-H_phi; 23 | denom_2=sum(c(:)); 24 | C2 = numer_2/denom_2; 25 | -------------------------------------------------------------------------------- /CV Model(Li)/CV/sdf2circle.m: -------------------------------------------------------------------------------- 1 | function f = sdf2circle(nrow,ncol, ic,jc,r) 2 | % sdf2circle(nrow,ncol, ic,jc,r) computes the signed distance to a circle 3 | % input: 4 | % nrow: number of rows 5 | % ncol: number of columns 6 | % (ic,jc): center of the circle 7 | % r: radius of the circle 8 | % output: 9 | % f: signed distance to the circle 10 | % 11 | % created on 04/26/2004 12 | % author: Chunming Li 13 | % email: li_chunming@hotmail.com 14 | % Copyright (c) 2004-2006 by Chunming Li 15 | 16 | 17 | [X,Y] = meshgrid(1:ncol, 1:nrow); 18 | 19 | f = sqrt((X-jc).^2+(Y-ic).^2)-r; 20 | 21 | %f=sdf2circle(100,50,51,25,10);figure;imagesc(f) -------------------------------------------------------------------------------- /CV Model(Li)/CV/three.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/CV/three.bmp -------------------------------------------------------------------------------- /CV Model(Li)/CV/twocells.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/CV/twocells.bmp -------------------------------------------------------------------------------- /CV Model(Li)/CV/vessel3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/CV/vessel3.bmp -------------------------------------------------------------------------------- /CV Model(Li)/Delta.m: -------------------------------------------------------------------------------- 1 | function Delta_h = Delta(phi, epsilon) 2 | % Delta(phi, epsilon) compute the smooth Dirac function 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | 9 | Delta_h=(epsilon/pi)./(epsilon^2+ phi.^2); -------------------------------------------------------------------------------- /CV Model(Li)/Heaviside.m: -------------------------------------------------------------------------------- 1 | function H = Heaviside(phi,epsilon) 2 | % Heaviside(phi,epsilon) compute the smooth Heaviside function 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | H = 0.5*(1+ (2/pi)*atan(phi./epsilon)); -------------------------------------------------------------------------------- /CV Model(Li)/backward_gradient.m: -------------------------------------------------------------------------------- 1 | function [bdy,bdx]=backward_gradient(f); 2 | % function [bdx,bdy]=backward_gradient(f); 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | [nr,nc]=size(f); 9 | bdx=zeros(nr,nc); 10 | bdy=zeros(nr,nc); 11 | 12 | bdx(2:nr,:)=f(2:nr,:)-f(1:nr-1,:); 13 | bdy(:,2:nc)=f(:,2:nc)-f(:,1:nc-1); -------------------------------------------------------------------------------- /CV Model(Li)/binaryfit.m: -------------------------------------------------------------------------------- 1 | function [C1,C2]= binaryfit(phi,U,epsilon) 2 | % [C1,C2]= binaryfit(phi,U,epsilon) computes c1 c2 for optimal binary fitting 3 | % input: 4 | % U: input image 5 | % phi: level set function 6 | % epsilon: parameter for computing smooth Heaviside and dirac function 7 | % output: 8 | % C1: a constant to fit the image U in the region phi>0 9 | % C2: a constant to fit the image U in the region phi<0 10 | % 11 | % created on 04/26/2004 12 | % author: Chunming Li 13 | % email: li_chunming@hotmail.com 14 | % Copyright (c) 2004-2006 by Chunming Li 15 | 16 | H = Heaviside(phi,epsilon); %compute the Heaveside function values 17 | 18 | 19 | a= H.*U; 20 | numer_1=sum(a(:)); 21 | denom_1=sum(H(:)); 22 | C1 = numer_1/denom_1; 23 | 24 | b=(1-H).*U; 25 | numer_2=sum(b(:)); 26 | c=1-H; 27 | denom_2=sum(c(:)); 28 | C2 = numer_2/denom_2; 29 | -------------------------------------------------------------------------------- /CV Model(Li)/curvature.m: -------------------------------------------------------------------------------- 1 | function K=curvature(f); 2 | % K=curvature(f); 3 | % K=div(Df/|Df|) 4 | % =(fxx*fy^2+fyy*fx^2-2*fx*fy*fxy)/(fx^2+fy^2)^(3/2) 5 | % created on 04/26/2004 6 | % author: Chunming Li 7 | % email: li_chunming@hotmail.com 8 | % Copyright (c) 2004-2006 by Chunming Li 9 | 10 | 11 | 12 | [f_fx,f_fy]=forward_gradient(f); 13 | [f_bx,f_by]=backward_gradient(f); 14 | 15 | mag1=sqrt(f_fx.^2+f_fy.^2+1e-10); 16 | n1x=f_fx./mag1; 17 | n1y=f_fy./mag1; 18 | 19 | mag2=sqrt(f_bx.^2+f_fy.^2+1e-10); 20 | n2x=f_bx./mag2; 21 | n2y=f_fy./mag2; 22 | 23 | mag3=sqrt(f_fx.^2+f_by.^2+1e-10); 24 | n3x=f_fx./mag3; 25 | n3y=f_by./mag3; 26 | 27 | mag4=sqrt(f_bx.^2+f_by.^2+1e-10); 28 | n4x=f_bx./mag4; 29 | n4y=f_by./mag4; 30 | 31 | nx=n1x+n2x+n3x+n4x; 32 | ny=n1y+n2y+n3y+n4y; 33 | 34 | magn=sqrt(nx.^2+ny.^2); 35 | nx=nx./(magn+1e-10); 36 | ny=ny./(magn+1e-10); 37 | 38 | [nxx,nxy]=gradient(nx); 39 | [nyx,nyy]=gradient(ny); 40 | 41 | K=nxx+nyy; -------------------------------------------------------------------------------- /CV Model(Li)/evolution_cv.m: -------------------------------------------------------------------------------- 1 | function phi = EVOLUTION_CV(I, phi0, mu, nu, lambda_1, lambda_2, delta_t, epsilon, numIter); 2 | % evolution_withoutedge(I, phi0, mu, nu, lambda_1, lambda_2, delta_t, delta_h, epsilon, numIter); 3 | % input: 4 | % I: input image 5 | % phi0: level set function to be updated 6 | % mu: weight for length term 7 | % nu: weight for area term, default value 0 8 | % lambda_1: weight for c1 fitting term 9 | % lambda_2: weight for c2 fitting term 10 | % delta_t: time step 11 | % epsilon: parameter for computing smooth Heaviside and dirac function 12 | % numIter: number of iterations 13 | % output: 14 | % phi: updated level set function 15 | % 16 | % created on 04/26/2004 17 | % author: Chunming Li 18 | % email: li_chunming@hotmail.com 19 | % Copyright (c) 2004-2006 by Chunming Li 20 | 21 | 22 | I=BoundMirrorExpand(I); 23 | phi=BoundMirrorExpand(phi0); 24 | 25 | for k=1:numIter 26 | phi=BoundMirrorEnsure(phi); 27 | delta_h=Delta(phi,epsilon); 28 | Curv = curvature(phi); 29 | [C1,C2]=binaryfit(phi,I,epsilon); 30 | % updating the phi function 31 | phi=phi+delta_t*delta_h.*(mu*Curv-nu-lambda_1*(I-C1).^2+lambda_2*(I-C2).^2); 32 | end 33 | phi=BoundMirrorShrink(phi); -------------------------------------------------------------------------------- /CV Model(Li)/forward_gradient.m: -------------------------------------------------------------------------------- 1 | function [fdy,fdx]=forward_gradient(f); 2 | % function [fdx,fdy]=forward_gradient(f); 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | [nr,nc]=size(f); 9 | fdx=zeros(nr,nc); 10 | fdy=zeros(nr,nc); 11 | 12 | a=f(2:nr,:)-f(1:nr-1,:); 13 | fdx(1:nr-1,:)=a; 14 | b=f(:,2:nc)-f(:,1:nc-1); 15 | fdy(:,1:nc-1)=b; 16 | -------------------------------------------------------------------------------- /CV Model(Li)/get_contour.m: -------------------------------------------------------------------------------- 1 | %/* this function computes the phi required initially */ 2 | function [xcontour, ycontour] = get_phi(I, nrow, ncol,margin) 3 | % I is the image matrix 4 | % nrow is the no of rows 5 | % ncol is the no of columns 6 | 7 | 8 | count=1; 9 | x=margin; 10 | for y=margin:nrow-margin+1, 11 | xcontour(count) = x; 12 | ycontour(count) = y; 13 | count=count+1; 14 | end; 15 | y=nrow-margin+1; 16 | for x=margin+1:ncol-margin+1, 17 | xcontour(count) = x; 18 | ycontour(count) = y; 19 | count=count+1; 20 | end; 21 | 22 | x=ncol-margin+1; 23 | for y=nrow-margin:-1:margin, 24 | xcontour(count) = x; 25 | ycontour(count) = y; 26 | count=count+1; 27 | end; 28 | 29 | y=margin; 30 | for x=ncol-margin:-1:margin+1, 31 | xcontour(count) = x; 32 | ycontour(count) = y; 33 | count=count+1; 34 | end; 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /CV Model(Li)/plotLevelSet.m: -------------------------------------------------------------------------------- 1 | function [c,h]=plotLevelSet(u,zLevel, style) 2 | % plotLevelSet(u,zLevel, style) plot the level contour of function u at 3 | % the zLevel. 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | % hold on; 9 | [c,h] = contour(u,[zLevel zLevel],style); 10 | % hold off; -------------------------------------------------------------------------------- /CV Model(Li)/sdf2circle.m: -------------------------------------------------------------------------------- 1 | function f = sdf2circle(nrow,ncol, ic,jc,r) 2 | % sdf2circle(nrow,ncol, ic,jc,r) computes the signed distance to a circle 3 | % input: 4 | % nrow: number of rows 5 | % ncol: number of columns 6 | % (ic,jc): center of the circle 7 | % r: radius of the circle 8 | % output: 9 | % f: signed distance to the circle 10 | % 11 | % created on 04/26/2004 12 | % author: Chunming Li 13 | % email: li_chunming@hotmail.com 14 | % Copyright (c) 2004-2006 by Chunming Li 15 | 16 | 17 | [X,Y] = meshgrid(1:ncol, 1:nrow); 18 | 19 | f = sqrt((X-jc).^2+(Y-ic).^2)-r; 20 | 21 | %f=sdf2circle(100,50,51,25,10);figure;imagesc(f) -------------------------------------------------------------------------------- /CV Model(Li)/signed_distance.m: -------------------------------------------------------------------------------- 1 | %/* this function computes the signed distance as initial level set function */ 2 | function u = signed_distance(I,xcontour, ycontour,margin) 3 | % I is the image matrix 4 | % nrow is the no of rows 5 | % ncol is the no of columns 6 | 7 | [nrow, ncol] = size(I); 8 | [temp, contsize] = size(xcontour); 9 | 10 | Mark = zeros(nrow, ncol); 11 | 12 | for y=1:nrow, 13 | for x=1:ncol 14 | if (x > ncol-margin+1) | (x < margin) | (y < margin) | (y > nrow-margin+1) 15 | Mark(y,x) = -1; 16 | end; 17 | end; 18 | end; 19 | 20 | for y = 1:nrow, 21 | for x =1: ncol, 22 | u(y,x) = sqrt(min((x-xcontour).^2+(y-ycontour).^2)); 23 | if Mark(y,x) == -1 24 | u(y,x) = -u(y,x); 25 | end; 26 | end; 27 | end; 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /CV Model(Li)/test.asv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/test.asv -------------------------------------------------------------------------------- /CV Model(Li)/test.m: -------------------------------------------------------------------------------- 1 | % Matlad code implementing Chan-Vese model in the paper 'Active Contours Without Edges' 2 | % This method works well for bimodal images, for example the image 'three.bmp' 3 | % created on 04/26/2004 4 | % author: Chunming Li 5 | % email: li_chunming@hotmail.com 6 | % Copyright (c) 2004-2006 by Chunming Li 7 | 8 | clear; 9 | 10 | %Img=imread('three.bmp'); % example that CV model works well 11 | Img=imread('vessel.bmp'); % example that CV model does NOT work well 12 | %Img=imread('twoCells.bmp'); % example that CV model does NOT work well 13 | %Img=imread('noisyNonUniform.bmp'); 14 | 15 | U=Img(:,:,1); 16 | 17 | % get the size 18 | [nrow,ncol] =size(U); 19 | 20 | ic=nrow/2; 21 | jc=ncol/2; 22 | r=30; 23 | phi_0 = sdf2circle(nrow,ncol,ic,jc,r); 24 | 25 | 26 | delta_t = 0.1; 27 | lambda_1=1; 28 | lambda_2=1; 29 | nu=0; 30 | h = 1; 31 | epsilon=1; 32 | mu = 0.01*255*255; 33 | 34 | I=double(U); 35 | % iteration should begin from here 36 | phi=phi_0; 37 | figure; 38 | imagesc(uint8(I));colormap(gray) 39 | hold on; 40 | plotLevelSet(phi,0,'r'); 41 | 42 | numIter = 1; 43 | for k=1:400, 44 | phi=evolution_cv(I, phi, mu, nu, lambda_1, lambda_2, delta_t, epsilon, numIter); % update level set function 45 | if mod(k,10)==0 46 | pause(.5); 47 | imagesc(uint8(I));colormap(gray) 48 | hold on; 49 | plotLevelSet(phi,0,'r'); 50 | end 51 | end; 52 | -------------------------------------------------------------------------------- /CV Model(Li)/three.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/three.bmp -------------------------------------------------------------------------------- /CV Model(Li)/twocells.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/twocells.bmp -------------------------------------------------------------------------------- /CV Model(Li)/vessel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/CV Model(Li)/vessel.bmp -------------------------------------------------------------------------------- /DRLSE(Li)/DRLSE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/DRLSE(Li)/DRLSE.pdf -------------------------------------------------------------------------------- /DRLSE(Li)/demo_1.m: -------------------------------------------------------------------------------- 1 | % This Matlab code demonstrates an edge-based active contour model as an application of 2 | % the Distance Regularized Level Set Evolution (DRLSE) formulation in the following paper: 3 | % 4 | % C. Li, C. Xu, C. Gui, M. D. Fox, "Distance Regularized Level Set Evolution and Its Application to Image Segmentation", 5 | % IEEE Trans. Image Processing, vol. 19 (12), pp. 3243-3254, 2010. 6 | % 7 | % Author: Chunming Li, all rights reserved 8 | % E-mail: lchunming@gmail.com 9 | % li_chunming@hotmail.com 10 | % URL: http://www.engr.uconn.edu/~cmli/ 11 | 12 | clear all; 13 | close all; 14 | 15 | Img=imread('gourd.bmp'); 16 | Img=double(Img(:,:,1)); 17 | %% parameter setting 18 | timestep=1; % time step 19 | mu=0.2/timestep; % coefficient of the distance regularization term R(phi) 20 | iter_inner=5; 21 | iter_outer=20; 22 | lambda=5; % coefficient of the weighted length term L(phi) 23 | alfa=-3; % coefficient of the weighted area term A(phi) 24 | epsilon=1.5; % papramater that specifies the width of the DiracDelta function 25 | 26 | sigma=.8; % scale parameter in Gaussian kernel 27 | G=fspecial('gaussian',15,sigma); % Caussian kernel 28 | Img_smooth=conv2(Img,G,'same'); % smooth image by Gaussiin convolution 29 | [Ix,Iy]=gradient(Img_smooth); 30 | f=Ix.^2+Iy.^2; 31 | g=1./(1+f); % edge indicator function. 32 | 33 | % initialize LSF as binary step function 34 | c0=2; 35 | initialLSF = c0*ones(size(Img)); 36 | % generate the initial region R0 as two rectangles 37 | initialLSF(25:35,20:25)=-c0; 38 | initialLSF(25:35,40:50)=-c0; 39 | phi=initialLSF; 40 | 41 | figure(1); 42 | mesh(-phi); % for a better view, the LSF is displayed upside down 43 | hold on; contour(phi, [0,0], 'r','LineWidth',2); 44 | title('Initial level set function'); 45 | view([-80 35]); 46 | 47 | figure(2); 48 | imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on; contour(phi, [0,0], 'r'); 49 | title('Initial zero level contour'); 50 | pause(0.5); 51 | 52 | potential=2; 53 | if potential ==1 54 | potentialFunction = 'single-well'; % use single well potential p1(s)=0.5*(s-1)^2, which is good for region-based model 55 | elseif potential == 2 56 | potentialFunction = 'double-well'; % use double-well potential in Eq. (16), which is good for both edge and region based models 57 | else 58 | potentialFunction = 'double-well'; % default choice of potential function 59 | end 60 | 61 | % start level set evolution 62 | for n=1:iter_outer 63 | phi = drlse_edge(phi, g, lambda, mu, alfa, epsilon, timestep, iter_inner, potentialFunction); 64 | if mod(n,2)==0 65 | figure(2); 66 | imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on; contour(phi, [0,0], 'r'); 67 | end 68 | end 69 | 70 | % refine the zero level contour by further level set evolution with alfa=0 71 | alfa=0; 72 | iter_refine = 10; 73 | phi = drlse_edge(phi, g, lambda, mu, alfa, epsilon, timestep, iter_inner, potentialFunction); 74 | 75 | finalLSF=phi; 76 | figure(2); 77 | imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on; contour(phi, [0,0], 'r'); 78 | hold on; contour(phi, [0,0], 'r'); 79 | str=['Final zero level contour, ', num2str(iter_outer*iter_inner+iter_refine), ' iterations']; 80 | title(str); 81 | 82 | figure; 83 | mesh(-finalLSF); % for a better view, the LSF is displayed upside down 84 | hold on; contour(phi, [0,0], 'r','LineWidth',2); 85 | view([-80 35]); 86 | str=['Final level set function, ', num2str(iter_outer*iter_inner+iter_refine), ' iterations']; 87 | title(str); 88 | axis on; 89 | [nrow, ncol]=size(Img); 90 | axis([1 ncol 1 nrow -5 5]); 91 | set(gca,'ZTick',[-3:1:3]); 92 | set(gca,'FontSize',14) 93 | 94 | -------------------------------------------------------------------------------- /DRLSE(Li)/demo_2.m: -------------------------------------------------------------------------------- 1 | % This Matlab code demonstrates an edge-based active contour model as an application of 2 | % the Distance Regularized Level Set Evolution (DRLSE) formulation in the following paper: 3 | % 4 | % C. Li, C. Xu, C. Gui, M. D. Fox, "Distance Regularized Level Set Evolution and Its Application to Image Segmentation", 5 | % IEEE Trans. Image Processing, vol. 19 (12), pp. 3243-3254, 2010. 6 | % 7 | % Author: Chunming Li, all rights reserved 8 | % E-mail: lchunming@gmail.com 9 | % li_chunming@hotmail.com 10 | % URL: http://www.engr.uconn.edu/~cmli/ 11 | 12 | clear all; 13 | close all; 14 | 15 | Img = imread('twocells.bmp'); % real miscroscope image of cells 16 | Img=double(Img(:,:,1)); 17 | %% parameter setting 18 | timestep=5; % time step 19 | mu=0.2/timestep; % coefficient of the distance regularization term R(phi) 20 | iter_inner=5; 21 | iter_outer=40; 22 | lambda=5; % coefficient of the weighted length term L(phi) 23 | alfa=1.5; % coefficient of the weighted area term A(phi) 24 | epsilon=1.5; % papramater that specifies the width of the DiracDelta function 25 | 26 | sigma=1.5; % scale parameter in Gaussian kernel 27 | G=fspecial('gaussian',15,sigma); 28 | Img_smooth=conv2(Img,G,'same'); % smooth image by Gaussiin convolution 29 | [Ix,Iy]=gradient(Img_smooth); 30 | f=Ix.^2+Iy.^2; 31 | g=1./(1+f); % edge indicator function. 32 | 33 | % initialize LSF as binary step function 34 | c0=2; 35 | initialLSF=c0*ones(size(Img)); 36 | % generate the initial region R0 as a rectangle 37 | initialLSF(10:55, 10:75)=-c0; 38 | phi=initialLSF; 39 | 40 | figure(1); 41 | mesh(-phi); % for a better view, the LSF is displayed upside down 42 | hold on; contour(phi, [0,0], 'r','LineWidth',2); 43 | title('Initial level set function'); 44 | view([-80 35]); 45 | 46 | figure(2); 47 | imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on; contour(phi, [0,0], 'r'); 48 | title('Initial zero level contour'); 49 | pause(0.5); 50 | 51 | potential=2; 52 | if potential ==1 53 | potentialFunction = 'single-well'; % use single well potential p1(s)=0.5*(s-1)^2, which is good for region-based model 54 | elseif potential == 2 55 | potentialFunction = 'double-well'; % use double-well potential in Eq. (16), which is good for both edge and region based models 56 | else 57 | potentialFunction = 'double-well'; % default choice of potential function 58 | end 59 | 60 | 61 | % start level set evolution 62 | for n=1:iter_outer 63 | phi = drlse_edge(phi, g, lambda, mu, alfa, epsilon, timestep, iter_inner, potentialFunction); 64 | if mod(n,2)==0 65 | figure(2); 66 | imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on; contour(phi, [0,0], 'r'); 67 | end 68 | end 69 | 70 | % refine the zero level contour by further level set evolution with alfa=0 71 | alfa=0; 72 | iter_refine = 10; 73 | phi = drlse_edge(phi, g, lambda, mu, alfa, epsilon, timestep, iter_inner, potentialFunction); 74 | 75 | finalLSF=phi; 76 | figure(2); 77 | imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on; contour(phi, [0,0], 'r'); 78 | hold on; contour(phi, [0,0], 'r'); 79 | str=['Final zero level contour, ', num2str(iter_outer*iter_inner+iter_refine), ' iterations']; 80 | title(str); 81 | 82 | pause(1); 83 | figure; 84 | mesh(-finalLSF); % for a better view, the LSF is displayed upside down 85 | hold on; contour(phi, [0,0], 'r','LineWidth',2); 86 | str=['Final level set function, ', num2str(iter_outer*iter_inner+iter_refine), ' iterations']; 87 | title(str); 88 | axis on; 89 | 90 | 91 | -------------------------------------------------------------------------------- /DRLSE(Li)/drlse_edge.m: -------------------------------------------------------------------------------- 1 | function phi = drlse_edge(phi_0, g, lambda,mu, alfa, epsilon, timestep, iter, potentialFunction) 2 | % This Matlab code implements an edge-based active contour model as an 3 | % application of the Distance Regularized Level Set Evolution (DRLSE) formulation in Li et al's paper: 4 | % 5 | % C. Li, C. Xu, C. Gui, M. D. Fox, "Distance Regularized Level Set Evolution and Its Application to Image Segmentation", 6 | % IEEE Trans. Image Processing, vol. 19 (12), pp.3243-3254, 2010. 7 | % 8 | % Input: 9 | % phi_0: level set function to be updated by level set evolution 10 | % g: edge indicator function 11 | % mu: weight of distance regularization term 12 | % timestep: time step 13 | % lambda: weight of the weighted length term 14 | % alfa: weight of the weighted area term 15 | % epsilon: width of Dirac Delta function 16 | % iter: number of iterations 17 | % potentialFunction: choice of potential function in distance regularization term. 18 | % As mentioned in the above paper, two choices are provided: potentialFunction='single-well' or 19 | % potentialFunction='double-well', which correspond to the potential functions p1 (single-well) 20 | % and p2 (double-well), respectively.% 21 | % Output: 22 | % phi: updated level set function after level set evolution 23 | % 24 | % Author: Chunming Li, all rights reserved 25 | % E-mail: lchunming@gmail.com 26 | % li_chunming@hotmail.com 27 | % URL: http://www.engr.uconn.edu/~cmli/ 28 | 29 | phi=phi_0; 30 | [vx, vy]=gradient(g); 31 | for k=1:iter 32 | phi=NeumannBoundCond(phi); 33 | [phi_x,phi_y]=gradient(phi); 34 | s=sqrt(phi_x.^2 + phi_y.^2); 35 | smallNumber=1e-10; 36 | Nx=phi_x./(s+smallNumber); % add a small positive number to avoid division by zero 37 | Ny=phi_y./(s+smallNumber); 38 | curvature=div(Nx,Ny); 39 | if strcmp(potentialFunction,'single-well') 40 | distRegTerm = 4*del2(phi)-curvature; % compute distance regularization term in equation (13) with the single-well potential p1. 41 | elseif strcmp(potentialFunction,'double-well'); 42 | distRegTerm=distReg_p2(phi); % compute the distance regularization term in eqaution (13) with the double-well potential p2. 43 | else 44 | disp('Error: Wrong choice of potential function. Please input the string "single-well" or "double-well" in the drlse_edge function.'); 45 | end 46 | diracPhi=Dirac(phi,epsilon); 47 | areaTerm=diracPhi.*g; % balloon/pressure force 48 | edgeTerm=diracPhi.*(vx.*Nx+vy.*Ny) + diracPhi.*g.*curvature; 49 | phi=phi + timestep*(mu*distRegTerm + lambda*edgeTerm + alfa*areaTerm); 50 | end 51 | 52 | 53 | function f = distReg_p2(phi) 54 | % compute the distance regularization term with the double-well potential p2 in eqaution (16) 55 | [phi_x,phi_y]=gradient(phi); 56 | s=sqrt(phi_x.^2 + phi_y.^2); 57 | a=(s>=0) & (s<=1); 58 | b=(s>1); 59 | ps=a.*sin(2*pi*s)/(2*pi)+b.*(s-1); % compute first order derivative of the double-well potential p2 in eqaution (16) 60 | dps=((ps~=0).*ps+(ps==0))./((s~=0).*s+(s==0)); % compute d_p(s)=p'(s)/s in equation (10). As s-->0, we have d_p(s)-->1 according to equation (18) 61 | f = div(dps.*phi_x - phi_x, dps.*phi_y - phi_y) + 4*del2(phi); 62 | 63 | function f = div(nx,ny) 64 | [nxx,junk]=gradient(nx); 65 | [junk,nyy]=gradient(ny); 66 | f=nxx+nyy; 67 | 68 | function f = Dirac(x, sigma) 69 | f=(1/2/sigma)*(1+cos(pi*x/sigma)); 70 | b = (x<=sigma) & (x>=-sigma); 71 | f = f.*b; 72 | 73 | function g = NeumannBoundCond(f) 74 | % Make a function satisfy Neumann boundary condition 75 | [nrow,ncol] = size(f); 76 | g = f; 77 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 78 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 79 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /DRLSE(Li)/gourd.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/DRLSE(Li)/gourd.bmp -------------------------------------------------------------------------------- /DRLSE(Li)/improved-drlse.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/DRLSE(Li)/improved-drlse.m -------------------------------------------------------------------------------- /DRLSE(Li)/twocells.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/DRLSE(Li)/twocells.bmp -------------------------------------------------------------------------------- /DRLSE(Li)/vessel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/DRLSE(Li)/vessel.bmp -------------------------------------------------------------------------------- /GAC/GACmodel/3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/GAC/GACmodel/3.bmp -------------------------------------------------------------------------------- /GAC/GACmodel/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/GAC/GACmodel/Thumbs.db -------------------------------------------------------------------------------- /GAC/GACmodel/calcspeed.m: -------------------------------------------------------------------------------- 1 | function speed = calcspeed( u, g, grad_g_x,grad_g_y,iterations) 2 | % CALCSPEED Calculate the speed for all points 3 | 4 | [I,J]=size(u);% image size 5 | 6 | % fill speed matrix with zeros at first 7 | speed = zeros( I , J ); 8 | 9 | % calculate the central differences 10 | [Dx_central Dy_central] = gradient(u); 11 | 12 | % calculate the forward differences 13 | Dx_minus = u - circshift(u,[0,1]); 14 | Dy_minus = u - circshift(u,[1,0]); 15 | 16 | % calculate the backward differences 17 | Dx_plus = circshift(u,[0,-1])-u; 18 | Dy_plus = circshift(u,[-1,0])-u; 19 | 20 | % calculate the curvature 21 | u_x = Dx_central; 22 | u_y = Dy_central; 23 | u_xx = Dx_plus - Dx_minus; %circshift(u,[0,-1]) + circshift(u,[0,1]) - 2 * u; 24 | u_yy = Dy_plus - Dy_minus; %circshift(u,[-1,0]) + circshift(u,[1,0]) - 2 * u; 25 | u_xy1 = ( circshift(u,[-1,-1]) + circshift(u,[1,1]) ) / 4; 26 | u_xy2 = ( circshift(u,[1,-1]) + circshift(u,[-1,1]) ) / 4; 27 | u_xy = u_xy1 - u_xy2; 28 | K_top = u_xx.* ( u_y.^2 ) - ( 2 * u_x.*u_y.* u_xy ) + u_yy.* ( u_x.^2 ); 29 | 30 | K_bot = u_x.^2 + u_y.^2 ; 31 | K_bot = max(K_bot,0.00001); 32 | F_remainder = K_top ./ K_bot ; 33 | 34 | % estimate the final speed term 35 | grad_g_u = grad_g_x .* Dx_central + grad_g_y .* Dy_central; 36 | speed =g .*( F_remainder + 3 ) + grad_g_u; -------------------------------------------------------------------------------- /GAC/GACmodel/createimage.m: -------------------------------------------------------------------------------- 1 | function newim = createimage( im, u ) 2 | % CREATEIMAGE Return segmented image as 3 channel uint8 image 3 | % CREATEIMAGE( im, u ) Draws the segmented region in red 4 | % overtop of the original image im. The region is determined by 5 | % finding the front points from u 6 | 7 | % copy over pixels to a temporary image and outline pixels of the 8 | % segmented region 9 | tempim = im; 10 | % copy over pixels into red channel 11 | front = isfront( u ); 12 | front = circshift(front,[1,0]); 13 | tempim( find( front ) ) = 255; 14 | newim( :, :, 1 ) = tempim; 15 | tempim( find( front ) ) = 0; 16 | newim( :, :, 2 ) = tempim; 17 | tempim( find( front ) ) = 0; 18 | newim( :, :, 3 ) = tempim; 19 | % convert to uint8 20 | newim = uint8( newim ); 21 | -------------------------------------------------------------------------------- /GAC/GACmodel/init_u.m: -------------------------------------------------------------------------------- 1 | function u = init_u( imsize, center, radius, isinside ) 2 | % init_u Initialize the u funcion 3 | % initializes the zero level level-set 4 | % of the u function by the circle with the given center (x, y) 5 | % and radius. The size of u is given by 'imsize'. 6 | 7 | % grab the requested size of u 8 | m = imsize( 1 ); n = imsize( 2 ); 9 | 10 | % create a zero matrix 11 | u = zeros( imsize ); 12 | 13 | % go over each pixel 14 | for i = 1 : m; 15 | for j = 1 : n; 16 | 17 | % get the sum of squares distance of the pixel from the center 18 | % of the circle 19 | distance = sqrt( sum( ( center - [ i, j ] ).^2 ) ); 20 | 21 | % set u to be the signed distance from the pixel to the 22 | % circle's boundary, where the distance is positive for pixels 23 | % outside the boundary and negative for pixels inside the 24 | % boundary 25 | u( i, j ) = distance - radius; 26 | 27 | % if( isinside == 0 ) 28 | % u( i, j ) = -u( i, j ); 29 | % end 30 | 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /GAC/GACmodel/isfront.m: -------------------------------------------------------------------------------- 1 | function front = isfront(u) 2 | % ISFRONT Determine whether a pixel is a front point 3 | % ISFRONT(u ) return binary matrix whose value at each pixel 4 | % represents whether the corresponding pixel in u is a front 5 | % point or not. 6 | 7 | % grab the size ofu 8 | [ n, m ] = size(u ); 9 | 10 | % create an boolean matrix whose value at each pixel is 0 or 1 11 | % depending on whether that pixel is a front point or not 12 | front = zeros( size(u ) ); 13 | 14 | % A piecewise linear approximation to the front is contructed by 15 | % checking each pixels neighbour. Do not check pixels on border. 16 | for i = 2 : n - 1; 17 | for j = 2 : m - 1; 18 | 19 | % if there is a sign change then we have a front point 20 | maxVal = max( max(u( i:i+1, j:j+1 ) ) ); 21 | minVal = min( min(u( i:i+1, j:j+1 ) ) ); 22 | front( i, j ) = ( ( maxVal > 0 ) & ( minVal < 0 ) ) | u( i, j ) == 0; 23 | 24 | end 25 | end -------------------------------------------------------------------------------- /GAC/GACmodel/levelset.m: -------------------------------------------------------------------------------- 1 | function u = levelset( im, center, radius, d_it, re_init, m_name ) 2 | % Segment the image im using level set method, given 3 | % an initial circle with the arguments: center and 4 | % radius. Then the current curve is displayed every d_it 5 | % iterations and written to disk s with name m_name*.jpg 6 | 7 | 8 | % set constants 9 | delta_t = 0.001; 10 | ITERATIONS = 200000; 11 | 12 | % initialize the u function 13 | u = init_u( size( im ), center, radius, 1 ); 14 | 15 | % calculate the stopping function 16 | g = stopfunction( im,3, 2 ); 17 | 18 | [grad_g_x,grad_g_y]=gradient(g); 19 | 20 | 21 | iterations = 0; 22 | 23 | [I,J]=size(im);% image size 24 | 25 | gauss_filter = fspecial( 'gaussian', 3, 2 ); 26 | 27 | while( iterations < ITERATIONS ) 28 | if( mod( iterations, d_it ) == 0 ) 29 | % display the segmented image every 'd_it' iterations 30 | % display current curve 31 | fprintf( 1, '%d\n', iterations ); 32 | disp( 'Displaying segmented image' ); 33 | segim = createimage( im, u ); 34 | imshow( segim ); drawnow; 35 | 36 | filename = strcat( m_name, sprintf( '%06d', ( iterations / d_it ) + 1 ), '.jpg' ); 37 | imwrite( segim, filename ); 38 | end; 39 | % reinitialization of the embedding function u 40 | if( mod( iterations, re_init ) == 0 ) 41 | u = re_init_u( u ); 42 | end; 43 | % calculate the speed and update u 44 | speed = calcspeed( u, g, grad_g_x, grad_g_y ,iterations ); 45 | 46 | u = u + (delta_t .* speed); 47 | 48 | if sum(sum(abs(delta_t .* speed)))<0.1 49 | break; 50 | end 51 | 52 | iterations = iterations + 1; 53 | end 54 | % iterations -------------------------------------------------------------------------------- /GAC/GACmodel/main.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/GAC/GACmodel/main.m -------------------------------------------------------------------------------- /GAC/GACmodel/re_init_u.m: -------------------------------------------------------------------------------- 1 | function u = re_init_u( u ) 2 | % re-initialize the u funcion 3 | 4 | % get the size of u 5 | [M,N] = size (u); 6 | 7 | [x,y] = find( isfront( u ) ); 8 | L = length ( x ); 9 | for i = 1 : M 10 | for j = 1 : N 11 | min_dist = sqrt(M^2+N^2); 12 | for k= 1 : L 13 | dist = sqrt((i-x(k))^2+(j-y(k))^2) ; 14 | if dist 0 19 | u(i,j) = min_dist; 20 | else 21 | u(i,j) = - min_dist; 22 | end 23 | end 24 | end 25 | 26 | 27 | -------------------------------------------------------------------------------- /GAC/GACmodel/stopfunction.m: -------------------------------------------------------------------------------- 1 | function g = stopfunction( im, n, sigma ) 2 | 3 | % This function calculates the edge-stopping 4 | % function of 'im'. The 'im' is firstly smoothed with a gaussian 5 | % kernal of size 'n' and parameter 'sigma', and then calculate its 6 | % gradeint vector 7 | 8 | % first convolve the image with a gaussian filter 9 | gauss_filter = fspecial( 'gaussian', n, sigma ); 10 | filtered_im = imfilter( im, gauss_filter ); 11 | [ x_grad, y_grad ] = gradient( filtered_im ); 12 | 13 | grad_im = sqrt( ( x_grad.^2 ) + ( y_grad.^2 ) ); 14 | 15 | % normolize the gradient image 16 | max_grad = max( max( grad_im ) ); 17 | min_grad = min( min( grad_im ) ); 18 | grad_im = 100 .* ( grad_im - min_grad ) ./ ( max_grad - min_grad ); 19 | 20 | % Create the edge-stopping function: 21 | g = exp( -abs( grad_im ) ); 22 | %g = 1 ./ (( 1 + abs( grad_im )).^2 ); 23 | 24 | -------------------------------------------------------------------------------- /GAC/GACmodel/vessel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/GAC/GACmodel/vessel.bmp -------------------------------------------------------------------------------- /GAC/Geodesic Active Contours1997IJCV.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/GAC/Geodesic Active Contours1997IJCV.pdf -------------------------------------------------------------------------------- /LBF(Li)/LBF/DemoLBF.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/DemoLBF.m -------------------------------------------------------------------------------- /LBF(Li)/LBF/EVOL_LBF.m: -------------------------------------------------------------------------------- 1 | function u = EVOL_LBF(u0,Img,K,KI,KONE,nu,timestep,mu,lambda1,lambda2,epsilon,numIter) 2 | % u = EVOL_LBF(u0,Img,Ksigma,KI,KONE,nu,timestep,mu,lambda1,lambda2,epsilon,numIter) 3 | 4 | u=u0; 5 | for k1=1:numIter 6 | u=NeumannBoundCond(u); 7 | C=curvature_central(u); % div() 8 | HeavU=Heaviside(u,epsilon); 9 | DiracU=Dirac(u,epsilon); 10 | 11 | [f1,f2]=LBF_LocalBinaryFit(K,Img,KI,KONE,HeavU); 12 | LBF=LBF_dataForce(Img,K,KONE,f1,f2,lambda1,lambda2); 13 | 14 | areaTerm=-DiracU.*LBF; 15 | penalizeTerm=mu*(4*del2(u)-C); 16 | lengthTerm=nu.*DiracU.*C; 17 | u=u+timestep*(lengthTerm+penalizeTerm+areaTerm); 18 | end 19 | 20 | % Make a function satisfy Neumann boundary condition 21 | function g = NeumannBoundCond(f) 22 | [nrow,ncol] = size(f); 23 | g = f; 24 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 25 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 26 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 27 | 28 | function k = curvature_central(u) 29 | % compute curvature for u with central difference scheme 30 | [ux,uy] = gradient(u); 31 | normDu = sqrt(ux.^2+uy.^2+1e-10); 32 | Nx = ux./normDu; 33 | Ny = uy./normDu; 34 | [nxx,junk] = gradient(Nx); 35 | [junk,nyy] = gradient(Ny); 36 | k = nxx+nyy; 37 | 38 | function [f1,f2] = LBF_LocalBinaryFit(K,Img,KI,KONE,H) 39 | I=Img.*H; 40 | c1=conv2(H,K,'same'); 41 | c2=conv2(I,K,'same'); 42 | f1=c2./(c1); 43 | f2=(KI-c2)./(KONE-c1); 44 | 45 | function h = Heaviside(x,epsilon) % function (11) 46 | h=0.5*(1+(2/pi)*atan(x./epsilon)); 47 | 48 | function f = Dirac(x, epsilon) % function (12) 49 | f=(epsilon/pi)./(epsilon^2.+x.^2); 50 | 51 | function f=LBF_dataForce(Img,K,KONE,f1,f2,lamda1,lamda2) 52 | s1=lamda1.*f1.^2-lamda2.*f2.^2; 53 | s2=lamda1.*f1-lamda2.*f2; 54 | f=(lamda1-lamda2)*KONE.*Img.*Img+conv2(s1,K,'same')-2.*Img.*conv2(s2,K,'same'); 55 | -------------------------------------------------------------------------------- /LBF(Li)/LBF/I5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/I5.bmp -------------------------------------------------------------------------------- /LBF(Li)/LBF/LBF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/LBF.pdf -------------------------------------------------------------------------------- /LBF(Li)/LBF/cq2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/cq2.jpg -------------------------------------------------------------------------------- /LBF(Li)/LBF/mri_nonuniform.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/mri_nonuniform.bmp -------------------------------------------------------------------------------- /LBF(Li)/LBF/noisyNonUniform.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/noisyNonUniform.bmp -------------------------------------------------------------------------------- /LBF(Li)/LBF/plotLevelSet.m: -------------------------------------------------------------------------------- 1 | function [c,h]=plotLevelSet(u,zLevel, style) 2 | % plotLevelSet(u,zLevel, style) plot the level contour of function u at 3 | % the zLevel. 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | % hold on; 9 | [c,h] = contour(u,[zLevel zLevel],style); 10 | % hold off; -------------------------------------------------------------------------------- /LBF(Li)/LBF/vessel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/vessel.bmp -------------------------------------------------------------------------------- /LBF(Li)/LBF/vessel2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/vessel2.bmp -------------------------------------------------------------------------------- /LBF(Li)/LBF/vessel3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/vessel3.bmp -------------------------------------------------------------------------------- /LBF(Li)/LBF/灰度不均.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/LBF/灰度不均.jpg -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Demo_fourImages.m: -------------------------------------------------------------------------------- 1 | % This code demomstrates an improved algorithm based on the local binary fitting (LBF) model 2 | % in Chunming Li et al's paper: 3 | % "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 4 | % IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 5 | % 6 | % Author: Chunming Li, all rights reserved 7 | % E-mail: li_chunming@hotmail.com 8 | % URL: http://www.engr.uconn.edu/~cmli/ 9 | % 10 | % Notes: 11 | % 1. Some parameters are set to default values for the demos in this package. They may need to be 12 | % modified for different types of images. 13 | % 2. The current version does not work for images with multiple junctions, due to its two-phase 14 | % formulation (i.e. using only one level set function). For example, an image has 3 objects/regions, 15 | % and each object/region is directly contiguous to all the other two objects/regions. This code will be 16 | % extended to a multiphase formulation in a new version. 17 | % 3. The image intensities may need to be rescaled to the range of [0, 255], if the intensities are much lower 18 | % or much higher than 255. Alternatively, you can change the parameters lambda1 and lambda2, and nu (the 19 | % coefficient of lenght term) accordingly. 20 | 21 | 22 | close all; 23 | clear all; 24 | 25 | imgID=3; % choose one of the four images by setting imgID to 1, 2, 3, or 4. 26 | c0 = 2; 27 | if imgID ==1 28 | iterNum=120; 29 | lambda1 = 1.0; lambda2 = 1.0; nu = 0.001*255*255; 30 | load Vessel2_initialLSF2.mat; % load image and initial contour 31 | u=c0*sign(initialLSF); 32 | elseif imgID == 2 33 | iterNum=200; 34 | lambda1 = 1.0; lambda2 = 1.0; nu = 0.001*255*255; 35 | load Vessel3_initialLSF; % load image and initial contour 36 | u=c0*sign(initialLSF); 37 | elseif imgID == 3 38 | iterNum =200; 39 | lambda1 = 1.0; lambda2 = 2.0; nu = 0.003*255*255; 40 | load mybrainC100b_initialLSF.mat; % load image and initial contour 41 | u=initialLSF; 42 | elseif imgID==4 43 | iterNum=50; 44 | lambda1 = 1.0; lambda2 = 1.0; nu = 0.001*255*255; 45 | load nonhomo_initialLSF.mat; % load image and initial contour 46 | u=c0*sign(initialLSF); 47 | end 48 | 49 | Img=double(Img(:,:,1)); 50 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 51 | [nrow, ncol]=size(Img); 52 | contour(u,[0 0],'r'); 53 | title('Initial LSF') 54 | pause(.05); 55 | 56 | 57 | pause(0.1); 58 | timestep = .1; 59 | mu = 1; 60 | 61 | epsilon = 1.0; 62 | sigma=3.0; % scale parameter in Gaussian kernel 63 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % Gaussian kernel 64 | KI=conv2(Img,K,'same'); 65 | KONE=conv2(ones(nrow, ncol),K,'same'); 66 | % start level set evolution 67 | time = cputime; 68 | penalizeType=0; 69 | for n=1:iterNum 70 | method='ChunmingLi2005'; % this parameter specifies the method published in CVPR07 (developed in 2006). 71 | DiracFunction='global'; % this parameter specifies the Dirac function that is defined by the 72 | % equation (12) in the CVPR07 paper. Do NOT change this parameter for this version. 73 | Iter=1; 74 | % LSE: level set evolution. 75 | u=LSE(u,Img,K,KI,KONE, nu,timestep,mu,lambda1,lambda2,epsilon,Iter,1,DiracFunction,method,2004); 76 | % The input '2004' represents the internal energy term used in my CVPR'05 and 07 papers (developed in 2004). 77 | % Do NOT change this parameter for this version. 78 | if mod(n,10)==0 79 | pause(0.001); 80 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 81 | contour(u,[0 0],'r'); 82 | iterNum=[num2str(n*Iter), ' iterations']; 83 | title(iterNum); 84 | hold off; 85 | end 86 | end 87 | totaltime = cputime - time 88 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 89 | contour(u,[0 0],'r'); 90 | iterNum=[num2str(n), ' iterations']; 91 | title(iterNum); 92 | 93 | 94 | -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Demo_mri_nonuniform.m: -------------------------------------------------------------------------------- 1 | % This code demomstrates an improved algorithm based on the local binary fitting (LBF) model 2 | % in Chunming Li et al's paper: 3 | % "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 4 | % IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 5 | % 6 | % Author: Chunming Li, all rights reserved 7 | % E-mail: li_chunming@hotmail.com 8 | % URL: http://www.engr.uconn.edu/~cmli/ 9 | % 10 | % Notes: 11 | % 1. Some parameters are set to default values for the demos in this package. They may need to be 12 | % modified for different types of images. 13 | % 2. The current version does not work for images with multiple junctions, due to its two-phase 14 | % formulation (i.e. using only one level set function). For example, an image has 3 objects/regions, 15 | % and each object/region is directly contiguous to all the other two objects/regions. This code will be 16 | % extended to a multiphase formulation in a new version. 17 | % 3. The image intensities may need to be rescaled to the range of [0, 255], if the intensities are much lower 18 | % or much higher than 255. Alternatively, you can change the parameters lambda1 and lambda2, and nu (the 19 | % coefficient of lenght term) accordingly. 20 | 21 | 22 | close all; 23 | clear all; 24 | iterNum = 400; % the number of iterations depend on the location of the initial contour. 25 | % 26 | 27 | Img=imread('mri_nonuniform.bmp'); 28 | Img=double(Img(:,:,1)); 29 | 30 | 31 | lambda1 = 2.0; 32 | lambda2 = 1.0; 33 | nu = 0.001*255*255; 34 | 35 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 36 | text(6,6,'Left click to get points, right click to get end point','FontSize',[12],'Color', 'r'); 37 | BW=zeros(size(Img)); 38 | c0=2; 39 | initialLSF=c0*2*(0.5-BW); 40 | u=initialLSF; 41 | hold on; 42 | [c,h] = contour(u,[0 0],'r'); 43 | 44 | pause(0.1); 45 | timestep = 0.1; 46 | mu = 1; 47 | 48 | epsilon = 1.0; 49 | sigma=2.0; % scale parameter in Gaussian kernel 50 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % Gaussian kernel 51 | Img; 52 | KI=conv2(Img,K,'same'); 53 | KONE=conv2(ones(size(Img)),K,'same'); 54 | % start level set evolution 55 | time = cputime; 56 | for n=1:iterNum 57 | method='ChunmingLi2005'; % this parameter specifies the method published in CVPR07 (developed in 2006). 58 | DiracFunction='global'; % this parameter specifies the Dirac function that is defined by the 59 | % equation (12) in the CVPR07 paper. Do NOT change this parameter for this version. 60 | Iter=1; 61 | % LSE: level set evolution. 62 | u=LSE(u,Img,K,KI,KONE, nu,timestep,mu,lambda1,lambda2,epsilon,Iter,1,DiracFunction,method,2004); 63 | % The input '2004' represents the internal energy term used in my CVPR'05 and 07 papers (developed in 2004). 64 | % Do NOT change this parameter for this version. 65 | if mod(n,10)==0 66 | pause(0.001); 67 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 68 | contour(u,[0 0],'r'); 69 | iterNum=[num2str(n), ' iterations']; 70 | title(iterNum); 71 | hold off; 72 | end 73 | end 74 | totaltime = cputime - time 75 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 76 | contour(u,[0 0],'r'); 77 | iterNum=[num2str(n), ' iterations']; 78 | title(iterNum); 79 | 80 | -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Demo_noisySynthetic.m: -------------------------------------------------------------------------------- 1 | % This code demomstrates an improved algorithm based on the local binary fitting (LBF) model 2 | % in Chunming Li et al's paper: 3 | % "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 4 | % IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 5 | % 6 | % Author: Chunming Li, all rights reserved 7 | % E-mail: li_chunming@hotmail.com 8 | % URL: http://www.engr.uconn.edu/~cmli/ 9 | % 10 | % Notes: 11 | % 1. Some parameters are set to default values for the demos in this package. They may need to be 12 | % modified for different types of images. 13 | % 2. The current version does not work for images with multiple junctions, due to its two-phase 14 | % formulation (i.e. using only one level set function). For example, an image has 3 objects/regions, 15 | % and each object/region is directly contiguous to all the other two objects/regions. This code will be 16 | % extended to a multiphase formulation in a new version. 17 | % 3. The image intensities may need to be rescaled to the range of [0, 255], if the intensities are much lower 18 | % or much higher than 255. Alternatively, you can change the parameters lambda1 and lambda2, and nu (the 19 | % coefficient of lenght term) accordingly. 20 | 21 | 22 | close all; 23 | clear all; 24 | iterNum = 200; % the number of iterations depend on the location of the initial contour. 25 | % 26 | 27 | Img=imread('noisyNonUniform.bmp'); 28 | Img=double(Img(:,:,1)); 29 | 30 | 31 | lambda1 = 1.0; 32 | lambda2 = 1.0; 33 | nu = 0.001*255*255; % 34 | 35 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 36 | text(6,6,'Left click to get points, right click to get end point','FontSize',[12],'Color', 'r'); 37 | BW=roipoly; 38 | c0=2; 39 | initialLSF=c0*2*(0.5-BW); 40 | u=initialLSF; 41 | hold on; 42 | [c,h] = contour(u,[0 0],'r'); 43 | 44 | pause(0.1); 45 | timestep = 0.1; 46 | mu = 1; 47 | 48 | epsilon = 1.0; 49 | sigma=2.0; % scale parameter in Gaussian kernel 50 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % Gaussian kernel 51 | Img; 52 | KI=conv2(Img,K,'same'); 53 | KONE=conv2(ones(size(Img)),K,'same'); 54 | % start level set evolution 55 | time = cputime; 56 | for n=1:iterNum 57 | method='ChunmingLi2005'; % this parameter specifies the method published in CVPR07 (developed in 2006). 58 | DiracFunction='global'; % this parameter specifies the Dirac function that is defined by the 59 | % equation (12) in the CVPR07 paper. Do NOT change this parameter for this version. 60 | Iter=1; 61 | % LSE: level set evolution. 62 | u=LSE(u,Img,K,KI,KONE, nu,timestep,mu,lambda1,lambda2,epsilon,Iter,1,DiracFunction,method,2004); 63 | % The input '2004' represents the internal energy term used in my CVPR'05 and 07 papers (developed in 2004). 64 | % Do NOT change this parameter for this version. 65 | if mod(n,5)==0 66 | pause(0.001); 67 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 68 | contour(u,[0 0],'r'); 69 | iterNum=[num2str(n), ' iterations']; 70 | title(iterNum); 71 | hold off; 72 | end 73 | end 74 | totaltime = cputime - time 75 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 76 | contour(u,[0 0],'r'); 77 | iterNum=[num2str(n), ' iterations']; 78 | title(iterNum); -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Demo_vessel.m: -------------------------------------------------------------------------------- 1 | % This code demomstrates an improved algorithm based on the local binary fitting (LBF) model 2 | % in Chunming Li et al's paper: 3 | % "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 4 | % IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 5 | % 6 | % Author: Chunming Li, all rights reserved 7 | % E-mail: li_chunming@hotmail.com 8 | % URL: http://www.engr.uconn.edu/~cmli/ 9 | % 10 | % Notes: 11 | % 1. Some parameters are set to default values for the demos in this package. They may need to be 12 | % modified for different types of images. 13 | % 2. The current version does not work for images with multiple junctions, due to its two-phase 14 | % formulation (i.e. using only one level set function). For example, an image has 3 objects/regions, 15 | % and each object/region is directly contiguous to all the other two objects/regions. This code will be 16 | % extended to a multiphase formulation in a new version. 17 | % 3. The image intensities may need to be rescaled to the range of [0, 255], if the intensities are much lower 18 | % or much higher than 255. Alternatively, you can change the parameters lambda1 and lambda2, and nu (the 19 | % coefficient of lenght term) accordingly. 20 | 21 | 22 | 23 | close all; 24 | clear all; 25 | 26 | Img=imread('vessel3.bmp'); 27 | %Img=imread('vessel2.bmp'); % uncommont this line to use ther other vessel image 28 | Img=double(Img); 29 | 30 | iterNum = 400; 31 | lambda1 = 1.0; 32 | lambda2 = 1.0; 33 | nu = 0.001*255*255; 34 | 35 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 36 | text(6,6,'Left click to get points, right click to get end point','FontSize',[12],'Color', 'r'); 37 | BW=roipoly; 38 | c0=2; 39 | initialLSF=c0*2*(0.5-BW); 40 | u=initialLSF; 41 | hold on; 42 | [c,h] = contour(u,[0 0],'r'); 43 | 44 | pause(0.1); 45 | timestep = 0.1; 46 | mu = 1; 47 | 48 | epsilon = 1.0; 49 | sigma=3.0; % scale parameter in Gaussian kernel 50 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % Gaussian kernel 51 | Img; 52 | KI=conv2(Img,K,'same'); 53 | KONE=conv2(ones(size(Img)),K,'same'); 54 | % start level set evolution 55 | time = cputime; 56 | for n=1:iterNum 57 | method='ChunmingLi2005'; % this parameter specifies the method published in CVPR07 (developed in 2006). 58 | DiracFunction='global'; % this parameter specifies the Dirac function that is defined by the 59 | % equation (12) in the CVPR07 paper. Do NOT change this parameter for this version. 60 | Iter=1; 61 | % LSE: level set evolution. 62 | u=LSE(u,Img,K,KI,KONE, nu,timestep,mu,lambda1,lambda2,epsilon,Iter,1,DiracFunction,method,2004); 63 | % The input '2004' represents the internal energy term used in my CVPR'05 and 07 papers (developed in 2004). 64 | % Do NOT change this parameter for this version. 65 | if mod(n,10)==0 66 | pause(0.001); 67 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 68 | contour(u,[0 0],'r'); 69 | iterNum=[num2str(n), ' iterations']; 70 | title(iterNum); 71 | hold off; 72 | end 73 | end 74 | totaltime = cputime - time 75 | imagesc(Img, [0, 255]);colormap(gray);hold on; axis off; 76 | contour(u,[0 0],'r'); 77 | iterNum=[num2str(n), ' iterations']; 78 | title(iterNum); -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/LSE.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/LSE.dll -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Readme.txt: -------------------------------------------------------------------------------- 1 | This package includes two folders: 2 | 3 | LBF_v0: 4 | This is the Matlab code that implements the local binary fitting (LBF) model in Chunming Li et al's paper: 5 | "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 6 | IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 7 | 8 | LBF_v0.1: 9 | This code implements an improved algorithm slightly modified from the original LBF model in the above paper. 10 | A desirable advantage of this improved version of LBF algorithm is that it is very robust to contour initialization. -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Vessel2_initialLSF2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/Vessel2_initialLSF2.mat -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/Vessel3_initialLSF.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/Vessel3_initialLSF.mat -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/mri_nonuniform.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/mri_nonuniform.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/mybrainC100b_initialLSF.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/mybrainC100b_initialLSF.mat -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/noisyNonUniform.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/noisyNonUniform.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/noisyNonUniform_initialLSF.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/noisyNonUniform_initialLSF.mat -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/nonhomo_initialLSF.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/nonhomo_initialLSF.mat -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/vessel2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/vessel2.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0.1/vessel3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0.1/vessel3.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/1.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/2.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/3.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/4.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/5.bmp -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/88.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/88.tif -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/Demo_RSF.m: -------------------------------------------------------------------------------- 1 | % This Matlab file demomstrates a level set method in Chunming Li et al's paper 2 | % "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 3 | % IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 4 | % Author: Chunming Li, all rights reserved 5 | % E-mail: li_chunming@hotmail.com 6 | % URL: http://www.engr.uconn.edu/~cmli/ 7 | % 8 | % Note 1: This method with a small scale parameter sigma, such as sigma = 3, is sensitive to 9 | % initialization of the level set function. Appropriate initial level set functions are given in 10 | % this code for different test images. 11 | % Note 2: There are several ways to improve the original LBF model to make it robust to initialization. 12 | % One of the improved LBF algorithms is implemented by the code in the folder LBF_v0.1 13 | 14 | 15 | clc;clear all;close all; 16 | c0 = 2; 17 | imgID = 1; % 1,2,3,4,5 % choose one of the five test images 18 | 19 | Img = imread('1.bmp');%[num2str(imgID),'.bmp'] 20 | Img = double(Img(:,:,1)); 21 | 22 | switch imgID 23 | case 1 24 | iterNum =300; 25 | lambda1 = 1.0; 26 | lambda2 = 2.0; 27 | nu = 0.004*255*255;% coefficient of the length term 28 | initialLSF = ones(size(Img(:,:,1))).*c0; 29 | initialLSF(20:70,30:90) = -c0; 30 | case 2 31 | iterNum =200; 32 | lambda1 = 1.0; 33 | lambda2 = 1.0; 34 | nu = 0.002*255*255;% coefficient of the length term 35 | initialLSF = ones(size(Img(:,:,1))).*c0; 36 | initialLSF(26:32,28:34) = -c0; 37 | case 3 38 | iterNum =500; 39 | lambda1 = 1.0; 40 | lambda2 = 1.0; 41 | nu = 0.003*255*255;% coefficient of the length term 42 | initialLSF = ones(size(Img(:,:,1))).*c0; 43 | initialLSF(5:78,32:55) = -c0; 44 | case 4 45 | iterNum =150; 46 | lambda1 = 1.0; 47 | lambda2 = 1.0; 48 | nu = 0.001*255*255;% coefficient of the length term 49 | initialLSF = ones(size(Img(:,:,1))).*c0; 50 | initialLSF(53:77,46:70) = -c0; 51 | case 5 52 | iterNum =220; 53 | lambda1 = 1.0; 54 | lambda2 = 1.0; 55 | nu = 0.001*255*255;% coefficient of the length term 56 | initialLSF = ones(size(Img(:,:,1))).*c0; 57 | initialLSF(47:60,86:99) = -c0; 58 | end 59 | 60 | u = initialLSF; 61 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 62 | title('Initial contour'); 63 | [c,h] = contour(u,[0 0],'r'); 64 | pause(0.1); 65 | 66 | timestep = .1;% time step 67 | mu = 1;% coefficient of the level set (distance) regularization term P(\phi) 68 | 69 | epsilon = 1.0;% the papramater in the definition of smoothed Dirac function 70 | sigma=3.0; % scale parameter in Gaussian kernel 71 | % Note: A larger scale parameter sigma, such as sigma=10, would make the LBF algorithm more robust 72 | % to initialization, but the segmentation result may not be as accurate as using 73 | % a small sigma when there is severe intensity inhomogeneity in the image. If the intensity 74 | % inhomogeneity is not severe, a relatively larger sigma can be used to increase the robustness of the LBF 75 | % algorithm. 76 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); % the Gaussian kernel 77 | I = Img; 78 | KI=conv2(Img,K,'same'); % compute the convolution of the image with the Gaussian kernel outside the iteration 79 | % See Section IV-A in the above IEEE TIP paper for implementation. 80 | 81 | KONE=conv2(ones(size(Img)),K,'same'); % compute the convolution of Gassian kernel and constant 1 outside the iteration 82 | % See Section IV-A in the above IEEE TIP paper for implementation. 83 | 84 | % start level set evolution 85 | for n=1:iterNum 86 | u=RSF(u,I,K,KI,KONE, nu,timestep,mu,lambda1,lambda2,epsilon,1); 87 | if mod(n,20)==0 88 | pause(0.1); 89 | imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 90 | [c,h] = contour(u,[0 0],'r'); 91 | iterNum=[num2str(n), ' iterations']; 92 | title(iterNum); 93 | hold off; 94 | end 95 | end 96 | imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 97 | [c,h] = contour(u,[0 0],'r'); 98 | totalIterNum=[num2str(n), ' iterations']; 99 | title(['Final contour, ', totalIterNum]); 100 | 101 | figure; 102 | mesh(u); 103 | title('Final level set function'); 104 | 105 | -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/Minimization of Region-Scalable Fitting Energy__for Image Segmentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/Minimization of Region-Scalable Fitting Energy__for Image Segmentation.pdf -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/RSF.m: -------------------------------------------------------------------------------- 1 | function u = RSF(u0,Img,Ksigma,KI,KONE,nu,timestep,mu,lambda1,lambda2,epsilon,numIter) 2 | % LSE_LBF implements the level set evolution (LSE) for the method in Chunming Li et al's paper: 3 | % "Minimization of Region-Scalable Fitting Energy for Image Segmentation", 4 | % IEEE Trans. Image Processing, vol. 17 (10), pp.1940-1949, 2008. 5 | % 6 | % Author: Chunming Li, all rights reserved 7 | % E-mail: li_chunming@hotmail.com 8 | % URL: http://www.engr.uconn.edu/~cmli/ 9 | % 10 | % For easy understanding of my code, please read the comments in the code that refer 11 | % to the corresponding equations in the above IEEE TIP paper. 12 | 13 | 14 | u=u0; 15 | for k1=1:numIter 16 | u=NeumannBoundCond(u); 17 | K=curvature_central(u); 18 | 19 | DrcU=(epsilon/pi)./(epsilon^2.+u.^2); % eq.(9) 20 | 21 | [f1, f2] = localBinaryFit(Img, u, KI, KONE, Ksigma, epsilon); 22 | 23 | 24 | %%% compute lambda1*e1-lambda2*e2 25 | s1=lambda1.*f1.^2-lambda2.*f2.^2; % compute lambda1*e1-lambda2*e2 in the 1st term in eq. (15) in IEEE TIP 08 26 | s2=lambda1.*f1-lambda2.*f2; 27 | dataForce=(lambda1-lambda2)*KONE.*Img.*Img+conv2(s1,Ksigma,'same')-2.*Img.*conv2(s2,Ksigma,'same'); 28 | % eq.(15) 29 | A=-DrcU.*dataForce; % 1st term in eq. (15) 30 | P=mu*(4*del2(u)-K); % 3rd term in eq. (15), where 4*del2(u) computes the laplacian (d^2u/dx^2 + d^2u/dy^2) 31 | L=nu.*DrcU.*K; % 2nd term in eq. (15) 32 | u=u+timestep*(L+P+A); % eq.(15) 33 | end 34 | 35 | function [f1, f2]= localBinaryFit(Img, u, KI, KONE, Ksigma, epsilon) 36 | % compute f1 and f2 37 | Hu=0.5*(1+(2/pi)*atan(u./epsilon)); % eq.(8) 38 | 39 | I=Img.*Hu; 40 | c1=conv2(Hu,Ksigma,'same'); 41 | c2=conv2(I,Ksigma,'same'); % the numerator of eq.(14) for i = 1 42 | f1=c2./(c1); % compute f1 according to eq.(14) for i = 1 43 | f2=(KI-c2)./(KONE-c1); % compute f2 according to the formula in Section IV-A, 44 | % which is an equivalent expression of eq.(14) for i = 2. 45 | 46 | 47 | function g = NeumannBoundCond(f) 48 | % Neumann boundary condition 49 | [nrow,ncol] = size(f); 50 | g = f; 51 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 52 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 53 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 54 | 55 | function k = curvature_central(u) 56 | % compute curvature 57 | [ux,uy] = gradient(u); 58 | normDu = sqrt(ux.^2+uy.^2+1e-10); % the norm of the gradient plus a small possitive number 59 | % to avoid division by zero in the following computation. 60 | Nx = ux./normDu; 61 | Ny = uy./normDu; 62 | [nxx,junk] = gradient(Nx); 63 | [junk,nyy] = gradient(Ny); 64 | k = nxx+nyy; % compute divergence 65 | 66 | 67 | -------------------------------------------------------------------------------- /LBF(Li)/RSF_v0/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LBF(Li)/RSF_v0/Thumbs.db -------------------------------------------------------------------------------- /LGIF/03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/03.jpg -------------------------------------------------------------------------------- /LGIF/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/12.jpg -------------------------------------------------------------------------------- /LGIF/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/3.jpg -------------------------------------------------------------------------------- /LGIF/Delta.m: -------------------------------------------------------------------------------- 1 | function Delta_h = Delta(phi, epsilon) 2 | 3 | 4 | Delta_h=(epsilon/pi)./(epsilon^2+ phi.^2); -------------------------------------------------------------------------------- /LGIF/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/Thumbs.db -------------------------------------------------------------------------------- /LGIF/backward_gradient.m: -------------------------------------------------------------------------------- 1 | function [bdy,bdx]=backward_gradient(f); 2 | % function [bdx,bdy]=backward_gradient(f); 3 | 4 | [nr,nc]=size(f); 5 | bdx=zeros(nr,nc); 6 | bdy=zeros(nr,nc); 7 | 8 | bdx(2:nr,:)=f(2:nr,:)-f(1:nr-1,:); 9 | bdy(:,2:nc)=f(:,2:nc)-f(:,1:nc-1); -------------------------------------------------------------------------------- /LGIF/cq18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/cq18.jpg -------------------------------------------------------------------------------- /LGIF/cq2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/cq2.jpg -------------------------------------------------------------------------------- /LGIF/cq391.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/cq391.jpg -------------------------------------------------------------------------------- /LGIF/cq44.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/cq44.bmp -------------------------------------------------------------------------------- /LGIF/cqc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/cqc.jpg -------------------------------------------------------------------------------- /LGIF/curvature.m: -------------------------------------------------------------------------------- 1 | function K=curvature(f) 2 | 3 | 4 | 5 | 6 | [f_fx,f_fy]=forward_gradient(f); 7 | [f_bx,f_by]=backward_gradient(f); 8 | 9 | mag1=sqrt(f_fx.^2+f_fy.^2+1e-10); 10 | n1x=f_fx./mag1; 11 | n1y=f_fy./mag1; 12 | 13 | mag2=sqrt(f_bx.^2+f_fy.^2+1e-10); 14 | n2x=f_bx./mag2; 15 | n2y=f_fy./mag2; 16 | 17 | mag3=sqrt(f_fx.^2+f_by.^2+1e-10); 18 | n3x=f_fx./mag3; 19 | n3y=f_by./mag3; 20 | 21 | mag4=sqrt(f_bx.^2+f_by.^2+1e-10); 22 | n4x=f_bx./mag4; 23 | n4y=f_by./mag4; 24 | 25 | nx=n1x+n2x+n3x+n4x; 26 | ny=n1y+n2y+n3y+n4y; 27 | 28 | magn=sqrt(nx.^2+ny.^2); 29 | nx=nx./(magn+1e-10); 30 | ny=ny./(magn+1e-10); 31 | 32 | [nxx,nxy]=gradient(nx); 33 | [nyx,nyy]=gradient(ny); 34 | 35 | K=nxx+nyy; -------------------------------------------------------------------------------- /LGIF/demo_LGIF.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/demo_LGIF.m -------------------------------------------------------------------------------- /LGIF/evolution_LGIF.m: -------------------------------------------------------------------------------- 1 | function phi = evolution_LGIF(Img,K,KI,KONE,phi,M,lambda1,lambda2,mu,lambda,delta_t,epsilon,numIter) 2 | % evolution_withoutedge(I, phi0, mu, nu, lambda_1, lambda_2, delta_t, delta_h, epsilon, numIter); 3 | % input: 4 | % I: input image 5 | % phi0: level set function to be updated 6 | % mu: weight for length term 7 | % nu: weight for area term, default value 0 8 | % lambda_1: weight for c1 fitting term 9 | % lambda_2: weight for c2 fitting term 10 | % delta_t: time step 11 | % epsilon: parameter for computing smooth Heaviside and dirac function 12 | % numIter: number of iterations 13 | % output: 14 | % phi: updated level set function 15 | % 16 | 17 | for k=1:numIter 18 | phi=NeumannBoundCond(phi); 19 | delta_h=Delta(phi,epsilon); 20 | H=Heaviside(phi,epsilon); 21 | Curv=curvature(phi); 22 | [C1,C2]=binaryfit(phi,Img,H,epsilon); 23 | [f1,f2]=LBF_LocalBinaryFit(K,Img,KI,KONE,H); 24 | LBF=LBF_dataForce(Img,K,KONE,f1,f2,lambda1,lambda2); 25 | % updating the phi function 26 | F1=(1-M)*LBF; 27 | F2=M*(-lambda1*(Img-C1).^2+lambda2*(Img-C2).^2); 28 | penalizingTerm=mu.*(4*del2(phi)-Curv); 29 | weightedLengthTerm=lambda.*delta_h.*Curv ; 30 | phi=phi+delta_t*(delta_h.*(F2-F1)+ weightedLengthTerm+penalizingTerm); 31 | end 32 | 33 | 34 | 35 | function g=NeumannBoundCond(f) 36 | % Make a function satisfy Neumann boundary condition 37 | [nrow,ncol] = size(f); 38 | g = f; 39 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 40 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 41 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 42 | 43 | function H = Heaviside(phi,epsilon) 44 | % Heaviside(phi,epsilon) compute the smooth Heaviside function 45 | H = 0.5*(1+ (2/pi)*atan(phi./epsilon)); 46 | 47 | function [f1,f2] = LBF_LocalBinaryFit(K,Img,KI,KONE,H) 48 | I=Img.*H; 49 | c1=conv2(H,K,'same'); 50 | c2=conv2(I,K,'same'); 51 | f1=c2./(c1); 52 | f2=(KI-c2)./(KONE-c1); 53 | 54 | function f=LBF_dataForce(Img,K,KONE,f1,f2,lamda1,lamda2) 55 | s1=lamda1.*f1.^2-lamda2.*f2.^2; 56 | s2=lamda1.*f1-lamda2.*f2; 57 | f=(lamda1-lamda2)*KONE.*Img.*Img+conv2(s1,K,'same')-2.*Img.*conv2(s2,K,'same'); 58 | 59 | function [C1,C2]= binaryfit(phi,U,H,epsilon) 60 | a= H.*U; 61 | numer_1=sum(a(:)); 62 | denom_1=sum(H(:)); 63 | C1 = numer_1/denom_1; 64 | 65 | b=(1-H).*U; 66 | numer_2=sum(b(:)); 67 | c=1-H; 68 | denom_2=sum(c(:)); 69 | C2 = numer_2/denom_2; 70 | -------------------------------------------------------------------------------- /LGIF/forward_gradient.m: -------------------------------------------------------------------------------- 1 | function [fdy,fdx]=forward_gradient(f); 2 | % function [fdx,fdy]=forward_gradient(f); 3 | 4 | [nr,nc]=size(f); 5 | fdx=zeros(nr,nc); 6 | fdy=zeros(nr,nc); 7 | 8 | a=f(2:nr,:)-f(1:nr-1,:); 9 | fdx(1:nr-1,:)=a; 10 | b=f(:,2:nc)-f(:,1:nc-1); 11 | fdy(:,1:nc-1)=b; 12 | -------------------------------------------------------------------------------- /LGIF/new_img.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/new_img.bmp -------------------------------------------------------------------------------- /LGIF/picturelab.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/picturelab.bmp -------------------------------------------------------------------------------- /LGIF/plotLevelSet.m: -------------------------------------------------------------------------------- 1 | function [c,h]=plotLevelSet(u,zLevel, style) 2 | % plotLevelSet(u,zLevel, style) plot the level contour of function u at 3 | 4 | [c,h] = contour(u,[zLevel zLevel],style); 5 | -------------------------------------------------------------------------------- /LGIF/vessel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LGIF/vessel.bmp -------------------------------------------------------------------------------- /LIF/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LIF/1.bmp -------------------------------------------------------------------------------- /LIF/3c.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LIF/3c.bmp -------------------------------------------------------------------------------- /LIF/Demo.m: -------------------------------------------------------------------------------- 1 | % This Matlab program demomstrates the level set algorithm in paper: 2 | % "Active contours driven by local image fitting energy" 3 | % to appear in Pattern Recognition, 2010 4 | % Author: Kaihua Zhang, Huihui Song and Lei Zhang 5 | % E-mail: zhkhua@mail.ustc.edu.cn, cslzhang@comp.polyu.edu.hk 6 | % http://www4.comp.polyu.edu.hk/~cslzhang/ 7 | 8 | % Notes: 9 | % 1. Some parameters may need to be modified for different types of images. Please contact the author if any problem regarding the choice of parameters. 10 | % 2. Intial contour should be set properly. 11 | 12 | % Date: 5/11/2009 13 | 14 | clear all;close all;clc; 15 | 16 | Img = imread('1.bmp'); 17 | Img = double(Img(:,:,1)); 18 | sigma =3;% the key parameter which needs to be tuned properly. 19 | sigma_phi = 0.9;% the variance of regularized Gaussian kernel 20 | K = fspecial('gaussian',2*round(2*sigma)+1,sigma); 21 | K_phi = fspecial('gaussian',5,sigma_phi); 22 | 23 | [nrow,ncol] = size(Img); 24 | 25 | phi = ones(nrow,ncol); 26 | phi(35:nrow-35,55:ncol-35) = -1; 27 | figure; imagesc(Img,[0 255]);colormap(gray);hold on; 28 | contour(phi,[0 0],'b'); 29 | 30 | timestep = 1; 31 | epsilon = 1.5; 32 | for n = 1:600 33 | [phi,f1,f2,Hphi]= LIF_2D(Img,phi,timestep,epsilon,K); 34 | phi = conv2(phi,K_phi,'same'); 35 | if mod(n,40)==0 36 | pause(0.0001); 37 | imagesc(Img,[0 255]);colormap(gray) 38 | hold on;contour(phi,[0 0],'b'); 39 | iterNum=[num2str(n), ' iterations']; 40 | title(iterNum); 41 | hold off; 42 | end 43 | end 44 | 45 | figure; 46 | mesh(phi); -------------------------------------------------------------------------------- /LIF/LIF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LIF/LIF.pdf -------------------------------------------------------------------------------- /LIF/LIF_2D.m: -------------------------------------------------------------------------------- 1 | function [phi,f1,f2,Hphi] = LIF_2D(I,phi,timestep,epsilon,K) 2 | 3 | phi = NeumannBoundCond(phi); 4 | 5 | Hphi = Heaviside(phi,epsilon); 6 | DiracPhi = Delta(phi,epsilon); 7 | 8 | [f1,f2] = Local_Avr(I,Hphi,K); 9 | 10 | phi = phi + timestep*DiracPhi.*((I - f1.*Hphi - f2.*(1 - Hphi)).*(f1 - f2)); 11 | 12 | function H = Heaviside(phi,epsilon) 13 | H = 0.5*(1+(2/pi)*atan(phi./epsilon)); 14 | 15 | function Delta_h = Delta(phi,epsilon) 16 | Delta_h = (epsilon/pi)./(epsilon^2+phi.^2); 17 | 18 | function [f1,f2] = Local_Avr(I,H,K) 19 | 20 | f1 = conv2(I.*H,K,'same'); 21 | c1 = conv2(H,K,'same'); 22 | f1 = f1./c1; 23 | f2 = conv2(I.*(1-H),K,'same'); 24 | c2 = conv2(1-H,K,'same'); 25 | f2 = f2./c2; 26 | 27 | function g = NeumannBoundCond(f) 28 | % Make a function satisfy Neumann boundary condition 29 | [nrow,ncol] = size(f); 30 | g = f; 31 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 32 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 33 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /LoG&RSF/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/1.bmp -------------------------------------------------------------------------------- /LoG&RSF/2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/2.bmp -------------------------------------------------------------------------------- /LoG&RSF/3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/3.bmp -------------------------------------------------------------------------------- /LoG&RSF/4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/4.bmp -------------------------------------------------------------------------------- /LoG&RSF/5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/5.bmp -------------------------------------------------------------------------------- /LoG&RSF/6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/6.bmp -------------------------------------------------------------------------------- /LoG&RSF/ACM_LoG.m: -------------------------------------------------------------------------------- 1 | function [u,f1,f2]= ACM_LoG(u,Img,Ksigma,KI,KONE,nu,timestep,mu,epsilon,lambda1,lambda2,RSF,LRCV,LIF,isExchange,log_) 2 | 3 | u=NeumannBoundCond(u); 4 | K=curvature_central(u); 5 | 6 | Hu=0.5*(1+(2/pi)*atan(u./epsilon)); 7 | DrcU=(epsilon/pi)./(epsilon^2.+u.^2); 8 | 9 | KIH= imfilter((Hu.*Img),Ksigma,'replicate'); 10 | KH= imfilter(Hu,Ksigma,'replicate'); 11 | f1=KIH./KH; 12 | f2=(KI-KIH)./(KONE-KH); 13 | 14 | [f1,f2]=exchange(f1,f2,isExchange); 15 | 16 | if LRCV~=0 17 | LRCVterm=LRCV*DrcU.*(-lambda1*(Img-f1).^2+lambda2*(Img-f2).^2); 18 | else 19 | LRCVterm=0; 20 | end 21 | 22 | if LIF~=0 23 | LIFterm=DrcU.*((Img - f1.*Hu - f2.*(1 - Hu)).*(f1 - f2)); 24 | else 25 | LIFterm=0; 26 | end 27 | 28 | if RSF~=0 29 | s1=lambda1.*f1.^2-lambda2.*f2.^2; 30 | s2=lambda1.*f1-lambda2.*f2; 31 | dataForce=(lambda1-lambda2)*KONE.*Img.*Img+imfilter(s1,Ksigma,'replicate')-2.*Img.*imfilter(s2,Ksigma,'replicate'); 32 | RSFterm=-RSF*DrcU.*dataForce; 33 | else 34 | RSFterm=0; 35 | end 36 | 37 | LoGterm=log_.*DrcU; % 38 | 39 | PenaltyTerm=mu*(4*del2(u)-K); 40 | 41 | LengthTerm=nu.*DrcU.*K; 42 | 43 | u = u + timestep*(LengthTerm+PenaltyTerm+RSFterm+LRCVterm+LIFterm+LoGterm); % update level set 44 | 45 | 46 | function g = NeumannBoundCond(f) 47 | % Neumann boundary condition 48 | [nrow,ncol] = size(f); 49 | g = f; 50 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 51 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 52 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 53 | 54 | function k = curvature_central(u) 55 | % compute curvature 56 | [ux,uy] = gradient(u); 57 | normDu = sqrt(ux.^2+uy.^2+1e-10); 58 | Nx = ux./normDu; 59 | Ny = uy./normDu; 60 | [nxx,~] = gradient(Nx); 61 | [~,nyy] = gradient(Ny); 62 | k = nxx+nyy; 63 | 64 | function [f1,f2]=exchange(f1,f2,isExchange) 65 | %exchange f1 and f2 66 | if isExchange==0 67 | return; 68 | end 69 | if isExchange==1 70 | f1=min(f1,f2); 71 | f2=max(f1,f2); 72 | end 73 | if isExchange==-1 74 | f1=max(f1,f2); 75 | f2=min(f1,f2); 76 | end 77 | -------------------------------------------------------------------------------- /LoG&RSF/Active contours driven by region-scalable fitting and optimized Laplacian of Gaussian energy for image segmentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LoG&RSF/Active contours driven by region-scalable fitting and optimized Laplacian of Gaussian energy for image segmentation.pdf -------------------------------------------------------------------------------- /LoG&RSF/Demo_ACM_LoG.m: -------------------------------------------------------------------------------- 1 | % The Matlab code of the paper 2 | % "K. Ding, L. Xiao and G. Weng. Active contours driven by region-scalable fitting and optimized loglacian of Gaussian energy for image segmentation. Signal Processing, 134, 224-233, 2017. 3 | % Keyan Ding, 2018.02.29 4 | 5 | clc; clear all; close all; 6 | Img = imread('3.bmp'); 7 | Img = double(Img(:,:,1)); 8 | 9 | % -----set initial contour----- 10 | c0 = 1; 11 | initialLSF = ones(size(Img(:,:,1))).*c0; 12 | initialLSF(15:55,40:80) = -c0; 13 | 14 | % figure;imagesc(Img, [0, 255]); colormap(gray);hold on; axis off;axis equal; 15 | % text(6,6,'Left click to get points, right click to get end point','FontSize',[12],'Color', 'g'); 16 | % BW=roipoly; 17 | % hold off; 18 | % initialLSF=c0*2*(0.5-BW); 19 | 20 | % BW=im2bw(imread('mask.bmp'),0.5); 21 | % initialLSF=c0*2*(0.5-BW); 22 | 23 | u = initialLSF; 24 | h1 = figure(1);imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 25 | contour(initialLSF,[0 0],'g','linewidth',1.5);hold off 26 | pause(0.1); 27 | 28 | % -----set parameters----- 29 | mu = 2; % the distance regularization term 30 | nu = 0.002*255*255; % the length term. (need adjust) 31 | theta = 20; %the LoG term, + / - (need adjust) 32 | lambda1 = 1; 33 | lambda2 = 1; 34 | epsilon = 1.0; 35 | timestep = 0.05; 36 | iterNum = 300; % the number of iterations. 37 | sigma = 3; % control the local size 38 | 39 | Ksigma=fspecial('gaussian',round(2*sigma)*2+1,sigma); 40 | KONE = imfilter(ones(size(Img)),Ksigma,'replicate'); 41 | KI = imfilter(Img,Ksigma,'replicate'); 42 | 43 | % --- model weight --- 44 | RSF = 1; 45 | LRCV = 0; 46 | LIF = 0; 47 | 48 | % see "K. Ding, A Simple Method to improve Initialization Robustness for Active Contours driven by Local Region Fitting Energy, 2018, arXiv:1802.10437." 49 | isExchange = 0; % '1' for bright object and dark backgroud; 50 | % '-1' for dark object and bright backgroud; 51 | % '0' represent original model. 52 | 53 | % ----- regularised loglacian----- 54 | G=fspecial('gaussian',[9 9],1); 55 | Img_gao=imfilter(Img,G,'replicate'); 56 | [Ix,Iy]=gradient(Img_gao); 57 | f=Ix.^2+Iy.^2; 58 | log=4*del2(Img_gao); 59 | % figure,imshow(log,[]),colorbar 60 | g_=zeros(size(Img)); 61 | log_=zeros(size(Img)); 62 | g=exp(-0.01*f); % alpha = 0.01 63 | for i=1:100 64 | log_=log_+0.01*(g.*log_ - (1-g).*(log_ - 5*log)); % beta = 5 65 | end 66 | log_ = theta*log_; 67 | % figure,imshow(log_,[]);colorbar 68 | 69 | % -----start level set evolution----- 70 | h2=figure(2); 71 | tic 72 | for n=1:iterNum 73 | [u,f1,f2]=ACM_LoG(u,Img,Ksigma,KI,KONE,nu,timestep,mu,epsilon,lambda1,lambda2,RSF,LRCV,LIF,isExchange,log_); 74 | if mod(n,10)==0 75 | imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 76 | contour(u,[0 0],'r'); title([num2str(n), ' iterations ']); 77 | hold off;pause(.1); 78 | end 79 | end 80 | toc 81 | 82 | % -----display result----- 83 | imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 84 | [c,h] = contour(u,[0 0],'r','linewidth',1.5); 85 | % figure;mesh(u);colorbar;title('Final level set function');hold on, contour(u,[0 0],'r','linewidth',1.5); 86 | 87 | -------------------------------------------------------------------------------- /Local Pre-fitting/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/1.bmp -------------------------------------------------------------------------------- /Local Pre-fitting/2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/2.bmp -------------------------------------------------------------------------------- /Local Pre-fitting/3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/3.bmp -------------------------------------------------------------------------------- /Local Pre-fitting/4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/4.bmp -------------------------------------------------------------------------------- /Local Pre-fitting/5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/5.bmp -------------------------------------------------------------------------------- /Local Pre-fitting/6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/6.bmp -------------------------------------------------------------------------------- /Local Pre-fitting/ACM_LPF.m: -------------------------------------------------------------------------------- 1 | function u= ACM_LPF(u,nu,timestep,mu,epsilon,lambda1,lambda2,e1,e2) 2 | 3 | u=NeumannBoundCond(u); 4 | K=curvature_central(u); 5 | 6 | DrcU=(epsilon/pi)./(epsilon^2.+u.^2); 7 | H=0.5*(1+(2/pi)*atan(u./epsilon)); 8 | 9 | LPFterm=-DrcU.*(e1.*lambda1-e2.*lambda2); 10 | PenaltyTerm=mu*(4*del2(u)-K); 11 | LengthTerm=nu.*DrcU.*K; 12 | u=u+timestep*(LengthTerm+PenaltyTerm+LPFterm); %LIFterm 13 | 14 | 15 | function g = NeumannBoundCond(f) 16 | % Neumann boundary condition 17 | [nrow,ncol] = size(f); 18 | g = f; 19 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 20 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 21 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 22 | 23 | function k = curvature_central(u) 24 | % compute curvature 25 | [ux,uy] = gradient(u); 26 | normDu = sqrt(ux.^2+uy.^2+1e-10); 27 | Nx = ux./normDu; 28 | Ny = uy./normDu; 29 | [nxx,~] = gradient(Nx); 30 | [~,nyy] = gradient(Ny); 31 | k = nxx+nyy; 32 | -------------------------------------------------------------------------------- /Local Pre-fitting/Active contours driven by local pre-fitting energy for fast image segmentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/Active contours driven by local pre-fitting energy for fast image segmentation.pdf -------------------------------------------------------------------------------- /Local Pre-fitting/Demo_ACM_LPF.m: -------------------------------------------------------------------------------- 1 | % The Matlab code of the paper 2 | % "K. Ding L. Xiao and G. Weng, Active Contours driven by Local Pre-Fitting Energy for Fast Image Segmentation, Pattern Recognition Letters, 104, 29-36, 2017." 3 | % Keyan Ding, 2018.02.12 4 | 5 | clc; clear all; close all; 6 | Img = imread('2.bmp'); 7 | Img = double(Img(:,:,1)); 8 | 9 | % -----set initial contour----- 10 | c0 = 1; 11 | initialLSF = ones(size(Img(:,:,1))).*c0; 12 | initialLSF(15:35,40:60) = -c0; 13 | 14 | % figure;imagesc(Img, [0, 255]); colormap(gray);hold on; axis off;axis equal; 15 | % text(6,6,'Left click to get points, right click to get end point','FontSize',[12],'Color', 'g'); 16 | % BW=roipoly; 17 | % hold off; 18 | % initialLSF=c0*2*(0.5-BW); 19 | 20 | % BW=im2bw(imread('mask.bmp'),0.5); 21 | % initialLSF=c0*2*(0.5-BW); 22 | 23 | u = initialLSF; 24 | h1 = figure(1);imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 25 | contour(initialLSF,[0 0],'g','linewidth',1.5);hold off 26 | pause(0.1); 27 | 28 | % -----set parameters----- 29 | mu = 1; % the distance regularization term 30 | nu = 0.01*255*255; % the length term. 31 | lambda1 = 1; 32 | lambda2 = lambda1; 33 | epsilon = 1.0; 34 | timestep = 0.02; 35 | iterNum = 200; % the number of iterations. 36 | sigma = 2; % control the local size 37 | 38 | % --- Local pre-fitting functions --- 39 | K=fspecial('gaussian',round(2*sigma)*2+1,sigma); 40 | [f1,f2,Im]=LPF(Img,K); 41 | e1=Img.*Img.*imfilter(ones(size(Img)),K,'replicate')-2.*Img.*imfilter(f1,K,'replicate')+imfilter(f1.^2,K,'replicate'); 42 | e2=Img.*Img.*imfilter(ones(size(Img)),K,'replicate')-2.*Img.*imfilter(f2,K,'replicate')+imfilter(f2.^2,K,'replicate'); 43 | % e1=(Img-f1).^2; 44 | % e2=(Img-f2).^2; 45 | 46 | %------color image segmentation------ 47 | % Img = double(Img); 48 | % for i = 1:3 49 | % [f1,f2,Im]=LPF(Img(:,:,i),K); 50 | % e1(:,:,i)=Img(:,:,i).*Img(:,:,i).*imfilter(ones(size(Img(:,:,i))),K,'replicate')-2.*Img(:,:,i).*imfilter(f1,K,'replicate')+imfilter(f1.^2,K,'replicate'); 51 | % e2(:,:,i)=Img(:,:,i).*Img(:,:,i).*imfilter(ones(size(Img(:,:,i))),K,'replicate')-2.*Img(:,:,i).*imfilter(f2,K,'replicate')+imfilter(f2.^2,K,'replicate'); 52 | % end 53 | % e1=-(e1(:,:,1)+e1(:,:,2)+e1(:,:,3))./3; 54 | % e2=-(e2(:,:,1)+e2(:,:,2)+e2(:,:,3))./3; 55 | 56 | % -----start level set evolution----- 57 | h2=figure(2); 58 | tic 59 | for n=1:iterNum 60 | u = ACM_LPF(u,nu,timestep,mu,epsilon,lambda1,lambda2,e1,e2); 61 | if mod(n,10)==0 62 | imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 63 | contour(u,[0 0],'r'); title([num2str(n), ' iterations ']); 64 | hold off;pause(.01); 65 | end 66 | end 67 | toc 68 | 69 | % -----display result----- 70 | imagesc(Img, [0, 255]);colormap(gray);hold on;axis off,axis equal 71 | [c,h] = contour(u,[0 0],'r','linewidth',1.5); 72 | % figure;mesh(u);colorbar;title('Final level set function');hold on, contour(u,[0 0],'r','linewidth',1.5); 73 | 74 | -------------------------------------------------------------------------------- /Local Pre-fitting/LPF.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Local Pre-fitting/LPF.m -------------------------------------------------------------------------------- /LocalizedActiveContour/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LocalizedActiveContour/1.bmp -------------------------------------------------------------------------------- /LocalizedActiveContour/2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LocalizedActiveContour/2.bmp -------------------------------------------------------------------------------- /LocalizedActiveContour/3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LocalizedActiveContour/3.bmp -------------------------------------------------------------------------------- /LocalizedActiveContour/Demo_LAC.m: -------------------------------------------------------------------------------- 1 | % This Matlab file calls two localized active contour methods proposed by 2 | % Shawn Lankton's IEEE TIP 2008 paper 'Localizing Region-Based Active 3 | % Contours'. 4 | % function local_AC_UM is the localized Chan-Vese's method see TIP 2001. 5 | % function local_AC_MS is the localized Antony's Mean Separation method see ICCV 1999 6 | % 7 | % The image used in this script are from Chunming Li (http://www.engr.uconn.edu/~cmli/) 8 | 9 | clc;clear all;close all; 10 | imgID = 2; % 1,2,3 % choose one of the five test images 11 | 12 | Img = imread([num2str(imgID),'.bmp']); 13 | Img = double(Img(:,:,1)); 14 | epsilon = 1; 15 | switch imgID 16 | 17 | case 1 18 | num_it =1000; 19 | rad = 8; 20 | alpha = 0.3;% coefficient of the length term 21 | mask_init = zeros(size(Img(:,:,1))); 22 | mask_init(15:78,32:95) = 1; 23 | seg = local_AC_MS(Img,mask_init,rad,alpha,num_it,epsilon); 24 | case 2 25 | num_it =800; 26 | rad = 9; 27 | alpha = 0.003;% coefficient of the length term 28 | mask_init = zeros(size(Img(:,:,1))); 29 | mask_init(53:77,56:70) = 1; 30 | seg = local_AC_UM(Img,mask_init,rad,alpha,num_it,epsilon); 31 | case 3 32 | num_it = 1500; 33 | rad = 5; 34 | alpha = 0.001;% coefficient of the length term 35 | mask_init = zeros(size(Img(:,:,1))); 36 | mask_init(47:80,86:99) = 1; 37 | seg = local_AC_UM(Img,mask_init,rad,alpha,num_it,epsilon); 38 | end 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /LocalizedActiveContour/local_AC_MS.m: -------------------------------------------------------------------------------- 1 | function seg = local_AC_MS(Img,mask_init,rad,alpha,num_it,epsilon) 2 | % This function aims to implement Shawn Lankton's local active contour. And 3 | % the energy model is the MS model as defined in eq.(15)-(19). 4 | % The local variables are calculated by filtering operation instead of 5 | % iterating inspired by Chunming Li's IEEE TIP 2008 paper 6 | % 7 | % One small change is that I used a square window instead of disk for 8 | % localization 9 | % 10 | % Input: 11 | % 1. Img: image needs to be segmented 12 | % 2. mask_init: intialization represented by binary image 13 | % 3. rad: the side length of the square window 14 | % 4. alpha: the coeficicent to balance the image fidality term and the 15 | % curvature regularization term 16 | % 5. num_it: maximum number of iterations 17 | % 6. epsilon: epsilon used for delta and heaviside function 18 | % Created by Jincheng Pang, Tufts University @11/09/2012 19 | 20 | phi0 = mask2phi(mask_init); 21 | phi = phi0; 22 | 23 | B0 = ones(2*rad+1,2*rad+1); 24 | % B0 = fspecial('disk',rad); 25 | 26 | KI=conv2(Img,B0,'same'); 27 | KONE=conv2(ones(size(Img)),B0,'same'); 28 | 29 | 30 | for ii = 1:num_it 31 | mask = Heaviside2(phi,epsilon); 32 | 33 | I=Img.*mask; 34 | temp1=conv2(mask,B0,'same'); 35 | temp2=conv2(I,B0,'same'); 36 | c1=temp2./(temp1); % local mean value inside 37 | c2=(KI-temp2)./(KONE-temp1); % local mean value outside 38 | 39 | A1 = temp1; 40 | A2 = conv2(1-mask,B0,'same'); 41 | %%%%% 42 | D = (A1.*A2+eps); 43 | term1 = (A2-A1)./D; 44 | term2 = (A2.*c1.^2-A1.*c2.^2)./D; 45 | term3 = (A2.*c1-A1.*c2)./D; 46 | dataForce = conv2(term1.*Dirac2(phi,epsilon),B0,'same').*Img.*Img + conv2(term2.*Dirac2(phi,epsilon),B0,'same')-2.*Img.*conv2(term3.*Dirac2(phi,epsilon),B0,'same'); %%% During the implementation, Img should be separated out of the filtering operation!!! 47 | % dataForce = conv2(term1.*Dirac2(phi,epsilon).*Img.^2,B0,'same') + conv2(term2.*Dirac2(phi,epsilon),B0,'same')-2.*conv2(term3.*Dirac2(phi,epsilon).*Img,B0,'same'); 48 | dataForce = dataForce/max(abs(dataForce(:))); 49 | % % curvature = get_curvature1(phi); 50 | curvature = curvature_central(phi); 51 | dphi = Dirac2(phi,epsilon).*(-dataForce + alpha*curvature); 52 | 53 | dt = .48/(max(abs(dphi(:)))+eps); 54 | 55 | %-- evolve the curve 56 | phi = phi + dt.*dphi; 57 | 58 | %-- Keep SDF smooth 59 | phi = sussman(phi, .5); 60 | 61 | if(mod(ii,10) == 0) 62 | showCurveAndPhi(Img,phi,ii); 63 | end 64 | end 65 | 66 | seg = (phi>=0); 67 | 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | %%%%%%%%%%%%%%%%Auxiliary functions %%%%%%%%%%%%%%%%%%% 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 | %-- level set re-initialization by the sussman method 72 | function D = sussman(D, dt) 73 | % forward/backward differences 74 | a = D - shiftR(D); % backward 75 | b = shiftL(D) - D; % forward 76 | c = D - shiftD(D); % backward 77 | d = shiftU(D) - D; % forward 78 | 79 | a_p = a; a_n = a; % a+ and a- 80 | b_p = b; b_n = b; 81 | c_p = c; c_n = c; 82 | d_p = d; d_n = d; 83 | 84 | a_p(a < 0) = 0; 85 | a_n(a > 0) = 0; 86 | b_p(b < 0) = 0; 87 | b_n(b > 0) = 0; 88 | c_p(c < 0) = 0; 89 | c_n(c > 0) = 0; 90 | d_p(d < 0) = 0; 91 | d_n(d > 0) = 0; 92 | 93 | dD = zeros(size(D)); 94 | D_neg_ind = find(D < 0); 95 | D_pos_ind = find(D > 0); 96 | dD(D_pos_ind) = sqrt(max(a_p(D_pos_ind).^2, b_n(D_pos_ind).^2) ... 97 | + max(c_p(D_pos_ind).^2, d_n(D_pos_ind).^2)) - 1; 98 | dD(D_neg_ind) = sqrt(max(a_n(D_neg_ind).^2, b_p(D_neg_ind).^2) ... 99 | + max(c_n(D_neg_ind).^2, d_p(D_neg_ind).^2)) - 1; 100 | 101 | D = D - dt .* sussman_sign(D) .* dD; 102 | 103 | %-- whole matrix derivatives 104 | function shift = shiftD(M) 105 | shift = shiftR(M')'; 106 | 107 | function shift = shiftL(M) 108 | shift = [ M(:,2:size(M,2)) M(:,size(M,2)) ]; 109 | 110 | function shift = shiftR(M) 111 | shift = [ M(:,1) M(:,1:size(M,2)-1) ]; 112 | 113 | function shift = shiftU(M) 114 | shift = shiftL(M')'; 115 | 116 | function S = sussman_sign(D) 117 | S = D ./ sqrt(D.^2 + 1); 118 | 119 | function phi = mask2phi(init_a) 120 | % Modified by Jincheng Pang to reverse the phi function; 121 | % 122 | %-- converts a mask to a SDF 123 | phi=bwdist(init_a)-bwdist(1-init_a)+im2double(init_a)-.5; 124 | phi = -double(phi); % modified by Jincheng Pang 04/20/2012 125 | 126 | 127 | function showCurveAndPhi(I, phi, i) 128 | imshow(I,'initialmagnification',200,'displayrange',[ ]); 129 | % % imagesc(xx,yy,I);axis square;axis xy 130 | hold on; contour(phi, [0 0], 'y','LineWidth',2); 131 | % contour(phi, [0 0], 'k','LineWidth',4); 132 | hold off; title([num2str(i) ' Iterations']); drawnow; 133 | 134 | function f = Dirac2(x, sigma) 135 | % % f=(1/2/sigma)*(1+cos(pi*x/sigma)); 136 | % % b = (x<=sigma) & (x>=-sigma); 137 | % % f = f.*b; 138 | f = (sigma/pi)./(sigma^2+x.^2); 139 | 140 | function f = Heaviside2(x, epsilon) % Use Heaviside_{2,epsilon} as denoted in Chan-Vese's TIP Paper. 141 | 142 | f = 0.5*(1+2/pi*atan(x./epsilon)); 143 | 144 | function k = curvature_central(u) 145 | % compute curvature 146 | [ux,uy] = gradient(u); 147 | normDu = sqrt(ux.^2+uy.^2+1e-10); % the norm of the gradient plus a small possitive number 148 | % to avoid division by zero in the following computation. 149 | Nx = ux./normDu; 150 | Ny = uy./normDu; 151 | [nxx,junk] = gradient(Nx); 152 | [junk,nyy] = gradient(Ny); 153 | k = nxx+nyy; % compute divergence -------------------------------------------------------------------------------- /LocalizedActiveContour/local_AC_UM.m: -------------------------------------------------------------------------------- 1 | function seg = local_AC_UM(Img,mask_init,rad,alpha,num_it,epsilon) 2 | % This function aims to implement Shawn Lankton's local active contour. And 3 | % the energy model is the UM model as defined in eq.(11)-(14). 4 | % The local variables are calculated by filtering operation instead of 5 | % iterating inspired by Chunming Li's IEEE TIP 2008 paper 6 | % 7 | % One small change is that I used a square window instead of disk for 8 | % localization 9 | % 10 | % Input: 11 | % 1. Img: image needs to be segmented 12 | % 2. mask_init: intialization represented by binary image 13 | % 3. rad: the side length of the square window 14 | % 4. alpha: the coeficicent to balance the image fidality term and the 15 | % curvature regularization term 16 | % 5. num_it: maximum number of iterations 17 | % 6. epsilon: epsilon used for delta and heaviside function 18 | % Created by Jincheng Pang, Tufts University @11/09/2012 19 | 20 | phi0 = mask2phi(mask_init); 21 | phi = phi0; 22 | 23 | B0 = ones(2*rad+1,2*rad+1); 24 | % B0 = fspecial('disk',rad); 25 | 26 | KI=conv2(Img,B0,'same'); 27 | KONE=conv2(ones(size(Img)),B0,'same'); 28 | 29 | 30 | for ii = 1:num_it 31 | mask = Heaviside2(phi,epsilon); 32 | 33 | I=Img.*mask; 34 | temp1=conv2(mask,B0,'same'); 35 | temp2=conv2(I,B0,'same'); 36 | c1=temp2./(temp1); % local mean value inside 37 | c2=(KI-temp2)./(KONE-temp1); % local mean value outside 38 | 39 | %%%%%% 40 | s1=(c1.^2-c2.^2).*Dirac2(phi,epsilon); % Compute the 1st term in eq. (14) in Lankton's IEEE TIP 08 41 | s2=(c1-c2).*Dirac2(phi,epsilon); 42 | dataForce=conv2(s1,B0,'same')-2.*Img.*conv2(s2,B0,'same'); %%% During the implementation, Img should be separated out of the filtering operation!!! 43 | % dataForce=conv2(s1,B0,'same')-2.*conv2(s2.*Img,B0,'same'); %%% During the implementation, Img should be separated out of the filtering operation!!! 44 | dataForce = dataForce/max(abs(dataForce(:))); 45 | %%%%%% 46 | % curvature = get_curvature1(phi); 47 | curvature = curvature_central(phi); 48 | dphi = Dirac2(phi,epsilon).*(-dataForce + alpha*curvature); 49 | 50 | dt = .48/(max(abs(dphi(:)))+eps); 51 | 52 | %-- evolve the curve 53 | phi = phi + dt.*dphi; 54 | 55 | %-- Keep SDF smooth 56 | phi = sussman(phi, .5); 57 | 58 | if(mod(ii,10) == 0) 59 | showCurveAndPhi(Img,phi,ii); 60 | end 61 | end 62 | 63 | seg = (phi>=0); 64 | 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | %%%%%%%%%%%%%%%%Auxiliary functions %%%%%%%%%%%%%%%%%%% 67 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 68 | %-- level set re-initialization by the sussman method 69 | function D = sussman(D, dt) 70 | % forward/backward differences 71 | a = D - shiftR(D); % backward 72 | b = shiftL(D) - D; % forward 73 | c = D - shiftD(D); % backward 74 | d = shiftU(D) - D; % forward 75 | 76 | a_p = a; a_n = a; % a+ and a- 77 | b_p = b; b_n = b; 78 | c_p = c; c_n = c; 79 | d_p = d; d_n = d; 80 | 81 | a_p(a < 0) = 0; 82 | a_n(a > 0) = 0; 83 | b_p(b < 0) = 0; 84 | b_n(b > 0) = 0; 85 | c_p(c < 0) = 0; 86 | c_n(c > 0) = 0; 87 | d_p(d < 0) = 0; 88 | d_n(d > 0) = 0; 89 | 90 | dD = zeros(size(D)); 91 | D_neg_ind = find(D < 0); 92 | D_pos_ind = find(D > 0); 93 | dD(D_pos_ind) = sqrt(max(a_p(D_pos_ind).^2, b_n(D_pos_ind).^2) ... 94 | + max(c_p(D_pos_ind).^2, d_n(D_pos_ind).^2)) - 1; 95 | dD(D_neg_ind) = sqrt(max(a_n(D_neg_ind).^2, b_p(D_neg_ind).^2) ... 96 | + max(c_n(D_neg_ind).^2, d_p(D_neg_ind).^2)) - 1; 97 | 98 | D = D - dt .* sussman_sign(D) .* dD; 99 | 100 | %-- whole matrix derivatives 101 | function shift = shiftD(M) 102 | shift = shiftR(M')'; 103 | 104 | function shift = shiftL(M) 105 | shift = [ M(:,2:size(M,2)) M(:,size(M,2)) ]; 106 | 107 | function shift = shiftR(M) 108 | shift = [ M(:,1) M(:,1:size(M,2)-1) ]; 109 | 110 | function shift = shiftU(M) 111 | shift = shiftL(M')'; 112 | 113 | function S = sussman_sign(D) 114 | S = D ./ sqrt(D.^2 + 1); 115 | 116 | function phi = mask2phi(init_a) 117 | % Modified by Jincheng Pang to reverse the phi function; 118 | % 119 | %-- converts a mask to a SDF 120 | phi=bwdist(init_a)-bwdist(1-init_a)+im2double(init_a)-.5; 121 | phi = -double(phi); % modified by Jincheng Pang 04/20/2012 122 | 123 | 124 | function showCurveAndPhi(I, phi, i) 125 | imshow(I,'initialmagnification',200,'displayrange',[ ]); 126 | % % imagesc(xx,yy,I);axis square;axis xy 127 | hold on; contour(phi, [0 0], 'y','LineWidth',2); 128 | % contour(phi, [0 0], 'k','LineWidth',4); 129 | hold off; title([num2str(i) ' Iterations']); drawnow; 130 | 131 | function f = Dirac2(x, sigma) 132 | % % f=(1/2/sigma)*(1+cos(pi*x/sigma)); 133 | % % b = (x<=sigma) & (x>=-sigma); 134 | % % f = f.*b; 135 | f = (sigma/pi)./(sigma^2+x.^2); 136 | 137 | function f = Heaviside2(x, epsilon) % Use Heaviside_{2,epsilon} as denoted in Chan-Vese's TIP Paper. 138 | 139 | f = 0.5*(1+2/pi*atan(x./epsilon)); 140 | 141 | function k = curvature_central(u) 142 | % compute curvature 143 | [ux,uy] = gradient(u); 144 | normDu = sqrt(ux.^2+uy.^2+1e-10); % the norm of the gradient plus a small possitive number 145 | % to avoid division by zero in the following computation. 146 | Nx = ux./normDu; 147 | Ny = uy./normDu; 148 | [nxx,junk] = gradient(Nx); 149 | [junk,nyy] = gradient(Ny); 150 | k = nxx+nyy; % compute divergence -------------------------------------------------------------------------------- /LocalizedActiveContour/readme.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, 2 | Jincheng Pang @ ECE Department, Tufts University 3 | jinchengpang@gmail.com 4 | All Rights Reserved, 2012 5 | How to use? 6 | The file Demo_LAC could be run directly. -------------------------------------------------------------------------------- /LocalizedActiveContour/results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/LocalizedActiveContour/results.png -------------------------------------------------------------------------------- /Multiphase_CV/A Multiphase Level Set Framework for Image Segmentation__Using the Mumford and Shah Model.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Multiphase_CV/A Multiphase Level Set Framework for Image Segmentation__Using the Mumford and Shah Model.pdf -------------------------------------------------------------------------------- /Multiphase_CV/CURVATURE_CV.m: -------------------------------------------------------------------------------- 1 | function K = CURVATURE_CV(f,diff_scheme) 2 | % K = CURVATURE_CV(f,diff_scheme) computes curvature 3 | % Copyright (c) 2001--2006 by Chunming Li 4 | % Author: Chunming Li, 11/02/2003 5 | % Revision by Chunming Li 8/18/2006 6 | 7 | epsilon=1e-10; 8 | 9 | if diff_scheme == 0 % the scheme in Chan and Vese's paper 10 | [fx,fy]=gradient(f); % central difference 11 | fx_f = forward_gradient(f); 12 | ax = fx_f./sqrt(fx_f.^2+ fy.^2+epsilon); 13 | axx = backward_gradient(ax); 14 | fy_f = forward_gradient(f); 15 | ay = fy_f./sqrt(fx.^2 + fy_f.^2 + epsilon); 16 | ayy = backward_gradient(ay); 17 | K = axx + ayy; 18 | 19 | elseif diff_scheme == 1 % forward difference followed by a backward difference 20 | 21 | fx_f = Dx_forward(f); 22 | fy_f = Dy_forward(f); 23 | ax = fx_f./sqrt(fx_f.^2+ fy_f.^2+epsilon); 24 | ay = fy_f./sqrt(fx_f.^2 + fy_f.^2 + epsilon); 25 | axx = Dx_backward(ax); 26 | ayy = Dy_backward(ay); 27 | K = axx + ayy; 28 | elseif diff_scheme == 2 % central difference followed by a central difference 29 | [fx, fy]= gradient(f); % central difference 30 | ax = fx./sqrt(fx.^2+ fy.^2+epsilon); 31 | ay = fy./sqrt(fx.^2 + fy.^2 + epsilon); 32 | [axx, axy] = gradient(ax); % central difference 33 | [ayx, ayy] = gradient(ay); 34 | K = axx + ayy; 35 | else 36 | disp('Wrong difference scheme: CURVATURE_CV.m'); 37 | return; 38 | end 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Multiphase_CV/Delta.m: -------------------------------------------------------------------------------- 1 | function Delta_h = Delta(phi, epsilon) 2 | % Delta(phi, epsilon) compute the smooth Dirac function 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | 9 | Delta_h=(epsilon/pi)./(epsilon^2+ phi.^2); -------------------------------------------------------------------------------- /Multiphase_CV/Demo_multiphase_improved.m: -------------------------------------------------------------------------------- 1 | % This code implements the improved Vese-Chan multiphase level set 2 | % model in [1] with modification by adding the distance regularizing (DR) term 3 | % introduced in Li et al's paper [2]. 4 | % 5 | % Reference: 6 | % [1] A Multiphase Level Set Framework for Image Segmentation Using the Mumford and Shah Model, IJCV 2002. 7 | % [2] Level Set Evolution Without Reinitialization: A New Variational Formulation", CVPR 2005. 8 | % 9 | % Although reinitialization in Vese and Chan's original level set methods 10 | % is not required for all images, the level set function can still be 11 | % degraded after a certain number of iterations. This not only causes the curve irregular, but also slow down 12 | % the curve evolution.By adding the distance regularizing term (the internal energy)in Li's level set method [2], 13 | % the need for reinitialization is completely eliminated, and the level set function is smooth during the 14 | % evolution, which ensure more accurate computation. 15 | % 16 | % Note that the distance regularizing term has an effect of maintaining the level set function as an approximate 17 | % signed distance function near the zero level set. 18 | % 19 | % Note: There may be more sophiscated numerical schemes with better performance than the one in 20 | % this implementation. We only use a simple difference scheme in this version to demonstrate the desirable 21 | % distance regularizing effect. 22 | % Author: Chunming Li 23 | 24 | clear; 25 | delta_t = .1; 26 | lambda_1=1; 27 | lambda_2=1; 28 | h = 1; 29 | epsilon=1; 30 | nu = .001*255*255; 31 | fun_n=2; % two level set functions for 4 phase level set formulation 32 | 33 | Img=imread('fourblock_gray.bmp'); 34 | U=Img(:,:,1); 35 | 36 | % get the size 37 | [nrow, ncol] =size(U); 38 | 39 | ic=nrow/2; 40 | jc=ncol/2; 41 | r=30; 42 | phi = initial_sdf2circle(nrow,ncol,ic,jc,r,fun_n); 43 | I=double(U); 44 | 45 | figure; 46 | imagesc(uint8(I));colormap(gray) 47 | hold on; 48 | plotLevelSet(phi(:,:,1),0,'r'); 49 | plotLevelSet(phi(:,:,2),0,'b'); 50 | 51 | numIter = 10; 52 | 53 | for k=1:70 54 | mu=0.5; % coefficient for the distance regularizing term (internal energy) in Li's CVPR05 paper 55 | phi=EVOLUTION_4PHASE_DR(I, phi, nu, lambda_1, lambda_2, mu, delta_t, epsilon, numIter); % update level set function 56 | if mod(k,2)==0 57 | pause(.1); 58 | imagesc(uint8(I));colormap(gray) 59 | hold on; 60 | phi_1=phi(:,:,1); 61 | phi_2=phi(:,:,2); 62 | plotLevelSet(phi_1,0,'r'); 63 | plotLevelSet(phi_2,0,'b'); 64 | hold off; 65 | end 66 | end 67 | figure;mesh(phi_1); 68 | title('\phi_1, improved Vese-Chan model by Li'); 69 | figure;mesh(phi_2); 70 | title('\phi_2, improved Vese-Chan model by Li'); -------------------------------------------------------------------------------- /Multiphase_CV/Demo_multiphase_original.m: -------------------------------------------------------------------------------- 1 | % This code implements the Vese-Chan multiphase level set model in [1]. 2 | % Note: There may be more sophiscated numerical schemes with better performance than the one in 3 | % this implementation. 4 | % 5 | % Reference: 6 | % [1] A Multiphase Level Set Framework for Image Segmentation Using the Mumford and Shah Model, IJCV 2002. 7 | 8 | clear; 9 | delta_t = .1; 10 | lambda_1=1; 11 | lambda_2=1; 12 | h = 1; 13 | epsilon=1; 14 | nu = .001*255*255; 15 | fun_n=2; % two level set functions for 4 phase level set formulation 16 | 17 | Img=imread('fourblock_gray.bmp'); 18 | U=Img(:,:,1); 19 | 20 | % get the size 21 | [nrow, ncol] =size(U); 22 | 23 | ic=nrow/2; 24 | jc=ncol/2; 25 | r=30; 26 | phi = initial_sdf2circle(nrow,ncol,ic,jc,r,fun_n); 27 | I=double(U); 28 | 29 | figure; 30 | imagesc(uint8(I));colormap(gray) 31 | hold on; 32 | plotLevelSet(phi(:,:,1),0,'r'); 33 | plotLevelSet(phi(:,:,2),0,'b'); 34 | 35 | numIter = 10; 36 | 37 | for k=1:120 38 | phi=EVOLUTION_4PHASE(I, phi, nu, lambda_1, lambda_2, delta_t, epsilon, numIter); % update level set function 39 | if mod(k,2)==0 40 | pause(.1); 41 | imagesc(uint8(I));colormap(gray) 42 | hold on; 43 | phi_1=phi(:,:,1); 44 | phi_2=phi(:,:,2); 45 | plotLevelSet(phi_1,0,'r'); 46 | plotLevelSet(phi_2,0,'b'); 47 | hold off; 48 | end 49 | end 50 | figure;mesh(phi_1); 51 | title('\phi_1, Vese-Chan model'); 52 | figure;mesh(phi_2); 53 | title('\phi_2, Vese-Chan model'); -------------------------------------------------------------------------------- /Multiphase_CV/EVOLUTION_4PHASE.m: -------------------------------------------------------------------------------- 1 | function phi = EVOLUTION_4PHASE(I, phi0, nu, lambda_1, lambda_2, delta_t, epsilon, numIter); 2 | % This function updates the level set function in the Vese-Chan multiphase level set 3 | % model in [1]. 4 | % 5 | % Reference: 6 | % [1] A Multiphase Level Set Framework for Image Segmentation Using the Mumford and Shah Model, IJCV 2002. 7 | % 8 | % created on 01/20/2006 by Chunming Li and Lu Li 9 | % author: Chunming Li and Lu Li 10 | % email: li_chunming@hotmail.com 11 | % Homepage: 12 | % http://www.vuiis.vanderbilt.edu/~licm/ 13 | % http://www.engr.uconn.edu/~cmli 14 | % Copyright (c) 2004-2008 by Chunming Li and Lu Li 15 | 16 | phi(:,:,1)=phi0(:,:,1); 17 | phi(:,:,2)=phi0(:,:,2); 18 | 19 | for m=1:numIter 20 | for k=1:2 21 | tmp_phi=phi(:,:,k); 22 | tmp_phi=NeumannBoundCond(tmp_phi); 23 | delta_h=Delta(tmp_phi,epsilon); 24 | differenceScheme=0; % use 0, 1, 2 for different schemes to compute curvature 25 | Curv = CURVATURE_CV(tmp_phi,differenceScheme); 26 | [C,mult]=quadrifit(phi,I,epsilon,2); 27 | b=zeros(size(Curv)); 28 | 29 | if k==1 30 | b=(C(1)-C(2))*(C(1)+C(2)-2*I).*mult(:,:,1,1); 31 | b=b+(C(3)-C(4))*(C(3)+C(4)-2*I).*mult(:,:,1,2); 32 | else 33 | b=(C(1)-C(3))*(C(1)+C(3)-2*I).*mult(:,:,2,1); 34 | b=b+(C(2)-C(4))*(C(2)+C(4)-2*I).*mult(:,:,2,2); 35 | end 36 | tmp_phi=tmp_phi+delta_t*(delta_h.*(nu*Curv+b)); 37 | phi(:,:,k)=tmp_phi; 38 | end 39 | end 40 | 41 | function g = NeumannBoundCond(f) 42 | % Make a function satisfy Neumann boundary condition 43 | [nrow,ncol] = size(f); 44 | g = f; 45 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 46 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 47 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /Multiphase_CV/EVOLUTION_4PHASE_DR.asv: -------------------------------------------------------------------------------- 1 | function phi = EVOLUTION_4PHASE_DR(I, phi0, nu, lambda_1, lambda_2, mu, delta_t, epsilon, numIter); 2 | % 3 | % This function updates the level set function in the improved Vese-Chan multiphase level set 4 | % model in [1] by adding the distance regularizing term introduced in Li et al's paper [2]. 5 | % 6 | % Reference: 7 | % [1] A Multiphase Level Set Framework for Image Segmentation Using the Mumford and Shah Model, IJCV 2002. 8 | % [2] Level Set Evolution Without Reinitialization: A New Variational Formulation", CVPR 2005. 9 | % 10 | % created on 01/20/2006 by Chunming Li and Lu Li 11 | % author: Chunming Li and Lu Li 12 | % email: li_chunming@hotmail.com 13 | % Homepage: 14 | % http://www.vuiis.vanderbilt.edu/~licm/ 15 | % http://www.engr.uconn.edu/~cmli 16 | % Copyright (c) 2004-2008 by Chunming Li and Lu Li 17 | 18 | phi(:,:,1)=phi0(:,:,1); 19 | phi(:,:,2)=phi0(:,:,2); 20 | 21 | for m=1:numIter 22 | for k=1:2 23 | tmp_phi=phi(:,:,k); 24 | tmp_phi=NeumannBoundCond(tmp_phi); 25 | delta_h=Delta(tmp_phi,epsilon); 26 | differenceScheme=0; % choo 27 | Curv = CURVATURE_CV(tmp_phi,differenceScheme); 28 | [C,mult]=quadrifit(phi,I,epsilon,2); 29 | b=zeros(size(Curv)); 30 | 31 | if k==1 32 | b=(C(1)-C(2))*(C(1)+C(2)-2*I).*mult(:,:,1,1); 33 | b=b+(C(3)-C(4))*(C(3)+C(4)-2*I).*mult(:,:,1,2); 34 | else 35 | b=(C(1)-C(3))*(C(1)+C(3)-2*I).*mult(:,:,2,1); 36 | b=b+(C(2)-C(4))*(C(2)+C(4)-2*I).*mult(:,:,2,2); 37 | end 38 | tmp_phi=tmp_phi+delta_t*(delta_h.*(nu*Curv+b) + mu*(4*del2(tmp_phi)-Curv)); % the last term is the distance regularizing term in Li's CVPR05 paper 39 | phi(:,:,k)=tmp_phi; 40 | end 41 | end 42 | 43 | function g = NeumannBoundCond(f) 44 | % Make a function satisfy Neumann boundary condition 45 | [nrow,ncol] = size(f); 46 | g = f; 47 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 48 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 49 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /Multiphase_CV/EVOLUTION_4PHASE_DR.m: -------------------------------------------------------------------------------- 1 | function phi = EVOLUTION_4PHASE_DR(I, phi0, nu, lambda_1, lambda_2, mu, delta_t, epsilon, numIter); 2 | % 3 | % This function updates the level set function in the improved Vese-Chan multiphase level set 4 | % model in [1] by adding the distance regularizing term introduced in Li et al's paper [2]. 5 | % 6 | % Reference: 7 | % [1] A Multiphase Level Set Framework for Image Segmentation Using the Mumford and Shah Model, IJCV 2002. 8 | % [2] Level Set Evolution Without Reinitialization: A New Variational Formulation", CVPR 2005. 9 | % 10 | % created on 01/20/2006 by Chunming Li and Lu Li 11 | % author: Chunming Li and Lu Li 12 | % email: li_chunming@hotmail.com 13 | % Homepage: 14 | % http://www.vuiis.vanderbilt.edu/~licm/ 15 | % http://www.engr.uconn.edu/~cmli 16 | % Copyright (c) 2004-2008 by Chunming Li and Lu Li 17 | 18 | phi(:,:,1)=phi0(:,:,1); 19 | phi(:,:,2)=phi0(:,:,2); 20 | 21 | for m=1:numIter 22 | for k=1:2 23 | tmp_phi=phi(:,:,k); 24 | tmp_phi=NeumannBoundCond(tmp_phi); 25 | delta_h=Delta(tmp_phi,epsilon); 26 | differenceScheme=0; % use 0, 1, 2 for different schemes to compute curvature 27 | Curv = CURVATURE_CV(tmp_phi,differenceScheme); 28 | [C,mult]=quadrifit(phi,I,epsilon,2); 29 | b=zeros(size(Curv)); 30 | 31 | if k==1 32 | b=(C(1)-C(2))*(C(1)+C(2)-2*I).*mult(:,:,1,1); 33 | b=b+(C(3)-C(4))*(C(3)+C(4)-2*I).*mult(:,:,1,2); 34 | else 35 | b=(C(1)-C(3))*(C(1)+C(3)-2*I).*mult(:,:,2,1); 36 | b=b+(C(2)-C(4))*(C(2)+C(4)-2*I).*mult(:,:,2,2); 37 | end 38 | tmp_phi=tmp_phi+delta_t*(delta_h.*(nu*Curv+b) + mu*(4*del2(tmp_phi)-Curv)); % the last term is the distance regularizing term in Li's CVPR05 paper 39 | phi(:,:,k)=tmp_phi; 40 | end 41 | end 42 | 43 | function g = NeumannBoundCond(f) 44 | % Make a function satisfy Neumann boundary condition 45 | [nrow,ncol] = size(f); 46 | g = f; 47 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 48 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 49 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); -------------------------------------------------------------------------------- /Multiphase_CV/Heaviside.m: -------------------------------------------------------------------------------- 1 | function H = Heaviside(phi,epsilon) 2 | % Heaviside(phi,epsilon) compute the smooth Heaviside function 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | H = 0.5*(1+ (2/pi)*atan(phi./epsilon)); -------------------------------------------------------------------------------- /Multiphase_CV/backward_gradient.m: -------------------------------------------------------------------------------- 1 | function [bdy,bdx]=backward_gradient(f); 2 | % function [bdx,bdy]=backward_gradient(f); 3 | % 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | [nr,nc]=size(f); 9 | bdx=zeros(nr,nc); 10 | bdy=zeros(nr,nc); 11 | 12 | bdx(2:nr,:)=f(2:nr,:)-f(1:nr-1,:); 13 | bdy(:,2:nc)=f(:,2:nc)-f(:,1:nc-1); -------------------------------------------------------------------------------- /Multiphase_CV/forward_gradient.m: -------------------------------------------------------------------------------- 1 | function [fdy,fdx]=forward_gradient(f); 2 | % function [fdx,fdy]=forward_gradient(f); 3 | [nr,nc]=size(f); 4 | fdx=zeros(nr,nc); 5 | fdy=zeros(nr,nc); 6 | 7 | a=f(2:nr,:)-f(1:nr-1,:); 8 | fdx(1:nr-1,:)=a; 9 | b=f(:,2:nc)-f(:,1:nc-1); 10 | fdy(:,1:nc-1)=b; 11 | -------------------------------------------------------------------------------- /Multiphase_CV/fourblock_gray.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Multiphase_CV/fourblock_gray.bmp -------------------------------------------------------------------------------- /Multiphase_CV/get_contour.m: -------------------------------------------------------------------------------- 1 | %/* this function computes the phi required initially */ 2 | function [xcontour, ycontour] = get_phi(I, nrow, ncol,margin) 3 | % I is the image matrix 4 | % nrow is the no of rows 5 | % ncol is the no of columns 6 | 7 | 8 | count=1; 9 | x=margin; 10 | for y=margin:nrow-margin+1, 11 | xcontour(count) = x; 12 | ycontour(count) = y; 13 | count=count+1; 14 | end; 15 | y=nrow-margin+1; 16 | for x=margin+1:ncol-margin+1, 17 | xcontour(count) = x; 18 | ycontour(count) = y; 19 | count=count+1; 20 | end; 21 | 22 | x=ncol-margin+1; 23 | for y=nrow-margin:-1:margin, 24 | xcontour(count) = x; 25 | ycontour(count) = y; 26 | count=count+1; 27 | end; 28 | 29 | y=margin; 30 | for x=ncol-margin:-1:margin+1, 31 | xcontour(count) = x; 32 | ycontour(count) = y; 33 | count=count+1; 34 | end; 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Multiphase_CV/initial_sdf2circle.m: -------------------------------------------------------------------------------- 1 | function f = initial_sdf2circle(nrow,ncol, ic,jc,r,fun_n) 2 | % sdf2circle(nrow,ncol, ic,jc,r) computes the signed distance to a circle 3 | % input: 4 | % nrow: number of rows 5 | % ncol: number of columns 6 | % (ic,jc): center of the circle 7 | % r: radius of the circle 8 | % output: 9 | % f: signed distance to the circle 10 | % 11 | % created on 04/26/2004 12 | % author: Chunming Li 13 | % email: li_chunming@hotmail.com 14 | % Copyright (c) 2004-2006 by Chunming Li 15 | [X,Y] = meshgrid(1:ncol, 1:nrow); 16 | a=5;b=6; 17 | f=ones(nrow,ncol,fun_n); 18 | for k=1:fun_n 19 | f(:,:,k) = -sqrt((X-k*jc/fun_n).^2+(Y-k*ic/fun_n).^2)+r/2; 20 | end 21 | 22 | %f=sdf2circle(100,50,51,25,10);figure;imagesc(f) -------------------------------------------------------------------------------- /Multiphase_CV/plotLevelSet.m: -------------------------------------------------------------------------------- 1 | function [c,h]=plotLevelSet(u,zLevel, style) 2 | % plotLevelSet(u,zLevel, style) plot the level contour of function u at 3 | % the zLevel. 4 | % created on 04/26/2004 5 | % author: Chunming Li 6 | % email: li_chunming@hotmail.com 7 | % Copyright (c) 2004-2006 by Chunming Li 8 | % hold on; 9 | [c,h] = contour(u,[zLevel zLevel],style); 10 | % hold off; -------------------------------------------------------------------------------- /Multiphase_CV/quadrifit.m: -------------------------------------------------------------------------------- 1 | function [C,mult]= quadrifit(phi,U,epsilon,fun_n) 2 | % quadrifit(phi,U,epsilon,fun_n) computes c1 c2 c3 c4for optimal binary fitting 3 | % created on 04/26/2004 4 | % author: Chunming Li & Lu Li 5 | % email: li_chunming@hotmail.com 6 | % Copyright (c) 2004-2008 by Chunming Li & Lu Li 7 | 8 | H = Heaviside(phi,epsilon); %compute the Heaveside function values 9 | s=size(H); 10 | M=2^fun_n; 11 | C=zeros(2^fun_n,1); 12 | a=zeros(size(H)); 13 | mult=ones(s(1),s(2),fun_n,M/2*(fun_n-1));%mult 14 | 15 | mult(:,:,1,1)=1-H(:,:,2);%1-H(phi(2)):c0 16 | mult(:,:,1,2)=H(:,:,2);%H(phi(2)):c1 17 | mult(:,:,2,1)=1-H(:,:,1);%1-H(phi(1)):c2 18 | mult(:,:,2,2)=H(:,:,1);%H(phi(1)):c3 19 | 20 | mult2=zeros(s(1),s(2),4);%numerator 21 | %%%phi-1,2,...n, c1...c2^n 22 | mult2(:,:,1)=(1-H(:,:,1)).*(1-H(:,:,2));%00 23 | mult2(:,:,2)=H(:,:,1).*(1-H(:,:,2));%01 24 | mult2(:,:,3)=(1-H(:,:,1)).*(H(:,:,2));%10 25 | mult2(:,:,4)=H(:,:,1).*H(:,:,2);%11 26 | mult3=mult2; 27 | for k=1:M 28 | mult2(:,:,k)= mult2(:,:,k).*U; 29 | end 30 | for k=1:M 31 | tmp1=mult3(:,:,k); 32 | tmp2=mult2(:,:,k); 33 | denum=sum(tmp1(:)); 34 | num=sum(tmp2(:)); 35 | C(k) = num/denum; 36 | end 37 | -------------------------------------------------------------------------------- /Narrow band/NarrowBand_DLL/Demo_nband.m: -------------------------------------------------------------------------------- 1 | % This Matlab file demomstrates a narrow band algorithm that implements the level set method in Li et al's paper 2 | % "Level Set Evolution Without Re-initialization: A New Variational Formulation" 3 | % in Proceedings of CVPR'05, vol. 1, pp. 430-436. 4 | % Author: Chunming Li, all rights reserved. 5 | % E-mail: li_chunming@hotmail.com 6 | % URL: http://www.engr.uconn.edu/~cmli/ 7 | 8 | clear all; 9 | close all; 10 | Img = imread('twoObjImg.bmp'); 11 | Img=double(Img(:,:,1)); 12 | sigma=1.5; % scale parameter in Gaussian kernel for smoothing. 13 | [nrow, ncol]=size(Img); 14 | total_time = 0; 15 | 16 | G=fspecial('gaussian',15,sigma); 17 | Img_smooth=conv2(Img,G,'same'); % smooth image by Gaussiin convolution 18 | [Ix,Iy]=gradient(Img_smooth); 19 | f=Ix.^2+Iy.^2; 20 | g=1./(1+f); % edge indicator function. 21 | [vx,vy] = gradient(g); 22 | tic; 23 | total_time = total_time + toc; 24 | epsilon=1.5; % the papramater in the definition of smoothed Dirac function 25 | 26 | N_iter=150; 27 | timestep=5; % time step 28 | mu=0.04; % coefficient of the internal (penalizing) energy term P(\phi) 29 | % Note: The product timestep*mu must be less than 0.25 for stable evolution 30 | DiracSigma=1.5; % the papramater in the definition of smoothed Dirac function 31 | lambda=5; % coefficient of the weighted length term Lg(\phi) 32 | alf=3; % coefficient of the weighted area term Ag(\phi); 33 | % Note: Choose a positive(negative) alf if the initial contour is outside(inside) the object. 34 | 35 | 36 | d = 1; % specify the width of the narrow band. The narrow band is 37 | % the union of (2d+1)x(2d+1) blocks centered at the zero crossing pixels. 38 | % Note: don't change this parameter for this version (nband_v14). 39 | epsilon = .000001; % small positive number added to the denominator to avoid 0 in the denominator 40 | rad = d; 41 | vs=d+1; 42 | 43 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; 44 | text(6,6,'Left click to get points, right click to get end point','FontSize',[12],'Color', 'r'); 45 | % Use mouse to obtain initial contour/region; 46 | BW = roipoly; % get a region R inside a polygon, BW is a binary image with 1 and 0 inside or outside the polygon; 47 | c0=2; % The constant value used to define binary level set function as initial LSF; 48 | % Using larger value of c0 usually slows down the evolution. 49 | 50 | initialLSF= c0*2*(0.5-BW); % initial level set function: -c0 inside R, c0 outside R; 51 | u=initialLSF; 52 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; 53 | [c,h] = contour(u,[0 0],'b'); 54 | title('Initial contour'); 55 | 56 | %initial bandmap, 57 | bandMap = initializeNB(u); 58 | 59 | total_iter_time = 0; 60 | 61 | ops{1}.name = 'normalGradient'; 62 | ops{end+1}.name = 'Dirac'; 63 | ops{end+1}.name = 'curvature'; 64 | ops{end+1}.name = 'computeDataTerm'; 65 | ops{end+1}.name = 'updateLSF'; 66 | ops{end+1}.name = 'updateZeroCrossBand'; 67 | ops{end+1}.name = 'updateZCBand init'; 68 | ops{end+1}.name = 'total time'; 69 | 70 | total_stats = zeros(length(ops), 1); 71 | 72 | tic; 73 | t1=cputime; 74 | [u, bandMap, ux, uy, Nx, Ny, diracU, K, ABD, f, E,Stats] = ... 75 | nband_v14(u, bandMap, DiracSigma, vs, lambda, alf, mu, timestep, rad, vx, vy, g, nrow, ncol, N_iter); 76 | t2=cputime; 77 | iterationTime=t2-t1 78 | total_stats = total_stats + Stats; 79 | total_iter_time = total_iter_time + toc; 80 | total_time = total_time + total_iter_time; 81 | 82 | %hold on; 83 | figure;imagesc(Img, [0, 255]);colormap(gray);hold on; 84 | [c,h] = contour(u,[0 0],'r'); 85 | iterNum=[num2str(N_iter), ' iterations']; 86 | title(iterNum); 87 | 88 | 89 | disp(' '); 90 | printStats(ops, total_stats); 91 | disp(' '); 92 | 93 | % display statistics of CPU times 94 | disp(' =============== time statistics (Matlab) ================'); 95 | disp(sprintf('%26s\t %.6g s', 'total iteration time', total_iter_time)); 96 | disp(sprintf('%26s\t %.6g s', 'total time (init/iter)', total_time)); 97 | disp(' '); 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Narrow band/NarrowBand_DLL/initializeNB.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/NarrowBand_DLL/initializeNB.dll -------------------------------------------------------------------------------- /Narrow band/NarrowBand_DLL/nband_v14.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/NarrowBand_DLL/nband_v14.dll -------------------------------------------------------------------------------- /Narrow band/NarrowBand_DLL/printStats.m: -------------------------------------------------------------------------------- 1 | function printStats(ops, total_stats) 2 | disp(' ================ time statistics (MEX) =================='); 3 | for i=1:length(ops), 4 | disp(sprintf('%26s\t %.6g s', ops{i}.name, total_stats(i))); 5 | end -------------------------------------------------------------------------------- /Narrow band/NarrowBand_DLL/twoObjImg.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/NarrowBand_DLL/twoObjImg.bmp -------------------------------------------------------------------------------- /Narrow band/calcspeed.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/calcspeed.m -------------------------------------------------------------------------------- /Narrow band/edgestop.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/edgestop.m -------------------------------------------------------------------------------- /Narrow band/extendspeed.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/extendspeed.m -------------------------------------------------------------------------------- /Narrow band/extendspeedband.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/extendspeedband.m -------------------------------------------------------------------------------- /Narrow band/initphi.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/initphi.m -------------------------------------------------------------------------------- /Narrow band/isband.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/isband.m -------------------------------------------------------------------------------- /Narrow band/isfront.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/isfront.m -------------------------------------------------------------------------------- /Narrow band/narrowbandEvolution.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/narrowbandEvolution.m -------------------------------------------------------------------------------- /Narrow band/noisyImg.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/noisyImg.bmp -------------------------------------------------------------------------------- /Narrow band/reinit_SD_ENO2.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/reinit_SD_ENO2.m -------------------------------------------------------------------------------- /Narrow band/test.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dingkeyan93/Active-Contour-Model-Matlab/5204e8a6e0b338981fae388e292630a3e58877dc/Narrow band/test.m -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Collected Matlab Code of Active Contour Model for Image Segmentation 2 | Here are some matlab code of Active Contour Models, which are collected from the Internet. 3 | 4 | Only used for research. --------------------------------------------------------------------------------