├── GC.zip ├── auxi_funcs ├── SCASC_IR.m ├── SARslicmex.c ├── Zupdate_PCG.p ├── performance.m ├── SCASC_IR_PCG.m ├── SARslicmex.mexw64 ├── shrinkage.m ├── remove_outlier.m ├── DenormImage.m ├── suplabel2ImFeature.m ├── LaplacianMatrix.m ├── deltUpdate.m ├── suplabel2DI.m ├── image_normlized.m ├── AUC_Diagdistance.m ├── AdaptiveStructureGraph.m ├── Roc_plot.m ├── SuperpixelSegmentation.m ├── MSMfeature_extraction.m ├── MRFsegmentation.m └── Load_dataset.m ├── datasets ├── Italy_1.bmp ├── Italy_2.bmp ├── Italy_gt.bmp ├── shuguang_1.bmp ├── shuguang_2.bmp └── shuguang_gt.bmp ├── LICENSE ├── README.md └── SCASC_demo.m /GC.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/GC.zip -------------------------------------------------------------------------------- /auxi_funcs/SCASC_IR.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/auxi_funcs/SCASC_IR.m -------------------------------------------------------------------------------- /datasets/Italy_1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/datasets/Italy_1.bmp -------------------------------------------------------------------------------- /datasets/Italy_2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/datasets/Italy_2.bmp -------------------------------------------------------------------------------- /datasets/Italy_gt.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/datasets/Italy_gt.bmp -------------------------------------------------------------------------------- /auxi_funcs/SARslicmex.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/auxi_funcs/SARslicmex.c -------------------------------------------------------------------------------- /auxi_funcs/Zupdate_PCG.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/auxi_funcs/Zupdate_PCG.p -------------------------------------------------------------------------------- /auxi_funcs/performance.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/auxi_funcs/performance.m -------------------------------------------------------------------------------- /datasets/shuguang_1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/datasets/shuguang_1.bmp -------------------------------------------------------------------------------- /datasets/shuguang_2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/datasets/shuguang_2.bmp -------------------------------------------------------------------------------- /datasets/shuguang_gt.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/datasets/shuguang_gt.bmp -------------------------------------------------------------------------------- /auxi_funcs/SCASC_IR_PCG.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/auxi_funcs/SCASC_IR_PCG.m -------------------------------------------------------------------------------- /auxi_funcs/SARslicmex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yulisun/SCASC/HEAD/auxi_funcs/SARslicmex.mexw64 -------------------------------------------------------------------------------- /auxi_funcs/shrinkage.m: -------------------------------------------------------------------------------- 1 | function z = shrinkage(x, kappa) 2 | z = max( 0, x - kappa ) - max( 0, -x - kappa ); 3 | end -------------------------------------------------------------------------------- /auxi_funcs/remove_outlier.m: -------------------------------------------------------------------------------- 1 | function x = remove_outlier(y) 2 | x = y; 3 | outliers = y - mean(y(:)) > 3*std(y(:)); 4 | x(outliers) = max(max(x(~outliers))); -------------------------------------------------------------------------------- /auxi_funcs/DenormImage.m: -------------------------------------------------------------------------------- 1 | function [Img] = DenormImage(X,norm_p) 2 | b=size(X,3); 3 | Img = zeros(size(X)); 4 | for i=1:b 5 | Img(:,:,i) = X(:,:,i)*norm_p(i); 6 | end -------------------------------------------------------------------------------- /auxi_funcs/suplabel2ImFeature.m: -------------------------------------------------------------------------------- 1 | function [Im,feature,sigband] = suplabel2ImFeature(sup_img,X,b) 2 | feature = suplabel2DI(sup_img,X); 3 | Im = feature(:,:,1:b); 4 | sigband = sum(feature.^2,3); -------------------------------------------------------------------------------- /auxi_funcs/LaplacianMatrix.m: -------------------------------------------------------------------------------- 1 | function [Lx] = LaplacianMatrix(Sx) 2 | N = size(Sx,2); 3 | Lx_temp1 = -(Sx + Sx')/2; 4 | Lx_temp2 = sum(Lx_temp1,2); 5 | Lx = Lx_temp1; 6 | for i = 1:N 7 | Lx(i,i) = - Lx_temp2(i) + Lx_temp1(i,i); 8 | end 9 | -------------------------------------------------------------------------------- /auxi_funcs/deltUpdate.m: -------------------------------------------------------------------------------- 1 | function [delt] = deltUpdate(Q,alfa,type) 2 | switch type 3 | case 1 4 | delt = shrinkage(Q,alfa); 5 | case 21 6 | Q1 = sqrt(sum(Q.^2,1)); 7 | Q1(Q1==0) = alfa; 8 | Q2 = (Q1 - alfa) ./ Q1; 9 | delt = Q * diag((Q1 > alfa) .* Q2); 10 | end 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /auxi_funcs/suplabel2DI.m: -------------------------------------------------------------------------------- 1 | function [DI] = suplabel2DI(sup_cog,suplabel) 2 | [h,w] = size(sup_cog); 3 | B = size(suplabel,1); 4 | nbr_sp = max(sup_cog(:)); 5 | idx_t1 = label2idx(sup_cog); 6 | for b = 1:B 7 | for i = 1:nbr_sp 8 | index_vector = idx_t1{i}; 9 | DI_temp(index_vector) = suplabel(b,i); 10 | end 11 | DI(:,:,b) =reshape(DI_temp,[h w]); 12 | end -------------------------------------------------------------------------------- /auxi_funcs/image_normlized.m: -------------------------------------------------------------------------------- 1 | function imnor = image_normlized(image,type) 2 | image = double (image); 3 | %image(find(isnan(image)==1)) = 0; 4 | if strcmp(type,'optical') 5 | imnor = (image - min(image(:)))./(max(image(:))-min(image(:))); 6 | elseif strcmp(type,'sar') 7 | image(abs(image)<=0) = min(image(abs(image)>0)); 8 | image = log(image+1); 9 | imnor = (image - min(image(:)))./(max(image(:))-min(image(:))); 10 | end 11 | -------------------------------------------------------------------------------- /auxi_funcs/AUC_Diagdistance.m: -------------------------------------------------------------------------------- 1 | function [AUC, diag_dis] = AUC_Diagdistance(TPR,FPR) 2 | x= FPR; 3 | y = TPR; 4 | t = length(FPR); 5 | x_1 = [0 x(1:(t-1))]; 6 | y_1 = [0 y(1:(t-1))]; 7 | AUC = sum((x-x_1).*(y+y_1)/2); 8 | if FPR(end)~=1 9 | AUC_temp = (1-FPR(end))* TPR(end); 10 | AUC = AUC + AUC_temp; 11 | end 12 | z = abs(1-(x + y)); 13 | [~, z_location] = min(z); 14 | diag_dis = ((1-x(z_location))^2 +y(z_location)^2)^0.5; 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /auxi_funcs/AdaptiveStructureGraph.m: -------------------------------------------------------------------------------- 1 | function [S] = AdaptiveStructureGraph (X,K) 2 | if nargin == 1 3 | K = round(sqrt(size(X,2))); 4 | end 5 | if nargin <= 2 6 | X = X'; 7 | N = size(X,1); 8 | S = zeros(N,N); 9 | K = K+1; 10 | [idx,value] = knnsearch(X,X,'k',K); 11 | degree = tabulate(idx(:)); 12 | Kmat = degree(:,2); 13 | kmax = K; 14 | kmin = round(kmax/10)+1; 15 | Kmat(Kmat>=kmax)=kmax; 16 | Kmat(Kmat<=kmin)=kmin; 17 | if length(Kmat) t; % thresholded response 18 | tp(i) = nnz(Rt & GT); 19 | fp(i) = nnz(Rt & ~GT); 20 | end 21 | % convert to rates 22 | TPR = tp/P; 23 | FPR = fp/N; 24 | %figure;plot(FPR, TPR) % ROC -------------------------------------------------------------------------------- /auxi_funcs/SuperpixelSegmentation.m: -------------------------------------------------------------------------------- 1 | function [sup_pixel,N] = SuperpixelSegmentation(image,seg_scal,Compactness) 2 | % for SAR image, SARslicmex or SLIC with Log-transformed image can be used 3 | [h, w, b]=size(image); 4 | if b==1 || b==3 5 | [sup_pixel,N] = superpixels(image,seg_scal,'Compactness',Compactness); 6 | end 7 | if b==2 8 | new_image = zeros(h,w,3); 9 | for i = 1:b 10 | new_image(:,:,i) = image(:,:,i); 11 | end 12 | new_image(:,:,3) = zeros(h,w); 13 | [sup_pixel,N] = superpixels(new_image,seg_scal,'IsInputLab',1,'Compactness',Compactness); 14 | end 15 | if b>3 16 | for i = 1:b 17 | temp = image(:,:,i); 18 | new_image(:,i) = temp(:); 19 | end 20 | [pc,score,latent,tsquare] = pca(new_image,'NumComponents',3); 21 | for i = 1:3 22 | tmep = score(:,i); 23 | result_image(:,:,i) = reshape(tmep,[h w]); 24 | end 25 | [sup_pixel,N] = superpixels(result_image,seg_scal,'IsInputLab',1,'Compactness',Compactness); 26 | end 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 yulisun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /auxi_funcs/MSMfeature_extraction.m: -------------------------------------------------------------------------------- 1 | function [t1_feature,t2_feature,norm_par] = MSMfeature_extraction(sup_img,image_t1,image_t2) 2 | [h,w,b1] = size(image_t1); 3 | [~,~,b2] = size(image_t2); 4 | idx_t1 = label2idx(sup_img); 5 | nbr_sp = max(sup_img(:)); 6 | re_image_t1=reshape(image_t1,[h*w,b1]); 7 | re_image_t2=reshape(image_t2,[h*w,b2]); 8 | for i = 1:nbr_sp 9 | index_vector = idx_t1{i}; 10 | %----t1 11 | sub_superpixel_t1 = re_image_t1(index_vector,1:b1); 12 | mean_feature_t1 = (mean(sub_superpixel_t1)); 13 | var_feature_t1 = (var(sub_superpixel_t1)); 14 | median_feature_t1 = (median(sub_superpixel_t1)); 15 | t1_feature(i,1:b1) = mean_feature_t1; 16 | t1_feature(i,b1+1:2*b1) = var_feature_t1; 17 | t1_feature(i,2*b1+1:3*b1) = median_feature_t1; 18 | %-----t2 19 | sub_superpixel_t2 = re_image_t2(index_vector,1:b2); 20 | mean_feature_t2 = (mean(sub_superpixel_t2)); 21 | var_feature_t2 = (var(sub_superpixel_t2)); 22 | median_feature_t2 = (median(sub_superpixel_t2)); 23 | t2_feature(i,1:b2) = mean_feature_t2; 24 | t2_feature(i,b2+1:2*b2) = var_feature_t2; 25 | t2_feature(i,2*b2+1:3*b2) = median_feature_t2; 26 | end 27 | t1_feature = t1_feature'; 28 | t2_feature = t2_feature'; 29 | t1_feature(find(isnan(t1_feature)==1)) = 0; 30 | t2_feature(find(isnan(t2_feature)==1)) = 0; 31 | %% Normalization 32 | for i = 1:b1 33 | norm_par(i) = max(t1_feature(i,:))+eps; 34 | end 35 | for i = 1:b2 36 | norm_par(b1+i) = max(t2_feature(i,:))+eps; 37 | end 38 | for i = 1:size(t1_feature,1) 39 | t1_feature(i,:) = t1_feature(i,:)/(max(t1_feature(i,:))+eps); 40 | end 41 | for i = 1:size(t2_feature,1) 42 | t2_feature(i,:) = t2_feature(i,:)/(max(t2_feature(i,:))+eps); 43 | end 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SCASC 2 | Sparse Constrained Adaptive Structure Consistency based Unsupervised Image Regression for Heterogeneous Remote Sensing Change Detection 3 | 4 | ## Introduction 5 | MATLAB Code: SCASC - 2021 6 | This is a test program for the Sparse Constrained Adaptive Structure Consistency based method (SCASC) for heterogeneous change detection. 7 | 8 | SCASC is an unsupervised image regression method based on the structure consistency between heterogeneous images. SCASC first adaptively 9 | constructs a similarity graph to represent the structure of pre-event image, then uses the graph to translate the pre-event image to the 10 | domain of post-event image, and then computes the difference image. Finally, a superpixel-based Markovian segmentation model is designed 11 | to segment the difference image into changed and unchanged classes. 12 | 13 | Please refer to the paper for details. You are more than welcome to use the code! 14 | 15 | =================================================== 16 | 17 | ## Available datasets and Graph Cut algorithm 18 | 19 | #2-Texas is download from Professor Michele Volpi's webpage at https://sites.google.com/site/michelevolpiresearch/home. 20 | 21 | #3-Img7, #4-Img17, and #7-Img5 can be found at Professor Max Mignotte's webpage (http://www-labs.iro.umontreal.ca/~mignotte/) and they are associated with this paper https://doi.org/10.1109/TGRS.2020.2986239. 22 | 23 | #6-California is download from Dr. Luigi Tommaso Luppino's webpage (https://sites.google.com/view/luppino/data) and it was downsampled to 875*500 as shown in our paper. 24 | 25 | The graphCut algorithm is download from Professor Anton Osokin's webpage at https://github.com/aosokin/graphCutMex_BoykovKolmogorov. 26 | 27 | If you use these resources, please cite their relevant papers. 28 | 29 | =================================================== 30 | 31 | ## Citation 32 | 33 | If you use this code for your research, please cite our paper. Thank you! 34 | 35 | @ARTICLE{Sun2021Sparse, 36 | author={Sun, Yuli and Lei, Lin and Guan, Dongdong and Li, Ming and Kuang, Gangyao}, 37 | journal={IEEE Transactions on Geoscience and Remote Sensing}, 38 | title={Sparse Constrained Adaptive Structure Consistency based Unsupervised Image Regression for Heterogeneous Remote Sensing Change Detection}, 39 | year={2021}, 40 | volume={}, 41 | number={}, 42 | pages={}, 43 | doi={10.1109/TGRS.2021.3110998}} 44 | 45 | ## Future work 46 | 47 | In this work, due to the computational complexity, we only consider the forward transformation, i.e., translating the pre-event image to the domain of post-event image. 48 | Our future work is to improve its computation efficiency and design an effective fusion strategy to fuse the forward and backward detection results, 49 | thus improving the detection performance. 50 | 51 | ## Running 52 | 53 | Unzip the Zip files (GC) and run the SCASC demo file (tested in Matlab 2016a)! 54 | 55 | If you have any queries, please do not hesitate to contact me (sunyuli@mail.ustc.edu.cn). 56 | -------------------------------------------------------------------------------- /auxi_funcs/MRFsegmentation.m: -------------------------------------------------------------------------------- 1 | function [CM_map,labels] = MRFsegmentation(sup_img,alfa,delt) 2 | [h,w] = size(sup_img); 3 | nbr_sp = max(sup_img(:)); 4 | idx_img = label2idx(sup_img); 5 | %% R-adjacency neighborhood system 6 | for i = 1:nbr_sp 7 | index_vector = idx_img{i}; 8 | [location_x, location_y] = ind2sub(size(sup_img),index_vector); 9 | location_center(i,:) = [round(mean(location_x)) round(mean(location_y))]; 10 | end 11 | adj_mat = zeros(nbr_sp); 12 | for i=2:h-1 13 | for j=2:w-1 14 | label = sup_img(i,j); 15 | if (label ~= sup_img(i+1,j-1)) 16 | adj_mat(label, sup_img(i+1,j-1)) = 1; 17 | end 18 | if (label ~= sup_img(i,j+1)) 19 | adj_mat(label, sup_img(i,j+1)) = 1; 20 | end 21 | if (label ~= sup_img(i+1,j)) 22 | adj_mat(label, sup_img(i+1,j)) = 1; 23 | end 24 | if (label ~= sup_img(i+1,j+1)) 25 | adj_mat(label, sup_img(i+1,j+1)) = 1; 26 | end 27 | end 28 | end 29 | adj_mat_1 = double((adj_mat + adj_mat')>0); 30 | R = 2*round(sqrt(h*w/nbr_sp)); 31 | adj_mat = zeros(nbr_sp); 32 | for i=1:nbr_sp 33 | for j = i:nbr_sp 34 | if ((location_center(i,1) - location_center(j,1))^2 + (location_center(i,2) - location_center(j,2))^2 < R^2) 35 | adj_mat (i,j) = 1; 36 | end 37 | end 38 | end 39 | adj_mat = double((adj_mat + adj_mat')>0); 40 | adj_mat_2 = adj_mat - eye(nbr_sp); 41 | adj_mat = adj_mat_1|adj_mat_2; 42 | %% edgeWeights 43 | edgeWeights = zeros(sum(adj_mat(:)),4); 44 | [node_x, node_y] = find(adj_mat ==1); 45 | edgeWeights(:,1) = node_x; % index of node 1 46 | edgeWeights(:,2) = node_y; % index of node 2 47 | for i = 1:sum(adj_mat(:)) 48 | index_node_x = edgeWeights(i,1); 49 | index_node_y = edgeWeights(i,2); 50 | feature_x = delt(:,index_node_x); 51 | feature_y = delt(:,index_node_y); 52 | Dpq(i) = norm(feature_x-feature_y,2)^2; 53 | dist(i) = max(norm(location_center(index_node_x,:)-location_center(index_node_y,:),2),1); 54 | end 55 | sigma = mean(Dpq); 56 | Vpq = exp(-Dpq/(2*sigma)); 57 | Vpq = Vpq ./dist; 58 | edgeWeights(:,3) = (1 - alfa)*Vpq; % node 1 ---> node 2 59 | edgeWeights(:,4) = (1 - alfa)*Vpq; % node 2 ---> node 1 60 | %% calculate W 61 | for i = 1:nbr_sp 62 | idx = find(node_y==i); 63 | W_temp(i) = sum(Vpq(idx)); 64 | end 65 | W = max(W_temp)+log(2); 66 | %% termWeights 67 | Ic = (sum(delt.^2,1)); 68 | Ic = remove_outlier(Ic); 69 | Ic = Ic/max(Ic); 70 | T_theory = graythresh(Ic); 71 | termWeights = zeros(nbr_sp,2); 72 | termWeights_sp = alfa*(-log(Ic/2/T_theory)); 73 | termWeights_sp(Ic>2*T_theory) = 0; 74 | termWeights_tp = alfa*(-log(1 - Ic/2/T_theory)); 75 | termWeights_tp(Ic>2*T_theory) = W; 76 | termWeights(:,1) = real(termWeights_sp); 77 | termWeights(:,2) = real(termWeights_tp); 78 | %% graph-cut; 79 | % use the graphCutMex download from https://github.com/aosokin/graphCutMex_BoykovKolmogorov. 80 | % Yuri Boykov and Vladimir Kolmogorov, An experimental comparison of Min-Cut/Max-Flow algorithms for energy minimization in vision, 81 | % IEEE TPAMI, 26(9):1124-1137, 2004. 82 | addpath('GC'); 83 | [cut, labels] = graphCutMex(termWeights, edgeWeights); 84 | %% CM calculation 85 | idx_img = label2idx(sup_img); 86 | for i = 1:size(delt,2) 87 | index_vector = idx_img{i}; 88 | CM_map(index_vector) = labels(i); 89 | end 90 | CM_map =reshape(CM_map,[size(sup_img,1) size(sup_img,2)]); 91 | -------------------------------------------------------------------------------- /auxi_funcs/Load_dataset.m: -------------------------------------------------------------------------------- 1 | if strcmp(dataset,'#1-Italy') == 1 % Heterogeneous CD of multispectral VS. multispectral 2 | image_t1 = imread('Italy_1.bmp'); 3 | image_t2 = imread('Italy_2.bmp'); 4 | gt = imread('Italy_gt.bmp'); 5 | Ref_gt = gt(:,:,1); 6 | figure; 7 | subplot(131);imshow(image_t1,[]);title('imaget1') 8 | subplot(132);imshow(image_t2,[]);title('imaget2') 9 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 10 | elseif strcmp(dataset,'#2-Texas') == 1 % Heterogeneous CD of multispectral VS. multispectral 11 | load('Cross-sensor-Bastrop-data.mat') 12 | image_t1 = double(t1_L5); 13 | image_t2 = double(t2_ALI); 14 | gt = double(ROI_1); 15 | Ref_gt = gt(:,:,1); 16 | figure; 17 | subplot(131);imshow(2*uint8(image_t1(:,:,[4 3 2])));title('imaget1') 18 | subplot(132);imshow(6*uint16(image_t2(:,:,[5 4 3])));title('imaget2') 19 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 20 | elseif strcmp(dataset,'#3-Img7') == 1 % Heterogeneous CD of multispectral VS. multispectral 21 | image_t1 = imread('Img7-Bc.tif'); 22 | image_t2 = imread('Img7-Ac.tif'); 23 | gt = imread('Img7-C.tif'); 24 | Ref_gt = gt(:,:,1); 25 | image_t1 = image_t1(1:4:end,1:4:end,:); 26 | image_t2 = image_t2(1:4:end,1:4:end,:); 27 | Ref_gt = Ref_gt(1:4:end,1:4:end); 28 | figure; 29 | subplot(131);imshow(image_t1,[]);title('imaget1') 30 | subplot(132);imshow(image_t2,[]);title('imaget2') 31 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 32 | elseif strcmp(dataset,'#4-Img17') == 1 % Heterogeneous CD of multispectral VS. multispectral 33 | image_t1 = imread('Img17-Bc.tif'); 34 | image_t2 = imread('Img17-A.tif'); 35 | gt = imread('Img17-C.tif'); 36 | Ref_gt = gt(:,:,1); 37 | figure; 38 | subplot(131);imshow(image_t1,[]);title('imaget1') 39 | subplot(132);imshow(image_t2,[]);title('imaget2') 40 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 41 | elseif strcmp(dataset,'#5-Shuguang') == 1 % Heterogeneous CD of SAR VS. Optical 42 | image_t1 = imread('shuguang_1.bmp'); 43 | image_t2 = imread('shuguang_2.bmp'); 44 | gt = imread('shuguang_gt.bmp'); 45 | Ref_gt = gt(:,:,1); 46 | figure; 47 | subplot(131);imshow(image_t1,[]);title('imaget1') 48 | subplot(132);imshow(image_t2,[]);title('imaget2') 49 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 50 | elseif strcmp(dataset,'#6-California') == 1 % Heterogeneous CD of SAR VS. Optical 51 | load('California.mat') 52 | image_t1_temp =image_t2; 53 | image_t2 = image_t1; 54 | image_t1 = image_t1_temp; 55 | Ref_gt = gt(:,:,1); 56 | figure; 57 | subplot(131);imshow(image_t1(:,:,[4 3 2])+1,[]);title('imaget1') 58 | subplot(132);imshow(image_t2,[-1 1]);title('imaget2') 59 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 60 | elseif strcmp(dataset,'#7-Img5') == 1 % Heterogeneous CD of SAR VS. Optical 61 | image_t1 = (imread('Img5-Bc.tif')); 62 | image_t2 = (imread('Img5-A.tif')); 63 | gt = imread('Img5-C.tif'); 64 | Ref_gt = gt(:,:,1); 65 | image_t1 = image_t1(1:4:end,1:4:end,:); 66 | image_t2 = image_t2(1:4:end,1:4:end,:); 67 | Ref_gt = Ref_gt(1:4:end,1:4:end); 68 | figure; 69 | subplot(131);imshow(image_t1,[]);title('imaget1') 70 | subplot(132);imshow(image_t2,[]);title('imaget2') 71 | subplot(133);imshow(Ref_gt,[]);title('Refgt') 72 | image_t2 = image_normlized(image_t2,'sar'); 73 | end 74 | image_t1 = double (image_t1); 75 | image_t2 = double (image_t2); -------------------------------------------------------------------------------- /SCASC_demo.m: -------------------------------------------------------------------------------- 1 | %% Sparse Constrained Adaptive Structure Consistency based Unsupervised Image Regression for Heterogeneous Remote Sensing Change Detection 2 | %{ 3 | Code: SCASC - 2021 4 | This is a test program for the Sparse Constrained Adaptive Structure Consistency method (SCASC) for heterogeneous change detection. 5 | 6 | If you use this code for your research, please cite our paper. Thank you! 7 | 8 | Sun, Yuli, et al. "Sparse Constrained Adaptive Structure Consistency based Unsupervised Image Regression for Heterogeneous Remote Sensing Change Detection." 9 | IEEE Transactions on Geoscience and Remote Sensing, Accepted, 2021, 10 | doi:10.1109/TGRS.2021.3110998. 11 | =================================================== 12 | %} 13 | 14 | clear; 15 | close all 16 | addpath(genpath(pwd)) 17 | %% load dataset 18 | % Please note that the forward and backward detection results are not the same. 19 | % When the forward result is not satisfactory, try swapping the input order of image_t1 and image_t2 to get the backward change detection result. 20 | % In the future we will consider fusing the forward and backward results to improve detection performance. 21 | dataset = '#5-Shuguang';% #1-Italy, #2-Texas, #3-Img7, #4-Img17, #5-Shuguang, #6-California, #7-Img5 22 | Load_dataset 23 | fprintf(['\n Data loading is completed...... ' '\n']) 24 | 25 | %% Parameter setting 26 | % With different parameter settings, the results will be a little different 27 | % Ns: the number of superpxiels, A larger Ns will improve the detection granularity, but also increase the running time. 5000 <= Ns <= 20000 is recommended. 28 | % Niter: the maximum number of SCASC iterations, Niter =10 is recommended. 29 | % lamda: sparse regularization parameter, which should be selected according to the proportion of the changed component. 30 | % alfa: balance parameter. The smaller the lambda, the smoother the CM. 0.025<= alfa <=0.1 is recommended. 31 | 32 | opt.Ns = 5000; % The results in the original paper are generated under Ns=10000, but setting Ns=5000 would be much faster. 33 | opt.Niter = 10; 34 | opt.lamda = 0.1; 35 | opt.alfa = 0.05; % for #2-Texas, alfa = 0.01 is better. 36 | 37 | %% SCASC 38 | t_o = clock; 39 | fprintf(['\n SCASC is running...... ' '\n']) 40 | %------------- Preprocessing: Superpixel segmentation and feature extraction---------------% 41 | t_p1 = clock; 42 | Compactness = 1; 43 | [sup_img,Ns] = SuperpixelSegmentation(image_t1,opt.Ns,Compactness); 44 | [t1_feature,t2_feature,norm_par] = MSMfeature_extraction(sup_img,image_t1,image_t2) ;% MVE;MSM 45 | fprintf('\n');fprintf('The computational time of Preprocessing (t_p1) is %i \n', etime(clock, t_p1)); 46 | fprintf(['\n' '====================================================================== ' '\n']) 47 | 48 | %------------- Algorithm 1: Graph Construction---------------% 49 | t_p2 = clock; 50 | Kmax =round(size(t1_feature,2).^0.5); 51 | [Sx] = AdaptiveStructureGraph(t1_feature,Kmax);% 52 | fprintf('\n');fprintf('The computational time of Graph Construction (t_p2) is %i \n', etime(clock, t_p2)); 53 | fprintf(['\n' '====================================================================== ' '\n']) 54 | 55 | %------------- Algorithm 2: Image Regression---------------% 56 | % Sparse constrained adaptive structure consistency based image regression 57 | % image_t1 ----> image_t2 58 | t_p3 = clock; 59 | if opt.Ns <=10000 60 | [regression_t1, delt,RelDiff] = SCASC_IR(t1_feature,t2_feature,Sx,opt);% t1--->t2 61 | elseif opt.Ns >10000 % for large Ns, the preconditioned conjugate gradient method is recommended 62 | [regression_t1, delt,RelDiff] = SCASC_IR_PCG(t1_feature,t2_feature,Sx,opt);% t1--->t2 63 | end 64 | fprintf('\n');fprintf('The computational time of Image Regression (t_p3) is %i \n', etime(clock, t_p3)); 65 | fprintf(['\n' '====================================================================== ' '\n']) 66 | 67 | %------------- Algorithm 3: MRF segmentation---------------% 68 | t_p4 = clock; 69 | [CM_map,labels] = MRFsegmentation(sup_img,opt.alfa,delt); 70 | fprintf('\n');fprintf('The computational time of MRF segmentation (t_p4) is %i \n', etime(clock, t_p4)); 71 | fprintf(['\n' '====================================================================== ' '\n']) 72 | 73 | fprintf('\n');fprintf('The total computational time of SCASC (t_total) is %i \n', etime(clock, t_o)); 74 | %% Displaying results 75 | fprintf(['\n' '====================================================================== ' '\n']) 76 | fprintf(['\n Displaying the results...... ' '\n']) 77 | %---------------------AUC PCC F1 KC ----------------------% 78 | n=500; 79 | Ref_gt = Ref_gt/max(Ref_gt(:)); 80 | DI_tmep = sum(delt.^2,1); 81 | DI = suplabel2DI(sup_img,DI_tmep); 82 | [TPR, FPR]= Roc_plot(DI,Ref_gt,n); 83 | [AUC, Ddist] = AUC_Diagdistance(TPR, FPR); 84 | [tp,fp,tn,fn,fplv,fnlv,~,~,pcc,kappa,imw]=performance(CM_map,1*Ref_gt); 85 | F1 = 2*tp/(2*tp + fp + fn); 86 | result = 'AUC is %4.3f; PCC is %4.3f; F1 is %4.3f; KC is %4.3f \n'; 87 | fprintf(result,AUC,pcc,F1,kappa) 88 | 89 | %------------Regression image, Difference imag and Change map --------------% 90 | figure; plot(FPR,TPR);title('ROC curves'); 91 | [RegImg,~,~] = suplabel2ImFeature(sup_img,regression_t1,size(image_t2,3));% t1--->t2 92 | RegImg = DenormImage(RegImg,norm_par(size(image_t1,3)+1:end)); 93 | figure; 94 | if strcmp(dataset,'#2-Texas') == 1 95 | subplot(131);imshow(6*uint16(RegImg(:,:,[5 4 3])));title('Regression image') 96 | elseif strcmp(dataset,'#6-California') == 1 97 | subplot(131);imshow(RegImg,[-1 1]);title('Regression image') 98 | elseif strcmp(dataset,'#7-Img5') == 1 99 | subplot(131);imshow(uint8(exp(RegImg*3.75+1.8)));title('Regression image') 100 | else 101 | subplot(131);imshow(uint8(RegImg));title('Regression image') 102 | end 103 | subplot(132);imshow(remove_outlier(DI),[]);title('Difference image') 104 | subplot(133);imshow(CM_map,[]);title('Change mape') 105 | 106 | if F1 < 0.3 107 | fprintf('\n');disp('Please exchange the order of the input images OR select the appropriate opt.alfa for SCASC!') 108 | end 109 | --------------------------------------------------------------------------------