├── seg_3D ├── test ├── Heaviside.m ├── last_lse_bfe_3D.m ├── single_Demo_3D.m ├── FP_calculation.m ├── TP_calculation.m ├── DC_calculation.m ├── JCS_calculation.m ├── P_calculation.m └── sdf2circle.m ├── Three-phase ├── 1.bmp ├── 6.bmp ├── 34.bmp ├── 35.png ├── readme ├── Heaviside.m ├── alf_evoluton3.m ├── TP_calculation.m ├── DC_calculation.m ├── JCS_calculation.m ├── FP_calculation.m ├── P_calculation.m └── Multi_Demo.m ├── Two-phase ├── readme ├── outImg17.bmp ├── outImg19.bmp ├── outImg21.bmp ├── outImg23.bmp ├── outImg25.bmp ├── Heaviside.m ├── alf_evolution.m ├── outImg105_crisp.bmp ├── outImg115_crisp.bmp ├── outImg125_crisp.bmp ├── outImg85_crisp.bmp ├── outImg95_crisp.bmp ├── DC_calculation.m ├── TP_calculation.m ├── JCS_calculation.m ├── FP_calculation.m ├── P_calculation.m └── single_Demo.m ├── Four-phase ├── readme ├── Multi_Demo.m ├── outImg17.bmp ├── outImg19.bmp ├── outImg21.bmp ├── outImg23.bmp ├── outImg25.bmp ├── Heaviside.m ├── DC_calculation.m ├── JCS_calculation.m ├── FP_calculation.m ├── TP_calculation.m ├── P_calculation.m └── alf_evolution4.m └── README.md /seg_3D/test: -------------------------------------------------------------------------------- 1 | Segmentation of 3D images. 2 | -------------------------------------------------------------------------------- /Three-phase/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Three-phase/1.bmp -------------------------------------------------------------------------------- /Three-phase/6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Three-phase/6.bmp -------------------------------------------------------------------------------- /Two-phase/readme: -------------------------------------------------------------------------------- 1 | Two-phase segmentation using the adaptive local fitting model. 2 | -------------------------------------------------------------------------------- /Four-phase/readme: -------------------------------------------------------------------------------- 1 | Four-phase segmentation using the adaptive local fitting model. 2 | -------------------------------------------------------------------------------- /Three-phase/34.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Three-phase/34.bmp -------------------------------------------------------------------------------- /Three-phase/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Three-phase/35.png -------------------------------------------------------------------------------- /Three-phase/readme: -------------------------------------------------------------------------------- 1 | Three-phase segmentation using the adaptive local fitting model. 2 | -------------------------------------------------------------------------------- /Two-phase/outImg17.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg17.bmp -------------------------------------------------------------------------------- /Two-phase/outImg19.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg19.bmp -------------------------------------------------------------------------------- /Two-phase/outImg21.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg21.bmp -------------------------------------------------------------------------------- /Two-phase/outImg23.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg23.bmp -------------------------------------------------------------------------------- /Two-phase/outImg25.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg25.bmp -------------------------------------------------------------------------------- /Four-phase/Multi_Demo.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Four-phase/Multi_Demo.m -------------------------------------------------------------------------------- /Four-phase/outImg17.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Four-phase/outImg17.bmp -------------------------------------------------------------------------------- /Four-phase/outImg19.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Four-phase/outImg19.bmp -------------------------------------------------------------------------------- /Four-phase/outImg21.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Four-phase/outImg21.bmp -------------------------------------------------------------------------------- /Four-phase/outImg23.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Four-phase/outImg23.bmp -------------------------------------------------------------------------------- /Four-phase/outImg25.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Four-phase/outImg25.bmp -------------------------------------------------------------------------------- /Two-phase/Heaviside.m: -------------------------------------------------------------------------------- 1 | function h = Heaviside(x,epsilon) 2 | h=0.5*(1+(2/pi)*atan(x./epsilon)); -------------------------------------------------------------------------------- /Two-phase/alf_evolution.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/alf_evolution.m -------------------------------------------------------------------------------- /seg_3D/Heaviside.m: -------------------------------------------------------------------------------- 1 | function h = Heaviside(x,epsilon) 2 | h=0.5*(1+(2/pi)*atan(x./epsilon)); -------------------------------------------------------------------------------- /seg_3D/last_lse_bfe_3D.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/seg_3D/last_lse_bfe_3D.m -------------------------------------------------------------------------------- /seg_3D/single_Demo_3D.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/seg_3D/single_Demo_3D.m -------------------------------------------------------------------------------- /Four-phase/Heaviside.m: -------------------------------------------------------------------------------- 1 | function h = Heaviside(x,epsilon) 2 | h=0.5*(1+(2/pi)*atan(x./epsilon)); -------------------------------------------------------------------------------- /Three-phase/Heaviside.m: -------------------------------------------------------------------------------- 1 | function h = Heaviside(x,epsilon) 2 | h=0.5*(1+(2/pi)*atan(x./epsilon)); -------------------------------------------------------------------------------- /Three-phase/alf_evoluton3.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Three-phase/alf_evoluton3.m -------------------------------------------------------------------------------- /Two-phase/outImg105_crisp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg105_crisp.bmp -------------------------------------------------------------------------------- /Two-phase/outImg115_crisp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg115_crisp.bmp -------------------------------------------------------------------------------- /Two-phase/outImg125_crisp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg125_crisp.bmp -------------------------------------------------------------------------------- /Two-phase/outImg85_crisp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg85_crisp.bmp -------------------------------------------------------------------------------- /Two-phase/outImg95_crisp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madd2014/ALF/HEAD/Two-phase/outImg95_crisp.bmp -------------------------------------------------------------------------------- /seg_3D/FP_calculation.m: -------------------------------------------------------------------------------- 1 | function FP_rate = FP_calculation(I_Out,I_Mask) 2 | 3 | unit_region = I_Out | I_Mask; 4 | numerator = sum(sum(unit_region - I_Mask)); 5 | denominator = sum(sum(I_Mask)); 6 | FP_rate = numerator/denominator; 7 | 8 | -------------------------------------------------------------------------------- /seg_3D/TP_calculation.m: -------------------------------------------------------------------------------- 1 | 2 | function TP_rate = TP_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | 8 | TP_rate = numerator/denominator; 9 | 10 | -------------------------------------------------------------------------------- /seg_3D/DC_calculation.m: -------------------------------------------------------------------------------- 1 | 2 | function DC_rate = DC_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Out)) + sum(sum(I_Mask)); 7 | DC_rate = 2*numerator/denominator; 8 | 9 | -------------------------------------------------------------------------------- /Three-phase/TP_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the TP index 2 | function TP_rate = TP_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | 8 | TP_rate = numerator/denominator; 9 | -------------------------------------------------------------------------------- /Two-phase/DC_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the DC index 2 | function DC_rate = DC_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Out)) + sum(sum(I_Mask)); 7 | DC_rate = 2*numerator/denominator; 8 | 9 | -------------------------------------------------------------------------------- /Four-phase/DC_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the DC index 2 | function DC_rate = DC_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Out)) + sum(sum(I_Mask)); 7 | DC_rate = 2*numerator/denominator; 8 | 9 | -------------------------------------------------------------------------------- /seg_3D/JCS_calculation.m: -------------------------------------------------------------------------------- 1 | 2 | function JCS_rate = JCS_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | unit_region = I_Out | I_Mask; 7 | denominator = sum(sum(unit_region)); 8 | 9 | JCS_rate = numerator/denominator; 10 | -------------------------------------------------------------------------------- /Two-phase/TP_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the TP index 2 | function TP_rate = TP_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | 8 | TP_rate = numerator/denominator; 9 | 10 | 11 | 12 | % TP_rate 13 | % test_end = 1; -------------------------------------------------------------------------------- /Three-phase/DC_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the DC index 2 | function DC_rate = DC_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Out)) + sum(sum(I_Mask)); 7 | DC_rate = 2*numerator/denominator; 8 | 9 | 10 | % TP_rate 11 | % test_end = 1; -------------------------------------------------------------------------------- /Four-phase/JCS_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the JCC index 2 | function JCS_rate = JCS_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | unit_region = I_Out | I_Mask; 7 | denominator = sum(sum(unit_region)); 8 | 9 | JCS_rate = numerator/denominator; 10 | 11 | % TP_rate 12 | % test_end = 1; -------------------------------------------------------------------------------- /Three-phase/JCS_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the JCS index 2 | function JCS_rate = JCS_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | unit_region = I_Out | I_Mask; 7 | denominator = sum(sum(unit_region)); 8 | 9 | JCS_rate = numerator/denominator; 10 | 11 | % TP_rate 12 | % test_end = 1; -------------------------------------------------------------------------------- /Two-phase/JCS_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the JCC index 2 | function JCS_rate = JCS_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | unit_region = I_Out | I_Mask; 7 | denominator = sum(sum(unit_region)); 8 | 9 | JCS_rate = numerator/denominator; 10 | 11 | % TP_rate 12 | % test_end = 1; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ALF 2 | Adaptive local fitting based active contour model for medical image segmentation. If you use this code, please cite the following paper: 3 | 4 | "Dongdong Ma, Qingmin Liao, Ziqin Chen, Ran Liao, and Hui Ma, Adaptive local-fitting-based active contour model for medical image segmentation. Signal Processing: Image Communication, 2019 (76): 201-213." 5 | -------------------------------------------------------------------------------- /Two-phase/FP_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the FP index 2 | function FP_rate = FP_calculation(I_Out,I_Mask) 3 | 4 | % I_Out = ones(10,10) > 0; 5 | % I_Mask = (randi(2,10,10)-1) > 0; 6 | unit_region = I_Out | I_Mask; 7 | numerator = sum(sum(unit_region - I_Mask)); 8 | denominator = sum(sum(I_Mask)); 9 | FP_rate = numerator/denominator; 10 | 11 | 12 | 13 | % TP_rate 14 | % test_end = 1; -------------------------------------------------------------------------------- /Four-phase/FP_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the FP index 2 | function FP_rate = FP_calculation(I_Out,I_Mask) 3 | 4 | % I_Out = ones(10,10) > 0; 5 | % I_Mask = (randi(2,10,10)-1) > 0; 6 | unit_region = I_Out | I_Mask; 7 | numerator = sum(sum(unit_region - I_Mask)); 8 | denominator = sum(sum(I_Mask)); 9 | FP_rate = numerator/denominator; 10 | 11 | 12 | 13 | % TP_rate 14 | % test_end = 1; -------------------------------------------------------------------------------- /Four-phase/TP_calculation.m: -------------------------------------------------------------------------------- 1 | % calculation of TP index 2 | function TP_rate = TP_calculation(I_Out,I_Mask) 3 | 4 | % I_Out = ones(10,10) > 0; 5 | % I_Mask = (randi(2,10,10)-1) > 0; 6 | cross_region = I_Out & I_Mask; 7 | numerator = sum(sum(cross_region)); 8 | denominator = sum(sum(I_Mask)); 9 | 10 | TP_rate = numerator/denominator; 11 | 12 | 13 | 14 | % TP_rate 15 | % test_end = 1; -------------------------------------------------------------------------------- /Three-phase/FP_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the FP index 2 | function FP_rate = FP_calculation(I_Out,I_Mask) 3 | 4 | % I_Out = ones(10,10) > 0; 5 | % I_Mask = (randi(2,10,10)-1) > 0; 6 | unit_region = I_Out | I_Mask; 7 | numerator = sum(sum(unit_region - I_Mask)); 8 | denominator = sum(sum(I_Mask)); 9 | FP_rate = numerator/denominator; 10 | 11 | 12 | 13 | % TP_rate 14 | % test_end = 1; -------------------------------------------------------------------------------- /seg_3D/P_calculation.m: -------------------------------------------------------------------------------- 1 | 2 | function P_rate = P_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | TP_rate = numerator/denominator; 8 | 9 | unit_region = I_Out | I_Mask; 10 | numerator = sum(sum(unit_region - I_Mask)); 11 | denominator = sum(sum(I_Mask)); 12 | FP_rate = numerator/denominator; 13 | 14 | P_rate = TP_rate/(TP_rate + FP_rate); 15 | 16 | % TP_rate 17 | % test_end = 1; -------------------------------------------------------------------------------- /Two-phase/P_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the Precision index 2 | function P_rate = P_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | TP_rate = numerator/denominator; 8 | 9 | unit_region = I_Out | I_Mask; 10 | numerator = sum(sum(unit_region - I_Mask)); 11 | denominator = sum(sum(I_Mask)); 12 | FP_rate = numerator/denominator; 13 | 14 | P_rate = TP_rate/(TP_rate + FP_rate); 15 | 16 | % TP_rate 17 | % test_end = 1; -------------------------------------------------------------------------------- /Four-phase/P_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the Precision index 2 | function P_rate = P_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | TP_rate = numerator/denominator; 8 | 9 | unit_region = I_Out | I_Mask; 10 | numerator = sum(sum(unit_region - I_Mask)); 11 | denominator = sum(sum(I_Mask)); 12 | FP_rate = numerator/denominator; 13 | 14 | P_rate = TP_rate/(TP_rate + FP_rate); 15 | 16 | % TP_rate 17 | % test_end = 1; -------------------------------------------------------------------------------- /Three-phase/P_calculation.m: -------------------------------------------------------------------------------- 1 | % calculate the P(Precision) index 2 | function P_rate = P_calculation(I_Out,I_Mask) 3 | 4 | cross_region = I_Out & I_Mask; 5 | numerator = sum(sum(cross_region)); 6 | denominator = sum(sum(I_Mask)); 7 | TP_rate = numerator/denominator; 8 | 9 | unit_region = I_Out | I_Mask; 10 | numerator = sum(sum(unit_region - I_Mask)); 11 | denominator = sum(sum(I_Mask)); 12 | FP_rate = numerator/denominator; 13 | 14 | P_rate = TP_rate/(TP_rate + FP_rate); 15 | 16 | % TP_rate 17 | % test_end = 1; -------------------------------------------------------------------------------- /seg_3D/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) -------------------------------------------------------------------------------- /Two-phase/single_Demo.m: -------------------------------------------------------------------------------- 1 | 2 | % Adaptive local fitting based active contour model for medical image segmentation 3 | % Create Date: 1/8/2018 4 | % Author: Dongdong Ma, Department of Eletronic Engineering, Tsinghua University 5 | 6 | clc; 7 | close all; 8 | clear; 9 | 10 | prefix = 'C:\Users\lenovo\Desktop\github\two-phase\data\'; 11 | img_num = 25; 12 | 13 | img_name = strcat(prefix,'outImg',num2str(img_num),'.bmp'); 14 | Img = double(imread(img_name)); 15 | if size(Img,3) > 1 16 | Img = double(rgb2gray(uint8(Img))); 17 | end 18 | 19 | switch img_num 20 | case 17 21 | A = 255; 22 | timestep = 0.1; 23 | iter_outer = 80; % inner iteration number 24 | iter_inner = 1; % outer iteration number 25 | 26 | lamda1 = 1; 27 | lamda2 = 1.5; 28 | sigma = 5; % control the size of neighboring region 29 | nu = 0.01 * A^2; % coefficient of arc length term 30 | mu = 1; % coefficient of distance regularization term 31 | c0 = 5; 32 | epsilon = 1; 33 | case 19 34 | A = 255; 35 | timestep = 0.1; 36 | iter_outer = 80; % outer iteration number 37 | iter_inner = 1; % inner iteration number 38 | 39 | lamda1 = 1; 40 | lamda2 = 1.5; 41 | sigma = 5; % control the size of neighboring region 42 | nu = 0.01 * A^2; % coefficient of arc length term 43 | mu = 1; % coefficient of distance regularization term 44 | c0 = 5; 45 | epsilon = 1; 46 | case 21 47 | A = 255; 48 | timestep = 0.1; 49 | iter_outer = 80; % outer iteration number 50 | iter_inner = 1; % inner iteration number 51 | 52 | lamda1 = 1; 53 | lamda2 = 1.5; 54 | sigma = 5; % control the size of neighboring region 55 | nu = 0.01 * A^2; % coefficient of arc length term 56 | mu = 1; % coefficient of distance regularization term 57 | c0 = 5; 58 | epsilon = 1; 59 | case 23 60 | A = 255; 61 | timestep = 0.1; 62 | iter_outer = 80; % outer iteration number 63 | iter_inner = 1; % inner iteration number 64 | 65 | lamda1 = 1; 66 | lamda2 = 1.5; 67 | sigma = 5; % control the size of neighboring region 68 | nu = 0.01 * A^2; % coefficient of arc length term 69 | mu = 1; % coefficient of distance regularization term 70 | c0 = 5; 71 | epsilon = 1; 72 | case 25 73 | A = 255; 74 | timestep = 0.1; 75 | iter_outer = 80; % outer iteration number 76 | iter_inner = 1; % inner iteration number 77 | 78 | lamda1 = 1; 79 | lamda2 = 1.5; 80 | sigma = 5; % control the size of neighboring region 81 | nu = 0.01 * A^2; % coefficient of arc length term 82 | mu = 1; % coefficient of distance regularization term 83 | c0 = 5; 84 | epsilon = 1; 85 | end 86 | 87 | % initial contour 88 | initialLSF = c0 * ones(size(Img)); 89 | initialLSF(50:end-50,50:end-50) = -c0; 90 | u = initialLSF; 91 | 92 | figure(2); 93 | imagesc(Img,[0, 255]); colormap(gray); axis off; axis equal 94 | hold on; 95 | contour(u,[0 0],'r'); 96 | title('Initial contour'); 97 | 98 | Komiga = ones(round(2*sigma)*2+1); Komiga = Komiga/sum(Komiga(:)); 99 | lamda_img = ones(size(Img)); 100 | 101 | rect_sdlen = (size(Komiga)-1)/2; 102 | ImgExt = padarray(Img,rect_sdlen,'symmetric','both'); 103 | Imgblks = im2col(ImgExt,size(Komiga),'sliding'); 104 | Avg_Imgblks = mean(Imgblks); 105 | sigma_mat = abs(Imgblks - repmat(Avg_Imgblks,size(Komiga,1)^2,1)); 106 | sigma2_mat = sigma_mat.^2; 107 | I_sigma_mat = Imgblks.*sigma_mat; 108 | omiga_mat = repmat(Komiga(:),1,size(Imgblks,2)); 109 | 110 | energy_curve = zeros(1,iter_outer); 111 | for n = 1:iter_outer 112 | [u, lamda_img,all_pixel_energy] = alf_evolution(lamda1,lamda2,omiga_mat,sigma_mat,sigma2_mat,I_sigma_mat,rect_sdlen,u,Img,lamda_img,Komiga,nu,timestep,mu,epsilon,iter_inner); 113 | energy_curve(n) = all_pixel_energy; 114 | if mod(n,1) == 0 115 | pause(0.001); 116 | imagesc(Img,[0, 255]); colormap(gray); axis off; axis equal; 117 | hold on; 118 | contour(u,[0 0],'r','LineWidth',1); 119 | iterNum = [num2str(n), ' iterations']; 120 | title(iterNum); 121 | hold off; 122 | end 123 | end 124 | 125 | % figure(5); plot(energy_curve); 126 | 127 | % read the ground truth 128 | gtruth_path = 'C:\Users\lenovo\Desktop\github\two-phase\data\'; 129 | file_name = strcat('outImg',num2str(img_num*5),'_crisp.bmp'); 130 | truth_bin = imread(strcat(gtruth_path,file_name)); 131 | whtmt = truth_bin == 3; % 2 means the white matter 132 | mask = (truth_bin == 2 | truth_bin == 3 | truth_bin == 1 | truth_bin == 8); 133 | output_img = u < 0; 134 | output_img = output_img & mask; 135 | figure(3); imshow(output_img); 136 | figure(4); imshow(whtmt);title('ground truth'); 137 | 138 | TP_rate = TP_calculation(output_img,whtmt) 139 | FP_rate = FP_calculation(output_img,whtmt) 140 | P_rate = P_calculation(output_img,whtmt) 141 | JCS_rate = JCS_calculation(output_img,whtmt) 142 | DC_rate = DC_calculation(output_img,whtmt) 143 | 144 | -------------------------------------------------------------------------------- /Three-phase/Multi_Demo.m: -------------------------------------------------------------------------------- 1 | % Adaptive local fitting based active contour model for medical image 2 | % segmentation, three phase segmentation 3 | % Create Date: 1/8/2018 4 | % Author: Dongdong Ma, Department of Eletronic Engineering, Tsinghua University 5 | clc; 6 | close all; 7 | clear; 8 | 9 | name_set = {'1.bmp','6.bmp','34.bmp','35.png'}; 10 | prefix = 'C:\Users\lenovo\Desktop\github\three-phase\data\'; 11 | name_num = 1; 12 | img_name = strcat(prefix,name_set{name_num}); 13 | Img = double(imread(img_name)); 14 | if size(Img,3) > 1 15 | Img = double(rgb2gray(uint8(Img))); 16 | end 17 | figure; 18 | imagesc(Img,[0 255]);colormap(gray);hold on; axis off;axis equal; 19 | title('Initial contour'); 20 | 21 | switch name_num 22 | case 1 23 | A = 255; 24 | timestep = 0.1; 25 | iter_outer = 200; % outer iteration number 26 | iter_inner = 1; % inner iteration number 27 | sigma = 5; % control the size of neighboring region 28 | nu = 0.005 * A^2; % coefficient of arc length term 29 | mu = 1.5; % coefficient of distance regularization term 30 | epsilon = 1; 31 | 32 | c0 = 3; 33 | temp1 = c0 * ones(size(Img)); 34 | temp1(30:end-15,30:end-30) = -c0; 35 | initialLSF(:,:,1) = temp1; 36 | temp2 = c0 * ones(size(Img)); 37 | temp2(10:end-10,10:end-10) = -c0; 38 | initialLSF(:,:,2) = temp2; 39 | case 2 40 | A = 255; 41 | timestep = 0.1; 42 | iter_outer = 50; % outer iteration number 43 | iter_inner = 1; % inner iteration number 44 | sigma = 8; % control the size of neighboring region 45 | nu = 0.005 * A^2; % coefficient of arc length term 46 | mu = 1.5; % coefficient of distance regularization term 47 | epsilon = 1; 48 | 49 | c0 = 3; 50 | temp1 = c0 * ones(size(Img)); 51 | temp1(35:end-35,35:end-35) = -c0; 52 | initialLSF(:,:,1) = temp1; 53 | temp2 = c0 * ones(size(Img)); 54 | temp2(10:end-10,10:end-10) = -c0; 55 | initialLSF(:,:,2) = temp2; 56 | case 3 57 | A = 255; 58 | timestep = 0.1; 59 | iter_outer = 200; % outer iteration number 60 | iter_inner = 1; % inner iteration number 61 | sigma = 5; % control the size of neighboring region 62 | nu = 0.003 * A^2; % coefficient of arc length term 63 | mu = 1.5; % coefficient of distance regularization term 64 | epsilon = 1; 65 | 66 | c0 = 3; 67 | temp1 = c0 * ones(size(Img)); 68 | temp1(40:end-25,40:end-40) = -c0; 69 | initialLSF(:,:,1) = temp1; 70 | temp2 = c0 * ones(size(Img)); 71 | temp2(42:end-23,42:end-38) = -c0; 72 | initialLSF(:,:,2) = temp2; 73 | case 4 74 | 75 | A = 255; 76 | timestep = 0.1; 77 | iter_outer = 150; % outer iteration number 78 | iter_inner = 1; % inner iteration number 79 | sigma = 5; % control the size of neighboring region 80 | nu = 0.005 * A^2; % coefficient of arc length term 81 | mu = 1.5; % coefficient of distance regularization term 82 | epsilon = 1; 83 | 84 | c0 = 8; 85 | temp1 = c0 * ones(size(Img)); 86 | temp1(55:end-55,40:end-40) = -c0; 87 | initialLSF(:,:,1) = temp1; 88 | temp2 = c0 * ones(size(Img)); 89 | temp2(30:end-20,10:end-10) = -c0; 90 | initialLSF(:,:,2) = temp2; 91 | case 5 92 | A = 255; 93 | timestep = 0.1; 94 | iter_outer = 150; % outer iteration number 95 | iter_inner = 1; % inner iteration number 96 | sigma = 5; % control the size of neighboring region 97 | nu = 0.0001 * A^2; % coefficient of arc length term 98 | mu = 1.5; % coefficient of distance regularization term 99 | epsilon = 1; 100 | 101 | c0 = 3; 102 | temp1 = c0 * ones(size(Img)); 103 | temp1(30:end-15,30:end-30) = -c0; 104 | initialLSF(:,:,1) = temp1; 105 | temp2 = c0 * ones(size(Img)); 106 | temp2(10:end-10,10:end-10) = -c0; 107 | initialLSF(:,:,2) = temp2; 108 | 109 | end 110 | 111 | u = initialLSF; 112 | [c,h] = contour(u(:,:,1),[0 0],'r','LineWidth',1); 113 | [c,h] = contour(u(:,:,2),[0 0],'g','LineWidth',1); 114 | hold off 115 | 116 | Komiga = ones(round(2*sigma)*2 + 1); Komiga = Komiga/sum(Komiga(:)); 117 | lamda_img = ones(size(Img)); 118 | 119 | rect_sdlen = (size(Komiga)-1)/2; 120 | ImgExt = padarray(Img,rect_sdlen,'symmetric','both'); 121 | Imgblks = im2col(ImgExt,size(Komiga),'sliding'); 122 | Avg_Imgblks = mean(Imgblks); 123 | sigma_mat = abs(Imgblks - repmat(Avg_Imgblks,size(Komiga,1)^2,1)); 124 | sigma2_mat = sigma_mat.^2; 125 | I_sigma_mat = Imgblks.*sigma_mat; 126 | omiga_mat = repmat(Komiga(:),1,size(Imgblks,2)); 127 | 128 | for n = 1:iter_outer 129 | lamda_img = zeros(size(Img)); 130 | [u,lamda_img,miu1_img,miu2_img,miu3_img] = alf_evoluton3(omiga_mat,sigma_mat,sigma2_mat,I_sigma_mat,rect_sdlen,u,Img,lamda_img,Komiga,nu,timestep,mu,epsilon,iter_inner); 131 | if mod(n,1) == 0 132 | pause(0.001); 133 | imagesc(Img,[0, 255]); colormap(gray); axis off; axis equal; 134 | hold on; 135 | [c,h] = contour(u(:,:,1),[0 0],'r','LineWidth',1); 136 | [c,h] = contour(u(:,:,2),[0 0],'g','LineWidth',1); 137 | iterNum = [num2str(n), ' iterations']; 138 | title(iterNum); 139 | hold off; 140 | end 141 | end 142 | 143 | H1 = Heaviside(u(:,:,1),epsilon ); 144 | H2 = Heaviside(u(:,:,2),epsilon ); 145 | M1 = H1.*H2; 146 | M2 = H1.*(1-H2); 147 | M3 = (1-H1); 148 | figure(2); imshow(M1); 149 | figure(3); imshow(M2); 150 | figure(4); imshow(M3); 151 | 152 | Img_seg = mean(miu1_img(:))*M1 + mean(miu2_img(:))*M2 + mean(miu3_img(:))*M3; % three regions are labeled with C1, C2, C3 153 | figure; imagesc(Img_seg); axis off; axis equal; title('Segmented regions'); 154 | colormap(gray); 155 | 156 | 157 | -------------------------------------------------------------------------------- /Four-phase/alf_evolution4.m: -------------------------------------------------------------------------------- 1 | % evolution function 2 | 3 | function [u, lamda_img,miu1_img,miu2_img,miu3_img,miu4_img] = alf_evolution4(lamda,omiga_mat,sigma_mat,sigma2_mat,I_sigma_mat,rect_sdlen,u0,Img,lamda_img,Komiga,nu,timestep,mu,epsilon,iter_lse) 4 | 5 | u = u0; 6 | 7 | for kk = 1:iter_lse 8 | u(:,:,1) = NeumannBoundCond(u(:,:,1)); 9 | K1 = curvature_central(u(:,:,1)); % div() 10 | DiracU1 = Dirac(u(:,:,1),epsilon); 11 | 12 | u(:,:,2) = NeumannBoundCond(u(:,:,2)); 13 | K2 = curvature_central(u(:,:,2)); % div() 14 | DiracU2 = Dirac(u(:,:,2),epsilon); 15 | 16 | Hu1 = Heaviside(u(:,:,1),epsilon); 17 | Hu2 = Heaviside(u(:,:,2),epsilon); 18 | M1 = Hu1.*Hu2; 19 | M2 = Hu2.*(1-Hu1); 20 | M3 = (1-Hu2).*Hu1; 21 | M4 = (1 - Hu1).*(1 - Hu2); 22 | 23 | M1Ext = padarray(M1,rect_sdlen,'symmetric','both'); 24 | M1_blks = im2col(M1Ext,size(Komiga),'sliding'); 25 | M2Ext = padarray(M2,rect_sdlen,'symmetric','both'); 26 | M2_blks = im2col(M2Ext,size(Komiga),'sliding'); 27 | M3Ext = padarray(M3,rect_sdlen,'symmetric','both'); 28 | M3_blks = im2col(M3Ext,size(Komiga),'sliding'); 29 | M4Ext = padarray(M4,rect_sdlen,'symmetric','both'); 30 | M4_blks = im2col(M4Ext,size(Komiga),'sliding'); 31 | 32 | % update miu 33 | temp = padarray(M1.*Img,rect_sdlen,'symmetric','both'); 34 | temp1 = conv2(temp,Komiga,'valid'); 35 | temp111 = sum(omiga_mat.*sigma_mat.*M1_blks); 36 | temp2 = lamda_img.*reshape(temp111,size(Img)); 37 | temp = padarray(M1,rect_sdlen,'symmetric','both'); 38 | temp3 = conv2(temp,Komiga,'valid'); 39 | miu1_img = (temp1 - temp2)./(temp3 + exp(-99)); 40 | 41 | temp = padarray(M2.*Img,rect_sdlen,'symmetric','both'); 42 | temp1 = conv2(temp,Komiga,'valid'); 43 | temp222 = sum(omiga_mat.*sigma_mat.*M2_blks); 44 | temp2 = lamda_img.*reshape(temp222,size(Img)); 45 | temp = padarray(M2,rect_sdlen,'symmetric','both'); 46 | temp3 = conv2(temp,Komiga,'valid'); 47 | miu2_img = (temp1 - temp2)./(temp3 + exp(-99)); 48 | 49 | temp = padarray(M3.*Img,rect_sdlen,'symmetric','both'); 50 | temp1 = conv2(temp,Komiga,'valid'); 51 | temp333 = sum(omiga_mat.*sigma_mat.*M3_blks); 52 | temp2 = lamda_img.*reshape(temp333,size(Img)); 53 | temp = padarray(M3,rect_sdlen,'symmetric','both'); 54 | temp3 = conv2(temp,Komiga,'valid'); 55 | miu3_img = (temp1 - temp2)./(temp3 + exp(-99)); 56 | 57 | temp = padarray(M4.*Img,rect_sdlen,'symmetric','both'); 58 | temp1 = conv2(temp,Komiga,'valid'); 59 | temp444 = sum(omiga_mat.*sigma_mat.*M4_blks); 60 | temp2 = lamda_img.*reshape(temp444,size(Img)); 61 | temp = padarray(M4,rect_sdlen,'symmetric','both'); 62 | temp3 = conv2(temp,Komiga,'valid'); 63 | miu4_img = (temp1 - temp2)./(temp3 + exp(-99)); 64 | 65 | % calculation of gradient flow 66 | temp = sigma_mat((size(Komiga,1)^2+1)/2,:); 67 | diff_Img = reshape(temp,size(Img)); 68 | diff_Img2 = diff_Img.^2; 69 | 70 | temp = padarray(ones(size(Img)),rect_sdlen,'symmetric','both'); 71 | temp1 = Img.^2.*conv2(temp,Komiga,'valid'); 72 | temp = padarray(miu1_img.^2,rect_sdlen,'symmetric','both'); 73 | temp2 = conv2(temp,Komiga,'valid'); 74 | temp = padarray(lamda_img.^2,rect_sdlen,'symmetric','both'); 75 | temp3 = diff_Img2.*conv2(temp,Komiga,'valid'); 76 | temp = padarray(miu1_img,rect_sdlen,'symmetric','both'); 77 | temp4 = 2*Img.*conv2(temp,Komiga,'valid'); 78 | temp = padarray(lamda_img,rect_sdlen,'symmetric','both'); 79 | temp5 = 2*Img.*diff_Img.*conv2(temp,Komiga,'valid'); 80 | temp = padarray(lamda_img.*miu1_img,rect_sdlen,'symmetric','both'); 81 | temp6 = 2*diff_Img.*conv2(temp,Komiga,'valid'); 82 | e1x = temp1 + temp2 + temp3 - temp4 - temp5 + temp6; 83 | 84 | temp = padarray(ones(size(Img)),rect_sdlen,'symmetric','both'); 85 | temp1 = Img.^2.*conv2(temp,Komiga,'valid'); 86 | temp = padarray(miu2_img.^2,rect_sdlen,'symmetric','both'); 87 | temp2 = conv2(temp,Komiga,'valid'); 88 | temp = padarray(lamda_img.^2,rect_sdlen,'symmetric','both'); 89 | temp3 = diff_Img2.*conv2(temp,Komiga,'valid'); 90 | temp = padarray(miu2_img,rect_sdlen,'symmetric','both'); 91 | temp4 = 2*Img.*conv2(temp,Komiga,'valid'); 92 | temp = padarray(lamda_img,rect_sdlen,'symmetric','both'); 93 | temp5 = 2*Img.*diff_Img.*conv2(temp,Komiga,'valid'); 94 | temp = padarray(lamda_img.*miu2_img,rect_sdlen,'symmetric','both'); 95 | temp6 = 2*diff_Img.*conv2(temp,Komiga,'valid'); 96 | e2x = temp1 + temp2 + temp3 - temp4 - temp5 + temp6; 97 | 98 | temp = padarray(ones(size(Img)),rect_sdlen,'symmetric','both'); 99 | temp1 = Img.^2.*conv2(temp,Komiga,'valid'); 100 | temp = padarray(miu3_img.^2,rect_sdlen,'symmetric','both'); 101 | temp2 = conv2(temp,Komiga,'valid'); 102 | temp = padarray(lamda_img.^2,rect_sdlen,'symmetric','both'); 103 | temp3 = diff_Img2.*conv2(temp,Komiga,'valid'); 104 | temp = padarray(miu3_img,rect_sdlen,'symmetric','both'); 105 | temp4 = 2*Img.*conv2(temp,Komiga,'valid'); 106 | temp = padarray(lamda_img,rect_sdlen,'symmetric','both'); 107 | temp5 = 2*Img.*diff_Img.*conv2(temp,Komiga,'valid'); 108 | temp = padarray(lamda_img.*miu3_img,rect_sdlen,'symmetric','both'); 109 | temp6 = 2*diff_Img.*conv2(temp,Komiga,'valid'); 110 | e3x = temp1 + temp2 + temp3 - temp4 - temp5 + temp6; 111 | 112 | temp = padarray(ones(size(Img)),rect_sdlen,'symmetric','both'); 113 | temp1 = Img.^2.*conv2(temp,Komiga,'valid'); 114 | temp = padarray(miu4_img.^2,rect_sdlen,'symmetric','both'); 115 | temp2 = conv2(temp,Komiga,'valid'); 116 | temp = padarray(lamda_img.^2,rect_sdlen,'symmetric','both'); 117 | temp3 = diff_Img2.*conv2(temp,Komiga,'valid'); 118 | temp = padarray(miu4_img,rect_sdlen,'symmetric','both'); 119 | temp4 = 2*Img.*conv2(temp,Komiga,'valid'); 120 | temp = padarray(lamda_img,rect_sdlen,'symmetric','both'); 121 | temp5 = 2*Img.*diff_Img.*conv2(temp,Komiga,'valid'); 122 | temp = padarray(lamda_img.*miu4_img,rect_sdlen,'symmetric','both'); 123 | temp6 = 2*diff_Img.*conv2(temp,Komiga,'valid'); 124 | e4x = temp1 + temp2 + temp3 - temp4 - temp5 + temp6; 125 | 126 | % multiply the weights 127 | e1x = lamda(1)*e1x; 128 | e2x = lamda(2)*e2x; 129 | e3x = lamda(3)*e3x; 130 | e4x = lamda(4)*e4x; 131 | 132 | dataForce1 = (e1x - e2x - e3x + e4x).*Hu2 + e3x - e4x; 133 | ImageTerm = -DiracU1.*dataForce1; 134 | penalizeTerm = mu*(4*del2(u(:,:,1)) - K1); 135 | lengthTerm = nu.*DiracU1.*K1; 136 | u(:,:,1) = u(:,:,1) + timestep*(lengthTerm + penalizeTerm + ImageTerm); 137 | 138 | dataForce2 = (e1x - e2x - e3x + e4x).*Hu1 + e2x - e4x; 139 | ImageTerm = -DiracU2.*dataForce2; 140 | penalizeTerm = mu*(4*del2(u(:,:,2)) - K2); 141 | lengthTerm = nu.*DiracU2.*K2; 142 | u(:,:,2) = u(:,:,2) + timestep*(lengthTerm + penalizeTerm + ImageTerm); 143 | end 144 | 145 | % update lamda 146 | temp1 = sum(omiga_mat.*I_sigma_mat.*M1_blks); 147 | temp1 = reshape(temp1,size(Img)); 148 | temp2 = sum(omiga_mat.*I_sigma_mat.*M2_blks); 149 | temp2 = reshape(temp2,size(Img)); 150 | temp33 = sum(omiga_mat.*I_sigma_mat.*M3_blks); 151 | temp33 = reshape(temp33,size(Img)); 152 | temp33_2 = sum(omiga_mat.*I_sigma_mat.*M4_blks); 153 | temp33_2 = reshape(temp33_2,size(Img)); 154 | 155 | temp3 = miu1_img.*reshape(temp111,size(Img)); 156 | temp4 = miu2_img.*reshape(temp222,size(Img)); 157 | temp55 = miu3_img.*reshape(temp333,size(Img)); 158 | temp55_2 = miu4_img.*reshape(temp444,size(Img)); 159 | 160 | temp5 = sum(omiga_mat.*sigma2_mat.*M1_blks); 161 | temp5 = reshape(temp5,size(Img)); 162 | temp6 = sum(omiga_mat.*sigma2_mat.*M2_blks); 163 | temp6 = reshape(temp6,size(Img)); 164 | temp7 = sum(omiga_mat.*sigma2_mat.*M3_blks); 165 | temp7 = reshape(temp7,size(Img)); 166 | temp7_2 = sum(omiga_mat.*sigma2_mat.*M4_blks); 167 | temp7_2 = reshape(temp7_2,size(Img)); 168 | 169 | lamda_img = (temp1 - temp3 + temp2 - temp4 + temp33 - temp55 + temp33_2 - temp55_2)./(temp5 + temp6 + temp7 + temp7_2 + exp(-99)); 170 | 171 | test_end = 1; 172 | 173 | 174 | % Neumann Bound condition 175 | function g = NeumannBoundCond(f) 176 | [nrow,ncol] = size(f); 177 | g = f; 178 | g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]); 179 | g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1); 180 | g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]); 181 | 182 | function k = curvature_central(u) 183 | [ux,uy] = gradient(u); 184 | normDu = sqrt(ux.^2+uy.^2+1e-10); % the norm of the gradient plus a small possitive number % to avoid division by zero in the following computation. 185 | Nx = ux./normDu; 186 | Ny = uy./normDu; 187 | [nxx,~] = gradient(Nx); 188 | [~,nyy] = gradient(Ny); 189 | k = nxx+nyy; % compute divergence 190 | 191 | function h = Heaviside(x,epsilon) 192 | h=0.5*(1+(2/pi)*atan(x./epsilon)); 193 | 194 | function f = Dirac(x, epsilon) 195 | f=(epsilon/pi)./(epsilon^2.+x.^2); 196 | 197 | 198 | 199 | --------------------------------------------------------------------------------