├── .editorconfig ├── .gitignore ├── 1-Data_Analysis ├── 1-Data_Representation │ ├── DataSet.xlsx │ └── Quiz_Loading_and_Inspecting_Datasets.m ├── 2-Statistical_Data_Analysis │ ├── Quiz_Detecting_Outliers.m │ ├── Script_standard_deviation_distance.m │ ├── nodetraffic.mat │ └── standard_deviation_distance.m ├── 3-Data_Visualizaiton │ ├── EulerIdentity.mat │ ├── Quiz_Histogram_Plots.m │ └── Quiz_Scatter_Plots.m ├── 4-Dimensionality_Reduction │ ├── DimensionReduction.mat │ ├── Example_1.m │ ├── Example_2_PCA.m │ ├── Example_3_PCA.m │ ├── Quiz_PCA.m │ ├── Script_How_Many_Dimensions_Do_I_Need.m │ └── Script_Plotting_The_Ellipsoid_Fit_To_The_Data.m ├── 5-Data_Classification │ ├── Example_1_Unsupervised_Learning_Kmeans.m │ ├── MahalanobisDistance.m │ ├── Quiz_Smartphone_Activity_Classifier.m │ ├── Script_EstimationErrorPlot.m │ ├── Script_MahalanobisDistance.m │ ├── Script_myfitpca.m │ ├── Script_mypredictpca.m │ ├── myfitpca.m │ └── mypredictpca.m └── 6-Data_Prediction │ ├── EstimationErrorPlot.m │ ├── Quiz_Predicting_Fuel_Efficiency_Using_GPR.m │ ├── Quiz_Predicting_Fuel_Efficiency_Using_RTs.m │ └── Script_EstimationErrorPlot.m ├── 2-Signal_Analysis ├── 1-Signals_as_Time_Dependent_Data │ ├── Example_1.m │ ├── Example_2.m │ └── Script_Making_Waves.m ├── 2-Signal_Interpolation │ ├── Example_1.m │ ├── Script_SignalResample.m │ └── SignalResample.m ├── 3-Audio_Analysis │ ├── Quiz_Reverse_Audio.m │ └── ReverseAudio.mat ├── 4-Convolution_Filtering │ ├── BandPassFilter.m │ ├── GaussianFilter.m │ ├── Script_BandPassFilter.m │ └── Script_GaussianFilter.m ├── 5-Signal_Frequency_Analysis │ ├── MagnitudeSpectrumPlot.m │ ├── Quiz_Filter_Quality_Analysis.m │ ├── Quiz_Spectrum_Plotting.m │ ├── Script_Spectrogram.m │ ├── Script_myfft.m │ ├── Script_myifft.m │ ├── crickets.mat │ ├── myfft.m │ └── myifft.m └── 6-Sampling_and_Aliasing │ ├── IsNyquistSatisfied.m │ └── Script_IsNyquistSatisfied.m ├── 3-Image_Analysis ├── 1-Image_Representation │ ├── Example_1.m │ ├── Example_2.m │ ├── Quiz_Cropping.m │ └── cameraman_anonymized.jpeg ├── 2-Image_Resampling │ ├── Example_1_Resampling.m │ ├── ImageResample.m │ └── Script_ImageResample.m ├── 3-Image_Intensity_and_Color_Distributions │ ├── Example_1_Grayscale_Image.m │ ├── Example_2_Color_Image_RGB.m │ ├── Example_3_Color_Image_HSV.m │ ├── Example_4.m │ ├── Quiz_Color_Images.m │ └── RGB.mat ├── 4-Image_Filtering │ ├── DrawBoxes.m │ ├── Example_1.m │ ├── Example_2.m │ ├── Example_3_Convolution_Based_Filters_Except_Median_Filter.m │ ├── Example_4_Matcing_Filter.m │ ├── GaussianBlur.m │ ├── Quiz_Motion.m │ ├── Script_GaussianBlur.m │ ├── Script_SobelMagnitude.m │ └── SobelMagnitude.m └── 5-Image_Segmentation │ ├── Example_1_Grayscale_Image.m │ ├── Example_2_Color_Image.m │ ├── OtsuThreshold.m │ ├── Quiz_Convex_Hull.m │ ├── Quiz_Erosion_and_Dilation_Morphological_Opening.m │ ├── Script_OtsuThreshold.m │ └── convhull.mat ├── Final_Project ├── AddCoinToCountAndPlot.m ├── Final_project_script_1.m ├── Final_project_script_2.m ├── Final_project_script_3.m ├── MakeCircleMatchingFilter.m ├── Script_AddCoinToCountAndPlot.m └── Script_MakeCircleMatchingFilter.m └── README.md /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs 2 | # editorconfig.org 3 | 4 | 5 | # Use top-most EditorConfig file 6 | root = true 7 | 8 | 9 | [*] 10 | # Unix-style newlines at the bottom of every file 11 | end_of_line = lf 12 | 13 | charset = utf-8 14 | 15 | # Remove any whitespace characters preceding newline characters 16 | trim_trailing_whitespace = true 17 | 18 | insert_final_newline = false 19 | 20 | # Tab indentation 21 | indent_style = space 22 | indent_size = 4 23 | 24 | # Give operators breathing room, but not brackets 25 | spaces_around_operators = true 26 | spaces_around_brackets = false 27 | 28 | 29 | [.js] 30 | quote_type = single 31 | curly_bracket_next_line = false 32 | 33 | 34 | [.html] 35 | quote_type = double 36 | 37 | 38 | [*.{diff, md}] 39 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.asv -------------------------------------------------------------------------------- /1-Data_Analysis/1-Data_Representation/DataSet.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/1-Data_Analysis/1-Data_Representation/DataSet.xlsx -------------------------------------------------------------------------------- /1-Data_Analysis/1-Data_Representation/Quiz_Loading_and_Inspecting_Datasets.m: -------------------------------------------------------------------------------- 1 | num = xlsread('DataSet.xlsx'); 2 | num(13,3) 3 | 4 | % Answer 5 | % 0.15 -------------------------------------------------------------------------------- /1-Data_Analysis/2-Statistical_Data_Analysis/Quiz_Detecting_Outliers.m: -------------------------------------------------------------------------------- 1 | load nodetraffic.mat; 2 | 3 | round(mean(nodetraffic)) 4 | round(std(nodetraffic)) 5 | 6 | % Method I 7 | tic 8 | count1 = 0; 9 | for i = 1 : length(nodetraffic) 10 | if (standard_deviation_distance(nodetraffic, nodetraffic(i)) > 6) 11 | count1 = count1 + 1; 12 | end 13 | end 14 | count1 15 | toc 16 | 17 | %% Method II 18 | tic 19 | A = arrayfun(@(x) standard_deviation_distance(nodetraffic, x), nodetraffic); 20 | count2 = length(A(A > 6)) % Or: count2 = sum(A > 6) 21 | toc 22 | 23 | % Method III 24 | tic 25 | A = (nodetraffic - mean(nodetraffic)) ./ std(nodetraffic); 26 | count3 = sum(A > 6) 27 | toc 28 | 29 | % Answer 30 | % 1) 24 31 | % 2) 9829 32 | % 3) 14009 -------------------------------------------------------------------------------- /1-Data_Analysis/2-Statistical_Data_Analysis/Script_standard_deviation_distance.m: -------------------------------------------------------------------------------- 1 | v = [10 12 14]; 2 | x = 7; 3 | dist = standard_deviation_distance(v, x); % = -2.5 -------------------------------------------------------------------------------- /1-Data_Analysis/2-Statistical_Data_Analysis/nodetraffic.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/1-Data_Analysis/2-Statistical_Data_Analysis/nodetraffic.mat -------------------------------------------------------------------------------- /1-Data_Analysis/2-Statistical_Data_Analysis/standard_deviation_distance.m: -------------------------------------------------------------------------------- 1 | function dist = standard_deviation_distance(v, x) 2 | standard_deviation = std(v); 3 | dist = (x - mean(v)) ./ standard_deviation; 4 | end -------------------------------------------------------------------------------- /1-Data_Analysis/3-Data_Visualizaiton/EulerIdentity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/1-Data_Analysis/3-Data_Visualizaiton/EulerIdentity.mat -------------------------------------------------------------------------------- /1-Data_Analysis/3-Data_Visualizaiton/Quiz_Histogram_Plots.m: -------------------------------------------------------------------------------- 1 | load carbig; 2 | h = histogram(MPG, 'BinLimits', [41,48]); 3 | h.Values 4 | 5 | % Answer 6 | % 7 -------------------------------------------------------------------------------- /1-Data_Analysis/3-Data_Visualizaiton/Quiz_Scatter_Plots.m: -------------------------------------------------------------------------------- 1 | load EulerIdentity.mat; 2 | scatter(x,y); 3 | axis equal; 4 | 5 | % Answer 6 | % exp(j*pi)+1=0 -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/DimensionReduction.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/1-Data_Analysis/4-Dimensionality_Reduction/DimensionReduction.mat -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/Example_1.m: -------------------------------------------------------------------------------- 1 | D = [-5 2.5; 2 -1; 10 -5; -12 6] 2 | v = [2 -1]; 3 | a = [-2.5; 1; 5; -6]; 4 | av = a*v 5 | 6 | figure(1); 7 | plot(D(:,1), D(:,2), 'o'); 8 | axis([-15 15 -15 15]); 9 | xlabel('Feature 1'); 10 | ylabel('Feature 2'); 11 | an = [-10 : 0.25 : 10]; 12 | hold on; 13 | cmap = jet(length(an)); 14 | for i = 1 : length(an) 15 | plot(an(i)*v(1), an(i)*v(2), '*', 'Color', cmap(i,:)); 16 | end -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/Example_2_PCA.m: -------------------------------------------------------------------------------- 1 | D = [5.5 -4; -1.5 2; -9 2; 5 0] 2 | 3 | figure(1); 4 | plot(D(:,1), D(:,2), 'bo', 'LineWidth', 2); 5 | axis([-15 15 -15 15]); 6 | xlabel('Feature 1'); 7 | ylabel('Feature 2'); 8 | axis equal; 9 | hold on; 10 | 11 | [eigvects,~,eigvals] = pca(D); 12 | plot(eigvects(1,1)*[2,-2]*sqrt(eigvals(1)), eigvects(2,1)*[2,-2]*sqrt(eigvals(1)), 'r'); 13 | plot(eigvects(1,2)*[2,-2]*sqrt(eigvals(2)), eigvects(2,2)*[2,-2]*sqrt(eigvals(2)), 'r'); 14 | 15 | theta = [0 : 0.25 : 2*pi]'; 16 | ellipse_x = 2*sqrt(eigvals(1))*eigvects(1,1)*cos(theta) + 2*sqrt(eigvals(2))*eigvects(1,2)*sin(theta); 17 | ellipse_y = 2*sqrt(eigvals(1))*eigvects(2,1)*cos(theta) + 2*sqrt(eigvals(2))*eigvects(2,2)*sin(theta); 18 | plot(ellipse_x, ellipse_y, 'k--'); 19 | 20 | [eigvects,D_pca,eigvals] = pca(D); 21 | % D_pca: the coordinates of the dataset in the PCA vector space, 22 | % where the 1st dimension is the direction of greatest variation, 23 | % the 2nd dimension is the direction orthogonal to the first that has the greatest variance, and so on 24 | % eigvects: define the principal axes (basis vectors) of the greatest variation 25 | % eigvals: define the width of the axes of the PCA ellipsoid (variance) 26 | plot([0;D_pca(1,1)*eigvects(1,1)], [0;D_pca(1,1)*eigvects(2,1)], 'g'); 27 | plot([0;D_pca(1,2)*eigvects(1,2)], [0;D_pca(1,2)*eigvects(2,2)], 'g'); 28 | plot([0;D_pca(1,1)*eigvects(1,1)+D_pca(1,2)*eigvects(1,2)], [0;D_pca(1,1)*eigvects(2,1)+D_pca(1,2)*eigvects(2,2)], 'c'); 29 | 30 | D1d = D_pca(:,1) * eigvects(:,1)' 31 | plot(D1d(:,1), D1d(:,2), 'ro', 'LineWidth', 2); 32 | [eigvects,D_pca,eigvals] = pca(D1d); 33 | eigvals -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/Example_3_PCA.m: -------------------------------------------------------------------------------- 1 | load fisheriris; 2 | D = meas; % [150 x 4] data feature matrix containing 4 features of 150 samples 3 | [eigvects,D_pca,eigvals] = pca(D); 4 | eigvects 5 | eigvals 6 | D_pca_x = D_pca(:,1); 7 | D_pca_y = D_pca(:,2); 8 | plot(D_pca_x,D_pca_y,'*'); 9 | hold on; 10 | theta = 2*pi*[0:100]/100; 11 | ellipse_x = 2*sqrt(eigvals(1))*cos(theta); 12 | ellipse_y = 2*sqrt(eigvals(2))*sin(theta); 13 | plot(ellipse_x, ellipse_y, 'k--'); 14 | axis equal; -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/Quiz_PCA.m: -------------------------------------------------------------------------------- 1 | load DimensionReduction.mat; 2 | [~,D_pca] = pca(dataset); 3 | round(max(D_pca(:,1))) 4 | round(max(D_pca(:,2))) 5 | scatter(D_pca(:,1), D_pca(:,2)); 6 | 7 | % Answer 8 | % 1) 120 9 | % 2) 12 10 | % 3) exp(j*pi)+1=0 -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/Script_How_Many_Dimensions_Do_I_Need.m: -------------------------------------------------------------------------------- 1 | load humanactivity.mat; 2 | D = feat; % [24075 x 60] matrix containing 60 feature measurements from 24075 samples 3 | 4 | % Compute eigvals 5 | [~,~,eigvals] = pca(D); 6 | 7 | % Compute the cumulative_percent_variance_permode vector. 8 | cumulative_percent_variance_permode = cumsum(eigvals/sum(eigvals)) * 100; 9 | 10 | % Define N as the number of eigenvectors needed to capture at least 99.9% of the variation in D 11 | N = find(cumulative_percent_variance_permode > 99.9, 1, 'first'); -------------------------------------------------------------------------------- /1-Data_Analysis/4-Dimensionality_Reduction/Script_Plotting_The_Ellipsoid_Fit_To_The_Data.m: -------------------------------------------------------------------------------- 1 | load fisheriris; 2 | D = meas; % [150 x 4] data feature matrix containing 4 features of 150 samples 3 | 4 | % Compute D_pca and eigvals using the pca function 5 | [~,D_pca,eigvals] = pca(D); 6 | 7 | % Define D_pca_x and D_pca_y, the first two dimensions of the data in the D_pca feature space 8 | D_pca_x = D_pca(:,1); 9 | D_pca_y = D_pca(:,2); 10 | 11 | % Scatter plot the data with asterisks '*' 12 | plot(D_pca_x, D_pca_y, '*'); 13 | 14 | % Define ellipse_x and ellipse_y, x and y coordinates for the PCA ellipsoid in the first 2 dimensions as a function of theta 15 | theta = 2*pi*[0:100]/100; 16 | ellipse_x = 2*sqrt(eigvals(1))*cos(theta); 17 | ellipse_y = 2*sqrt(eigvals(2))*sin(theta); 18 | 19 | % Plot the ellipse with red dashed lines 'r--' 20 | hold on; 21 | plot(ellipse_x, ellipse_y, 'r--'); 22 | 23 | % Use axis equal to correct aspect ratio 24 | axis equal; -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/Example_1_Unsupervised_Learning_Kmeans.m: -------------------------------------------------------------------------------- 1 | load fisheriris; 2 | [~,~,s] = unique(species); 3 | [~,D_pca] = pca(meas); 4 | 5 | figure(1); 6 | plot(D_pca(s==1,1), D_pca(s==1,2), 'rx'); 7 | hold on; 8 | plot(D_pca(s==2,1), D_pca(s==2,2), 'go'); 9 | plot(D_pca(s==3,1), D_pca(s==3,2), 'b*'); 10 | xlabel('PCA Feature 1'); 11 | ylabel('PCA Feature 2'); 12 | axis equal; 13 | 14 | [X,Y] = meshgrid([-4:0.01:4],[-2:0.01:2]); 15 | 16 | % ------------------------------------------------------------------ 17 | 18 | rng(0); [cls,C] = kmeans(D_pca(:,1:2), 3); 19 | plot(C(:,1), C(:,2), 'ko', 'LineWidth', 3); 20 | 21 | dist1 = sqrt((C(1,1)-X).^2 + (C(1,2)-Y).^2); 22 | dist2 = sqrt((C(2,1)-X).^2 + (C(2,2)-Y).^2); 23 | dist3 = sqrt((C(3,1)-X).^2 + (C(3,2)-Y).^2); 24 | cls3 = (dist3 < dist1) & (dist3 < dist2); 25 | cls2 = ~cls3 & (dist2 < dist1); 26 | cls1 = ~cls3 & ~cls2; 27 | contour(X, Y, cls1, [1 1], 'k--'); 28 | contour(X, Y, cls2, [1 1], 'k--'); 29 | contour(X, Y, cls3, [1 1], 'k--'); 30 | [cls s] 31 | accuracy = sum((4-cls) == s) / length(s) * 100 32 | 33 | % ------------------------------------------------------------------ 34 | 35 | C = [mean(D_pca(s==1,:)); mean(D_pca(s==2,:)); mean(D_pca(s==3,:))]; 36 | plot(C(:,1), C(:,2), 'mo', 'LineWidth', 3); 37 | 38 | dist1 = sqrt((C(1,1)-D_pca(:,1)).^2 + (C(1,2)-D_pca(:,2)).^2); 39 | dist2 = sqrt((C(2,1)-D_pca(:,1)).^2 + (C(2,2)-D_pca(:,2)).^2); 40 | dist3 = sqrt((C(3,1)-D_pca(:,1)).^2 + (C(3,2)-D_pca(:,2)).^2); 41 | cls3 = (dist3 < dist1) & (dist3 < dist2); 42 | cls2 = ~cls3 & (dist2 < dist1); 43 | cls1 = ~cls3 & ~cls2; 44 | cls = 3*cls3 + 2*cls2 + 1*cls1; 45 | accuracy = sum(cls == s) / length(s) * 100 -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/MahalanobisDistance.m: -------------------------------------------------------------------------------- 1 | function [md,b,std_per_mode] = MahalanobisDistance(pcamdl,v) 2 | % compute b, our PCA coordinates for v 3 | b = pcamdl.eigvects * (v - pcamdl.mu)'; 4 | % compute std_per_mode, the standard deviation distance from the mean for v for each mode of variation 5 | std_per_mode = abs(b)./sqrt(pcamdl.eigvals); 6 | % compute md, the Mahalanobis distance 7 | md = sqrt(sum(std_per_mode.^2)); 8 | end -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/Quiz_Smartphone_Activity_Classifier.m: -------------------------------------------------------------------------------- 1 | load humanactivity; 2 | D_train = feat(1:2:end,:); 3 | class_train = actid(1:2:end); 4 | D_test = feat(2:2:end,:); 5 | class_test = actid(2:2:end); 6 | 7 | % Method I 8 | mdl1 = myfitpca(D_train, class_train); 9 | [class_est1, score_est1] = mypredictpca(mdl1, D_test); 10 | accuracy1 = sum(class_est1 == class_test) / length(class_est1) * 100 11 | figure(1); 12 | EstimationErrorPlot(class_est1,class_test); 13 | 14 | % Method II 15 | mdl2 = fitlm(D_train, class_train); 16 | class_est2 = round(predict(mdl2, D_test)); 17 | accuracy2 = sum(class_est2 == class_test) / length(class_est2) * 100 18 | figure(2); 19 | EstimationErrorPlot(class_est2,class_test); 20 | 21 | function [mse,R,p,rg] = EstimationErrorPlot(prediction,target) 22 | mse = mean((target-prediction).^2); 23 | figure; 24 | plot(target,prediction,'r*'); 25 | hold on; 26 | xlabel('True Value'); 27 | ylabel('Mean Predicted Value'); 28 | rg = [min([prediction;target]),max([prediction;target])]; 29 | plot(rg,rg,'k--'); 30 | [R,p] = corr(target,prediction); % R: correlation coefficient (from -1 to 1); p: statistical significance 31 | title(sprintf('R=%.3f, p=%.3g, mse=%.3f', R, p, mse)); 32 | legend('True vs. Predicted','Diagonal','Location','SouthEast'); 33 | end 34 | 35 | % Answer 36 | % 96.93 -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/Script_EstimationErrorPlot.m: -------------------------------------------------------------------------------- 1 | load fisheriris; 2 | D_train = meas(1:2:end,:); 3 | D_test = meas(2:2:end,:); 4 | mdl = fitlm(D_train(:,1:3), D_train(:,4)); 5 | prediction = predict(mdl, D_test(:,1:3)); 6 | [mse,R,p,rg] = EstimationErrorPlot(prediction, D_test(:,4)); -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/Script_MahalanobisDistance.m: -------------------------------------------------------------------------------- 1 | mdl.class(1).eigvects = [0.7071 0.7071]; 2 | mdl.class(1).eigvals = 4; 3 | mdl.class(1).mu = [2 2]; 4 | v = [2,2]; 5 | md = MahalanobisDistance(mdl.class(1),v) % md = 0 because v = mu 6 | v = [2,2] + 2*[0.7071 0.7071]; 7 | md = MahalanobisDistance(mdl.class(1),v) % md = 1 because v is 2/sqrt(eigval)=2/2=1 standard deviations from mean along eigenvector 8 | v = [2,2] - 6*[0.7071 0.7071]; 9 | md = MahalanobisDistance(mdl.class(1),v) % md = 3 because v is 6/sqrt(eigval)=6/2=3 standard deviations from mean along eigenvector 10 | v = [2,2] + [-0.7071 0.7071]; 11 | md = MahalanobisDistance(mdl.class(1),v) % md = 0 because v lies in a direction from mu that is orthogonal to the eigenvector -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/Script_myfitpca.m: -------------------------------------------------------------------------------- 1 | D = [1 3 2 4; 1 3 4 5]'; 2 | class = [0; 0; 1; 1]; 3 | mdl = myfitpca(D,class); 4 | mdl.class(1) % eigvects: [0.7071 0.7071]; eigvals: 4; mu: [2 2]; 5 | mdl.class(2) % eigvects: [0.8944 0.4472]; eigvals: 2.5000; mu: [3 4.5000]; 6 | 7 | D = [1 3 2 4 5; 1 3 4 5 6; 6 3 2 1 7]'; 8 | class = [0; 0; 1; 1; 2]; 9 | mdl = myfitpca(D,class); 10 | mdl.class(1) % eigvects: [-0.4851 -0.4851 0.7276]; eigvals: 8.5000; mu: [2 2 4.5000] 11 | mdl.class(2) % eigvects: [0.8165 0.4082 -0.4082]; eigvals: 3.0000; mu: [3 4.5000 1.5000] 12 | mdl.class(3) % eigvects: [0×3 double]; eigvals: [0×1 double]; mu: [5 6 7] (We get empty eigvects and eigvals because with only one datapoint, there is no variability from the mean!) 13 | -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/Script_mypredictpca.m: -------------------------------------------------------------------------------- 1 | load fisheriris; 2 | [~,~,class] = unique(species); 3 | 4 | % Split into 50/50 training and testing data 5 | D_train = meas(1:2:end,:); 6 | class_train = class(1:2:end); 7 | D_test = meas(2:2:end,:); 8 | class_test = class(2:2:end); 9 | 10 | % Create pca model struct with pca model for each class using the training set (This is what 'myfitpca' would do) 11 | for i = 1 : 3 12 | [eigvects,~,eigvals,~,~,mu] = pca(D_train(class_train==i,:)); 13 | mdl.class(i).eigvects = eigvects; 14 | mdl.class(i).eigvals = eigvals; 15 | mdl.class(i).mu = mu; 16 | end 17 | 18 | % Use our new function to estimate classification on the testing set 19 | [class_est, score_est] = mypredictpca(mdl,D_test); 20 | sum(class_est == class_test) / length(class_est)*100 % We should find 97.3333% classification accuracy! -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/myfitpca.m: -------------------------------------------------------------------------------- 1 | function mdl = myfitpca(D,class) 2 | % Find the number of unique classes from the class vector, numclasses 3 | class_labels = unique(class); 4 | numclasses = length(class_labels); 5 | % For each class, use 'pca' to find the eigenvectors (1st output), 6 | % eigenvalues (3rd output), and mean feature vector (6th output), 7 | % create a subfield 'class' within the output struct mdl, which is a vector of length numclasses 8 | % mdl.class(i) has subfields 'eigvects' (the eigenvectors matrix output from 'pca', transposed), 9 | % 'eigvals' (the eigenvalues output from 'pca'), and 10 | % 'mu' (the mean feature vector) 11 | for i = 1:numclasses 12 | [eigvects,~,eigvals,~,~,mu] = pca(D(class == class_labels(i),:)); 13 | mdl.class(i).eigvects = eigvects'; 14 | mdl.class(i).eigvals = eigvals; 15 | mdl.class(i).mu = mu; 16 | end 17 | end -------------------------------------------------------------------------------- /1-Data_Analysis/5-Data_Classification/mypredictpca.m: -------------------------------------------------------------------------------- 1 | function [class,score] = mypredictpca(mdl,data) 2 | % Initialize output 'class' and 'score' to r x 1 zero vectors 3 | [r,~] = size(data); 4 | class = zeros(r,1); 5 | score = zeros(r,1); 6 | % Loop over the r samples, to classify each 'i'th sample 7 | % In a nested loop, loop over each 'j'th class to compare the 'i'th sample to the 'j'th class 8 | % Within the loop, find the Mahalanobis distance from the 'i'th sample feature vector to the 'j'th class pca model 9 | % The minimium Mahalanobis distance across the class pca models is used to choose our classification for the 'i'th sample 10 | % The classification and the Mahalanobis distance are stored in class(i) and score(i) 11 | for i = 1 : r 12 | mdscore = zeros(1,length(mdl.class)); 13 | for j = 1 : length(mdl.class) 14 | mdscore(j) = MahalanobisDistance(mdl.class(j),data(i,:)); 15 | end 16 | [score(i),class(i)] = min(mdscore); 17 | end 18 | end -------------------------------------------------------------------------------- /1-Data_Analysis/6-Data_Prediction/EstimationErrorPlot.m: -------------------------------------------------------------------------------- 1 | function [mse, R, p, rg] = EstimationErrorPlot(prediction, target) 2 | mse = mean((target-prediction).^2); 3 | figure; 4 | plot(target, prediction, 'r*'); 5 | hold on; 6 | xlabel('True Value'); 7 | ylabel('Mean Predicted Value'); 8 | rg = [min([prediction;target]), max([prediction;target])]; 9 | plot(rg,rg,'k--'); 10 | [R,p] = corr(target, prediction); % R: correlation coefficient (from -1 to 1); p: statistical significance 11 | title(sprintf('R=%.3f, p=%.3g, mse=%.3f', R, p, mse)); 12 | legend('True vs. Predicted','Diagonal', 'Location', 'SouthEast'); 13 | end -------------------------------------------------------------------------------- /1-Data_Analysis/6-Data_Prediction/Quiz_Predicting_Fuel_Efficiency_Using_GPR.m: -------------------------------------------------------------------------------- 1 | load carbig; 2 | D = [Acceleration, Cylinders, Displacement, Horsepower, Model_Year, Weight]; 3 | y = MPG; 4 | msk = ~ismissing(y); 5 | D = D(msk,:); 6 | y = y(msk); 7 | 8 | D_train = D(1:2:end,:); 9 | y_train = y(1:2:end); 10 | 11 | D_test = D(2:2:end,:); 12 | y_test = y(2:2:end); 13 | rng(0); 14 | 15 | mdl = fitrgp(D_train, y_train, ... 16 | 'OptimizeHyperparameters', 'auto', ... 17 | 'HyperparameterOptimizationOptions', struct('AcquisitionFunctionName','expected-improvement-plus')); 18 | ypred = predict(mdl, D_test); 19 | EstimationErrorPlot(ypred, y_test); 20 | 21 | % Answer 22 | % 1) fitrgp 23 | % 2) 8.56 24 | % 3) Gaussian Process Regression -------------------------------------------------------------------------------- /1-Data_Analysis/6-Data_Prediction/Quiz_Predicting_Fuel_Efficiency_Using_RTs.m: -------------------------------------------------------------------------------- 1 | load carbig; 2 | D = [Acceleration, Cylinders, Displacement, Horsepower, Model_Year, Weight]; 3 | y = MPG; 4 | msk = ~ismissing(y); 5 | D = D(msk,:); 6 | y = y(msk); 7 | 8 | D_train = D(1:2:end,:); 9 | y_train = y(1:2:end); 10 | 11 | D_test = D(2:2:end,:); 12 | y_test = y(2:2:end); 13 | rng(0); 14 | 15 | mdl = fitrtree(D_train, y_train, 'OptimizeHyperparameters', 'auto'); 16 | ypred = predict(mdl, D_test); 17 | EstimationErrorPlot(ypred, y_test); 18 | 19 | % Answer 20 | % 1) fitrtree 21 | % 2) 9.15 -------------------------------------------------------------------------------- /1-Data_Analysis/6-Data_Prediction/Script_EstimationErrorPlot.m: -------------------------------------------------------------------------------- 1 | load fisheriris; 2 | D_train = meas(1:2:end,:); 3 | D_test = meas(2:2:end,:); 4 | mdl = fitlm(D_train(:,1:3), D_train(:,4)); 5 | prediction = predict(mdl, D_test(:,1:3)); 6 | [mse, R, p, rg] = EstimationErrorPlot(prediction, D_test(:,4)); -------------------------------------------------------------------------------- /2-Signal_Analysis/1-Signals_as_Time_Dependent_Data/Example_1.m: -------------------------------------------------------------------------------- 1 | T = 100; % seconds 2 | t = 0:T; 3 | f = 1/100; 4 | a = 2*pi*f; 5 | for i = 1 : 50 6 | phs = i/50; 7 | y = cos(a*t + 2*pi*phs); 8 | plot(t, y, 'o'); 9 | xlabel('t (seconds)'); 10 | ylabel(['cos(a*t + 2\pi*', sprintf(' %1.2f)', phs)]); 11 | drawnow; 12 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/1-Signals_as_Time_Dependent_Data/Example_2.m: -------------------------------------------------------------------------------- 1 | T = 100; % seconds 2 | t = 0:T; 3 | f = 5/100; 4 | a = 2*pi*f; 5 | y = cos(a*t); 6 | plot(t,y,'bx'); 7 | xlabel('t (seconds)'); 8 | ylabel('y(t)'); 9 | 10 | hold on; 11 | 12 | t2 = 0:0.5:T; 13 | y2 = cos(a*t2); 14 | plot(t2,y2,'ro'); 15 | 16 | -------------------------------------------------------------------------------- /2-Signal_Analysis/1-Signals_as_Time_Dependent_Data/Script_Making_Waves.m: -------------------------------------------------------------------------------- 1 | % Creates an audio signal by combining 6 pure tones 2 | 3 | % Define T, Fs, and f (vector of sound frequencies) 4 | T = 3; 5 | Fs = 44100; % sampling frequency 6 | f = [330 247 208 165 123 82]; % Hz 7 | 8 | % Compute time vector t (spans [0,3) seconds) 9 | t = [0:1/Fs:T-(1/Fs)]; 10 | 11 | % Use a for-loop to construct y as a sum of cosines 12 | y = 0; 13 | for i = 1 : length(f) 14 | a = 2*pi*f(i); 15 | y = y + cos(a*t); % amplitude = 1, phase = 0 16 | end 17 | figure(1); 18 | plot(t,y); 19 | xlabel('t (seconds)'); 20 | ylabel('y(t)'); 21 | 22 | duration = length(y) / Fs; 23 | fprintf("The audio signal will last for %.1f seconds.\n", duration); 24 | soundsc(y,Fs); -------------------------------------------------------------------------------- /2-Signal_Analysis/2-Signal_Interpolation/Example_1.m: -------------------------------------------------------------------------------- 1 | t = [0:7]; 2 | rng(0); y = randn(size(t)); 3 | plot(t,y,'ko'); 4 | axis([-2 9 -3 7]); 5 | xlabel('Days recording % \Deltastock value'); 6 | ylabel('% \Deltastock value'); 7 | 8 | t_interpolated = [0:0.01:7]; 9 | y_spline_int = interp1(t,y,t_interpolated,'spline'); 10 | hold on; 11 | plot(t_interpolated,y_spline_int,'r'); 12 | 13 | t_extrapolated = [-2:0.01:9]; 14 | y_spline_ext = interp1(t,y,t_extrapolated,'spline'); 15 | plot(t_extrapolated,y_spline_ext,'r'); 16 | 17 | y_pchip = interp1(t,y,t_extrapolated,'pchip'); 18 | plot(t_extrapolated,y_pchip,'g'); 19 | 20 | y_lin = interp1(t,y,t_extrapolated,'linear'); 21 | plot(t_extrapolated,y_lin,'b'); 22 | 23 | legend('data','spline (interpolated)','spline (extrapolated)','pchip','linear'); -------------------------------------------------------------------------------- /2-Signal_Analysis/2-Signal_Interpolation/Script_SignalResample.m: -------------------------------------------------------------------------------- 1 | x = [1:0.5:5.5]; 2 | xFs = 2; 3 | yFs = 4; 4 | y = SignalResample(x, xFs, yFs); 5 | 6 | x = [1:0.5:5.5]; 7 | xFs = 2; 8 | yFs = 1; 9 | y = SignalResample(x, xFs, yFs); -------------------------------------------------------------------------------- /2-Signal_Analysis/2-Signal_Interpolation/SignalResample.m: -------------------------------------------------------------------------------- 1 | function y = SignalResample(x, xFs, yFs) 2 | 3 | % Find the total time duration 'T' 4 | T = (length(x) - 1) / xFs; 5 | 6 | % Using 'T', define a time vector 'tx' 7 | tx = [0:1/xFs:T]; 8 | 9 | % Using 'T', define the new time vector, 'ty' for our resampled time. 10 | ty = [0:1/yFs:T]; 11 | 12 | % Use interp1 to create y by resampling x 13 | y = interp1(tx,x,ty,'linear'); 14 | 15 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/3-Audio_Analysis/Quiz_Reverse_Audio.m: -------------------------------------------------------------------------------- 1 | load ReverseAudio.mat; 2 | 3 | y = ReverseAudio(y_rev); 4 | soundsc(y, Fs); 5 | [~,index] = max(y); 6 | 7 | function signal_rev = ReverseAudio(signal) 8 | [r,c] = size(signal); 9 | if (c == 1) % column vector 10 | signal_rev = flipud(signal); 11 | end 12 | if (r == 1) % row vector 13 | signal_rev = fliplr(signal); 14 | end 15 | end 16 | 17 | % Answer 18 | % matlab or 143068 -------------------------------------------------------------------------------- /2-Signal_Analysis/3-Audio_Analysis/ReverseAudio.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/2-Signal_Analysis/3-Audio_Analysis/ReverseAudio.mat -------------------------------------------------------------------------------- /2-Signal_Analysis/4-Convolution_Filtering/BandPassFilter.m: -------------------------------------------------------------------------------- 1 | function y = BandPassFilter(x, Fs, freq_range, W) 2 | % Create the filter using 'fir1' (freq_range need to be divided by Fs/2 to convert to normalized frequencies) 3 | filter = fir1(W,freq_range/(Fs/2),'bandpass'); 4 | 5 | % Apply the filter using 'conv' 6 | y = conv(x,filter,'same'); 7 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/4-Convolution_Filtering/GaussianFilter.m: -------------------------------------------------------------------------------- 1 | function y = GaussianFilter(x, sigma) 2 | % Compute W by rounding up 6*sigma 3 | W = ceil(6*sigma); 4 | 5 | % Use fspecial to create our Gaussian filter 6 | gaussianfilter = fspecial('gaussian',[1,W],sigma); 7 | 8 | % Convolve the signal with the filter 9 | y = conv(x,gaussianfilter,'same'); 10 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/4-Convolution_Filtering/Script_BandPassFilter.m: -------------------------------------------------------------------------------- 1 | Fs = 10; 2 | x1 = repmat([1 0 -1 0],[1,10]); % This is a 2.5 Hz signal 3 | x2 = repmat([1 -1],[1,20]); % This is a 5 Hz signal 4 | x = x1 + x2; 5 | freq_range = [2,3]; % filter out the 5 Hz but keep the 2.5 Hz component 6 | W = 10; 7 | 8 | y = BandPassFilter(x, Fs, freq_range, W); 9 | 10 | % plot x1, x2, x=x1+x2, and BandPassFilter output 11 | t = 0 : 1/Fs : (length(y)-1)/Fs; 12 | plot(t(1:Fs),x1(1:Fs),'bo-'); 13 | hold on; 14 | plot(t(1:Fs),x2(1:Fs),'r*-'); 15 | plot(t(1:Fs),x(1:Fs),'g'); 16 | plot(t(1:Fs),y(1:Fs),'m--', 'LineWidth', 2); 17 | legend('x1-2.5Hz','x2-5.0Hz','x=x1+x2','output'); -------------------------------------------------------------------------------- /2-Signal_Analysis/4-Convolution_Filtering/Script_GaussianFilter.m: -------------------------------------------------------------------------------- 1 | x = [0 0 0 1 0 0 0]; 2 | sigma = 1.5; 3 | y = GaussianFilter(x, sigma); -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/MagnitudeSpectrumPlot.m: -------------------------------------------------------------------------------- 1 | function MagnitudeSpectrumPlot(yfft, f, col) 2 | if (nargin < 3) 3 | col = 'b'; 4 | end 5 | figure; 6 | plot(f, abs(yfft), col); 7 | xlabel('frequency (Hz)'); 8 | ylabel('|Y(f)|'); 9 | title('Magnitude Spectrum'); 10 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/Quiz_Filter_Quality_Analysis.m: -------------------------------------------------------------------------------- 1 | Fs = 1000; 2 | freq_range = [100,200]; 3 | 4 | filt10 = fir1(10, freq_range/(Fs/2)); 5 | filt100 = fir1(100, freq_range/(Fs/2)); 6 | filt1000 = fir1(1000, freq_range/(Fs/2)); 7 | 8 | [yfft, f] = myfft(filt10, Fs); 9 | MagnitudeSpectrumPlot(yfft, f, '*'); 10 | % check Y near X = 90 11 | [~,i] = min(abs(f-90)); 12 | abs(yfft(i)) 13 | 14 | [yfft, f] = myfft(filt100, Fs); 15 | MagnitudeSpectrumPlot(yfft, f, '*'); 16 | % check Y near X = 90 17 | [~,i] = min(abs(f-90)); 18 | abs(yfft(i)) 19 | 20 | [yfft, f] = myfft(filt1000, Fs); 21 | MagnitudeSpectrumPlot(yfft, f, '*'); 22 | % check Y near X = 90 23 | [~,i] = min(abs(f-90)); 24 | abs(yfft(i)) 25 | 26 | % Answer 27 | % 1) 0.7722 28 | % 2) 0.0594 29 | % 3) 6.8140e-04 -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/Quiz_Spectrum_Plotting.m: -------------------------------------------------------------------------------- 1 | load crickets.mat; 2 | soundsc(crickets, Fs); 3 | [yfft, f] = myfft(crickets, Fs); 4 | MagnitudeSpectrumPlot(yfft, f, '*'); 5 | 6 | % Answer 7 | % VU -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/Script_Spectrogram.m: -------------------------------------------------------------------------------- 1 | % loads gong sound y and sampling frequency Fs 2 | load gong; 3 | 4 | soundsc(y(1:4*Fs),Fs); 5 | 6 | % call spectrogram to get s,f,t 7 | [s,f,t] = spectrogram(y,256,[],[],Fs); 8 | 9 | % use imagesc to display it 10 | imagesc(f,t,log(abs(s'))); 11 | 12 | colorbar; 13 | axis xy; 14 | xlabel('Frequency (Hz)'); 15 | ylabel('Time (s)'); -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/Script_myfft.m: -------------------------------------------------------------------------------- 1 | % Even length y 2 | Fs = 10; 3 | y = [0 0 0 0 1 0 0 0 0 0]'; 4 | [yfft, f] = myfft(y,Fs); 5 | abs(yfft') 6 | 7 | % Odd length y 8 | Fs = 10; 9 | y = [0 0 0 0 1 0 0 0 0]'; 10 | [yfft, f] = myfft(y,Fs); 11 | abs(yfft') 12 | 13 | f' % You should get 0:10/9:40/9 -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/Script_myifft.m: -------------------------------------------------------------------------------- 1 | % Even length y 2 | Fs = 10; 3 | yfft = [0 0 1 0 0 0 0 0 0 0]'; 4 | f = 0:5; 5 | y = myifft(yfft,Fs,f); 6 | t = 0 : 1/Fs : (length(y)-1)/Fs; 7 | plot(t,y); 8 | yEven = y' % = [0.1053 0.0831 0.0258 -0.0423 -0.0926 ...] 9 | 10 | % Odd length y 11 | Fs = 10; 12 | yfft = [0 0 1 0 0 0 0 0 0]'; 13 | f = 0 : 10/9 : 40/9; 14 | y = myifft(yfft,Fs,f); 15 | t = 0 : 1/Fs : (length(y)-1)/Fs; 16 | figure; 17 | plot(t,y); 18 | yOdd = y' % = [ 0.1176 0.0869 0.0109 -0.0709 -0.1156 ...] -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/crickets.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/2-Signal_Analysis/5-Signal_Frequency_Analysis/crickets.mat -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/myfft.m: -------------------------------------------------------------------------------- 1 | function [yfft, f] = myfft(y, Fs) 2 | % compute the standard fft 3 | yfft = fft(y); 4 | 5 | % trim away the redundant part 6 | yfft = yfft(1:ceil((length(y)+1)/2)); 7 | 8 | % compute the frequencies to which each fft entry corresponds 9 | samplenum = [0:(length(yfft)-1)]'; 10 | f = samplenum*Fs/length(y); % convert sample numbers to hertz (1/s) 11 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/5-Signal_Frequency_Analysis/myifft.m: -------------------------------------------------------------------------------- 1 | function y = myifft(yfft, f, Fs) 2 | % Replace redundant part of the fft that we trimmed away: 3 | % if the last frequency in f equals Fs/2, 4 | if (f(end) == Fs/2) 5 | % then we need to append the conjugate of the mirrored entries in yfft from 2 to length of yfft minus 1 6 | y = [yfft; conj(flipud(yfft(2:end-1)))]; 7 | else 8 | % then we need to append the conjugate of the mirrored entries in yfft from 2 to length of yfft 9 | y = [yfft; conj(flipud(yfft(2:end)))]; 10 | end 11 | 12 | % Perform ifft 13 | y = ifft(y); 14 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/6-Sampling_and_Aliasing/IsNyquistSatisfied.m: -------------------------------------------------------------------------------- 1 | function [y,Fs_min] = IsNyquistSatisfied(fmax,Fs) 2 | Fs_min = 2*fmax; 3 | if (Fs > Fs_min) 4 | y = true; 5 | else 6 | y = false; 7 | end 8 | end -------------------------------------------------------------------------------- /2-Signal_Analysis/6-Sampling_and_Aliasing/Script_IsNyquistSatisfied.m: -------------------------------------------------------------------------------- 1 | fmax = 16000; 2 | Fs = 28800; 3 | [y,Fs_min] = IsNyquistSatisfied(fmax,Fs); % false, with Fs_min = 32000 4 | 5 | fmax = 16000; 6 | Fs = 44100; 7 | [y,Fs_min] = IsNyquistSatisfied(fmax,Fs); % true, with Fs_min = 32000 -------------------------------------------------------------------------------- /3-Image_Analysis/1-Image_Representation/Example_1.m: -------------------------------------------------------------------------------- 1 | r = 10; 2 | c = 15; 3 | img = zeros(r,c); 4 | for i = 1 : r 5 | for j = 1 : c 6 | img(i,j) = i*j; 7 | end 8 | end 9 | img 10 | 11 | figure(1); 12 | imagesc(img); 13 | colorbar; 14 | xlabel('columns'); 15 | ylabel('rows'); 16 | 17 | figure(2); 18 | imagesc(img); 19 | colorbar; 20 | colormap(gray); 21 | xlabel('columns'); 22 | ylabel('rows'); -------------------------------------------------------------------------------- /3-Image_Analysis/1-Image_Representation/Example_2.m: -------------------------------------------------------------------------------- 1 | img = imread('cameraman.tif'); % requires Image Processing Toolbox 2 | imagesc(img); 3 | colormap(gray); 4 | axis equal; 5 | img(40:75,100:135) = 127; 6 | imagesc(img); 7 | axis equal; 8 | imwrite(img, 'cameraman_anonymized.jpeg'); -------------------------------------------------------------------------------- /3-Image_Analysis/1-Image_Representation/Quiz_Cropping.m: -------------------------------------------------------------------------------- 1 | img = imread('logo.tif'); 2 | figure; 3 | imagesc(img(30:50, 20:90)); 4 | 5 | % Answer 6 | % MATH -------------------------------------------------------------------------------- /3-Image_Analysis/1-Image_Representation/cameraman_anonymized.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/3-Image_Analysis/1-Image_Representation/cameraman_anonymized.jpeg -------------------------------------------------------------------------------- /3-Image_Analysis/2-Image_Resampling/Example_1_Resampling.m: -------------------------------------------------------------------------------- 1 | img = imread('cameraman.tif'); 2 | figure('Name','Original','NumberTitle','off'); 3 | imagesc(img); 4 | colormap(gray); 5 | 6 | nr = 1000; 7 | nc = 1500; 8 | [r,c] = size(img); 9 | [C,R] = meshgrid(1:(c-1)/(nc-1):c, 1:(r-1)/(nr-1):r); 10 | upsimg = interp2(double(img), C, R, 'linear'); 11 | figure('Name','Upsampled','NumberTitle','off'); 12 | imagesc(upsimg); 13 | colormap(gray); 14 | 15 | face = img(40:85,90:135); 16 | nr = 10; 17 | nc = 10; 18 | [r,c] = size(face); 19 | [C,R] = meshgrid(1:(c-1)/(nc-1):c, 1:(r-1)/(nr-1):r); 20 | downface = interp2(double(face), C, R, 'linear'); 21 | [C,R] = meshgrid(1:(nc-1)/(c-1):nc, 1:(nr-1)/(r-1):nr); 22 | anonface = interp2(double(downface), C, R, 'linear'); 23 | img(40:85,90:135) = anonface; 24 | figure('Name','Pixelated Face','NumberTitle','off'); 25 | imagesc(img); 26 | colormap(gray); -------------------------------------------------------------------------------- /3-Image_Analysis/2-Image_Resampling/ImageResample.m: -------------------------------------------------------------------------------- 1 | function img_resample = ImageResample(img, dim) 2 | % define r,c,nr,nc 3 | [r,c] = size(img); 4 | nr = dim(1); 5 | nc = dim(2); 6 | 7 | % use the meshgrid function to determine sampling coordinates 8 | [C,R] = meshgrid(1:(c-1)/(nc-1):c, 1:(r-1)/(nr-1):r); 9 | 10 | % use interp2 to interpolate 11 | img_resample = interp2(double(img), C, R, 'linear'); 12 | end -------------------------------------------------------------------------------- /3-Image_Analysis/2-Image_Resampling/Script_ImageResample.m: -------------------------------------------------------------------------------- 1 | [C,R] = meshgrid(1:10,1:15); % inputs are ordered columns, then rows 2 | img = uint8(C.*R); 3 | size(img) % = 15 x 10 4 | dim = [20;25]; 5 | img_resample = ImageResample(img, dim); 6 | size(img_resample) % = 20 x 25 7 | imagesc(img); 8 | figure; 9 | imagesc(img_resample); -------------------------------------------------------------------------------- /3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/Example_1_Grayscale_Image.m: -------------------------------------------------------------------------------- 1 | img = imread('tire.tif'); 2 | 3 | subplot(2,2,1); 4 | imagesc(img); 5 | colormap(gray); 6 | title('tire.tif'); 7 | xlabel('Columns'); 8 | ylabel('Rows'); 9 | axis equal; 10 | axis tight; 11 | 12 | subplot(2,2,2); 13 | imhist(img); 14 | title('Histogram of grayscale intensity values'); 15 | %xlabel('Pixel intensity'); 16 | ylabel('Total pixel count'); 17 | axis tight; 18 | 19 | subplot(2,2,3); 20 | imgeq = histeq(img); 21 | imagesc(imgeq); 22 | axis equal; 23 | axis tight; 24 | title('Histogram equalized image'); 25 | 26 | subplot(2,2,4); 27 | [pixelCount, grayLevels] = imhist(imgeq); 28 | bar(grayLevels, pixelCount); 29 | title('Histogram of grayscale intensity values'); 30 | xlabel('Pixel intensity'); 31 | ylabel('Total pixel count'); 32 | axis tight; -------------------------------------------------------------------------------- /3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/Example_2_Color_Image_RGB.m: -------------------------------------------------------------------------------- 1 | img = imread('peppers.png'); 2 | 3 | size(img) 4 | 5 | subplot(2,2,1); 6 | imagesc(img); 7 | axis tight; 8 | axis equal; 9 | 10 | subplot(2,2,2); 11 | imhist(img(:,:,1)); 12 | title('Red Channel'); 13 | axis tight; 14 | 15 | subplot(2,2,3); 16 | imhist(img(:,:,2)); 17 | title('Green Channel'); 18 | axis tight; 19 | 20 | subplot(2,2,4); 21 | imhist(img(:,:,3)); 22 | title('Blue Channel'); 23 | axis tight; -------------------------------------------------------------------------------- /3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/Example_3_Color_Image_HSV.m: -------------------------------------------------------------------------------- 1 | img = imread('peppers.png'); 2 | imghsv = rgb2hsv(img); 3 | 4 | size(imghsv) 5 | 6 | subplot(3,2,1); 7 | imagesc(imghsv(:,:,1)); 8 | axis tight; axis equal; 9 | cmap = hsv2rgb([[0:1/255:1]', ones(256,2)]); 10 | colormap(gca, cmap); 11 | title('Hue Channel'); 12 | 13 | subplot(3,2,2); 14 | imhist(round(imghsv(:,:,1)*255)+1, cmap); 15 | axis tight; 16 | 17 | ax3 = subplot(3,2,3); 18 | imagesc(imghsv(:,:,2)); 19 | colormap(ax3, gray); 20 | axis tight; axis equal; 21 | title('Saturation Channel'); 22 | 23 | subplot(3,2,4); 24 | imhist(imghsv(:,:,2)); 25 | axis tight; 26 | 27 | ax5 = subplot(3,2,5); 28 | imagesc(imghsv(:,:,3)); 29 | colormap(ax5, gray); 30 | axis tight; axis equal; 31 | title('Value Channel'); 32 | 33 | subplot(3,2,6); 34 | imhist(imghsv(:,:,3)); 35 | axis tight; -------------------------------------------------------------------------------- /3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/Example_4.m: -------------------------------------------------------------------------------- 1 | img = imread('peppers.png'); 2 | imghsv = rgb2hsv(img); 3 | 4 | subplot(2,2,1); 5 | imagesc(img); 6 | 7 | subplot(2,2,2); 8 | hsvbright = imghsv; 9 | hsvbright(:,:,3) = hsvbright(:,:,3).^0.5; 10 | imagesc(hsv2rgb(hsvbright)); 11 | title('Intensity brightened image'); 12 | 13 | subplot(2,2,3); 14 | hsvsat = imghsv; 15 | hsvsat(:,:,2) = hsvsat(:,:,2).^0.5; 16 | imagesc(hsv2rgb(hsvsat)); 17 | title('Color saturated image'); 18 | 19 | subplot(2,2,4); 20 | hsvhue = imghsv; 21 | hsvhue(:,:,1) = mod(hsvhue(:,:,1)-0.1, 1); 22 | imagesc(hsv2rgb(hsvhue)); 23 | title('Hue shifted image'); -------------------------------------------------------------------------------- /3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/Quiz_Color_Images.m: -------------------------------------------------------------------------------- 1 | load RGB.mat; 2 | 3 | %img = zeros(256,256,3); 4 | %img(:,:,1) = R; 5 | %img(:,:,2) = G; 6 | %img(:,:,3) = B; 7 | img = cat(3, R, G, B); 8 | 9 | figure; 10 | imagesc(img); 11 | 12 | % Answer 13 | % Color Images In MATLAB -------------------------------------------------------------------------------- /3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/RGB.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/3-Image_Analysis/3-Image_Intensity_and_Color_Distributions/RGB.mat -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/DrawBoxes.m: -------------------------------------------------------------------------------- 1 | function DrawBoxes(boxr, boxc, color) 2 | if (nargin < 3) 3 | color = 'r'; 4 | end 5 | verts_boxc = 7*[-1, 1, 1,-1, -1]; 6 | verts_boxr = 7*[-1,-1, 1, 1, -1]; 7 | hold on; 8 | for i = 1 : length(boxr) 9 | plot(verts_boxc + boxc(i), verts_boxr + boxr(i), color); 10 | end 11 | end -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Example_1.m: -------------------------------------------------------------------------------- 1 | img = imread('moon.tif'); 2 | 3 | ax1 = subplot(1,3,1); 4 | image(img); 5 | colormap(ax1, gray); 6 | title('moon.tif'); 7 | axis tight; axis equal; 8 | 9 | ax2 = subplot(3,3,2); 10 | sigma = 3; % many smaller details can be preserved 11 | gaussianfilter = fspecial('gaussian', [90,90], sigma); 12 | surf(gaussianfilter); 13 | colormap(ax2, jet); 14 | title(['Gaussian filter \sigma = ', num2str(sigma)]); 15 | 16 | ax3 = subplot(3,3,3); 17 | img_filtered = conv2(img, gaussianfilter, 'same'); 18 | image(img_filtered); 19 | colormap(ax3, gray); 20 | title('Filtered image'); 21 | axis tight; axis equal; 22 | 23 | ax5 = subplot(3,3,5); 24 | sigma = 9; 25 | gaussianfilter = fspecial('gaussian', [90,90], sigma); 26 | surf(gaussianfilter); 27 | colormap(ax5, jet); 28 | title(['Gaussian filter \sigma = ', num2str(sigma)]); 29 | 30 | ax6 = subplot(3,3,6); 31 | img_filtered = conv2(img, gaussianfilter, 'same'); 32 | image(img_filtered); 33 | colormap(ax6, gray); 34 | title('Filtered image'); 35 | axis tight; axis equal; 36 | 37 | ax8 = subplot(3,3,8); 38 | sigma = 15; % all of the fine details get blurred away 39 | gaussianfilter = fspecial('gaussian', [90,90], sigma); 40 | surf(gaussianfilter); 41 | colormap(ax8, jet); 42 | title(['Gaussian filter \sigma = ', num2str(sigma)]); 43 | 44 | ax9 = subplot(3,3,9); 45 | img_filtered = conv2(img, gaussianfilter, 'same'); 46 | image(img_filtered); 47 | colormap(ax9, gray); 48 | title('Filtered image'); 49 | axis tight; axis equal; -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Example_2.m: -------------------------------------------------------------------------------- 1 | img = imread('moon.tif'); 2 | 3 | ax1 = subplot(1,3,1); 4 | image(img); 5 | colormap(ax1, gray); 6 | title('moon.tif'); 7 | axis tight; axis equal; 8 | 9 | ax2 = subplot(1,3,2); 10 | rng(0); 11 | img_noisy = double(img) + 20*randn(size(img)); % random white noise artifacts with standard deviation of 20 12 | image(img_noisy); 13 | colormap(ax2, gray); 14 | title('Noisy image'); 15 | axis tight; axis equal; 16 | 17 | ax3 = subplot(1,3,3); 18 | sigma = 1.5; 19 | W = sigma * 6; % typically we would choose to filter width to be 6 times sigma 20 | img_filtered = imgaussfilt(img, sigma, 'FilterSize', [W,W]); 21 | image(img_filtered); 22 | colormap(ax3, gray); 23 | title(['Filtered image (\sigma = ', sprintf('%.1f', sigma), ')']); 24 | axis tight; axis equal; -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Example_3_Convolution_Based_Filters_Except_Median_Filter.m: -------------------------------------------------------------------------------- 1 | img = imread('moon.tif'); 2 | 3 | filt_sobelh = fspecial('sobel'); % Horizontal Sobel operator 4 | filt_sobelv = filt_sobelh'; % Vertical Sobel operator 5 | filt_log = fspecial('log'); % Laplacian of Gaussian filter 6 | 7 | %% Original image 8 | ax1 = subplot(2,6,1); 9 | image(img); 10 | colormap(ax1, gray); 11 | title('moon.tif'); 12 | axis tight; axis equal; 13 | 14 | ax7 = subplot(2,6,7); 15 | image(img); 16 | axis([130,250,360,480]); 17 | colormap(ax7, gray); 18 | 19 | %% Horizontal Sobel operator 20 | ax2 = subplot(2,6,2); 21 | img_sobelh = conv2(img, filt_sobelh, 'same'); 22 | image(abs(img_sobelh)); % we take the absolute value so that we get the magnitude for both bright to dark, and dark to bright horizontal edges 23 | colormap(ax2, gray); 24 | title('Horizontal Sobel'); 25 | axis tight; axis equal; 26 | 27 | ax8 = subplot(2,6,8); 28 | image(abs(img_sobelh)); 29 | axis([130,250,360,480]); 30 | colormap(ax8, gray); 31 | 32 | %% Vertical Sobel operator 33 | ax3 = subplot(2,6,3); 34 | img_sobelv = conv2(img, filt_sobelv, 'same'); 35 | image(abs(img_sobelv)); 36 | colormap(ax3, gray); 37 | title('Vertical Sobel'); 38 | axis tight; axis equal; 39 | 40 | ax9 = subplot(2,6,9); 41 | image(abs(img_sobelv)); 42 | axis([130,250,360,480]); 43 | colormap(ax9, gray); 44 | 45 | %% Add quiver plots 46 | subplot(2,6,7); 47 | hold on; 48 | quiver(img_sobelv, img_sobelh, 'LineWidth', 2); % display gradient vectors 49 | 50 | %% Laplacian fo Gaussian filter 51 | ax4 = subplot(2,6,4); 52 | img_log = conv2(img, filt_log, 'same'); 53 | imagesc(img_log); 54 | colormap(ax4, gray); 55 | title('Laplacian of Gaussian'); 56 | axis tight; axis equal; 57 | 58 | ax10 = subplot(2,6,10); 59 | imagesc(img_log); 60 | axis([130,250,360,480]); 61 | colormap(ax10, gray); 62 | 63 | %% Sharpen image 64 | ax5 = subplot(2,6,5); 65 | img_sharpened = double(img) - 1*img_log; 66 | %{ 67 | Since the filter result is positive on the dark side of an edge and negative on the bright side of an edge, 68 | adding a negative fraction of the filter will make the dark side of the edges darker and 69 | the bright side of the edges brighter, thus sharpening the image. 70 | %} 71 | image(img_sharpened); 72 | colormap(ax5, gray); 73 | title('Sharpened image'); 74 | axis tight; axis equal; 75 | 76 | ax11 = subplot(2,6,11); 77 | image(img_sharpened); 78 | axis([130,250,360,480]); 79 | colormap(ax11, gray); 80 | 81 | %% Median blur 82 | ax6 = subplot(2,6,6); 83 | img_med = img; 84 | for i = 2 : (size(img,1) - 1) 85 | for j = 2 : (size(img,2) - 1) 86 | img_med(i,j) = median(img(i-1:i+1,j-1:j+1),'all'); 87 | % The second argument 'all' tells the median function to consider all the values in the matrix, 88 | % rather than computing the median of each column of the matrix separately. 89 | end 90 | end 91 | image(img_med); % with this non-linear filter, we get good noise suppression without losing too much fine detail in the image 92 | colormap(ax6, gray); 93 | title('Median filtered image'); 94 | axis tight; axis equal; 95 | 96 | ax12 = subplot(2,6,12); 97 | image(img_med); 98 | axis([130,250,360,480]); 99 | colormap(ax12, gray); -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Example_4_Matcing_Filter.m: -------------------------------------------------------------------------------- 1 | img = imread('text.png'); 2 | 3 | subplot(1,2,1); 4 | rng(0); 5 | img = img + 0.05*randn(size(img)); % add random white noise artifacts 6 | imagesc(img); 7 | colormap(gray); 8 | axis tight; axis equal; 9 | 10 | subplot(1,2,2); 11 | match_h = img(33:45,88:99); % matching filter 12 | match_v = flipud(match_h'); 13 | imagesc(match_h); 14 | axis tight; axis equal; 15 | 16 | subplot(1,2,1); 17 | %% 18 | img_match_h = zeros(size(img)); 19 | [r,c] = size(match_h); 20 | dr = floor(r/2); 21 | dc = floor(c/2); 22 | for i = 1 : (size(img,1) - r + 1) 23 | for j = 1 : (size(img,2) - c + 1) 24 | img_match_h(i+dr,j+dc) = corr(match_h(:), reshape(img(i:i+r-1,j:j+c-1), [r*c,1])); % ranges from 0 to 1 25 | end 26 | end 27 | %% 28 | img_match_v = zeros(size(img)); 29 | [r,c] = size(match_v); 30 | dr = floor(r/2); 31 | dc = floor(c/2); 32 | for i = 1 : (size(img,1) - r + 1) 33 | for j = 1 : (size(img,2) - c + 1) 34 | img_match_v(i+dr,j+dc) = corr(match_v(:), reshape(img(i:i+r-1,j:j+c-1), [r*c,1])); 35 | end 36 | end 37 | axis tight; axis equal; 38 | %% 39 | [boxr,boxc] = find(img_match_h > 0.75); 40 | DrawBoxes(boxr, boxc, 'r'); 41 | [boxr,boxc] = find(img_match_v > 0.75); 42 | DrawBoxes(boxr, boxc, 'g'); -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/GaussianBlur.m: -------------------------------------------------------------------------------- 1 | function [img_filt,filt] = GaussianBlur(img,sigma) 2 | % Use fspecial to generate the Gaussian filter 3 | w = round(6*sigma); 4 | filt = fspecial('gaussian', [w,w], sigma); 5 | 6 | % Apply the filter to the image using convolution 7 | img_filt = conv2(img, filt, 'same'); 8 | end -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Quiz_Motion.m: -------------------------------------------------------------------------------- 1 | img = imread('cameraman.tif'); 2 | motion_filter = fspecial('motion'); 3 | img_motion_filter = conv2(img, motion_filter, 'same'); 4 | meanIntensityValue = mean2(img_motion_filter) 5 | 6 | % Answer 7 | % 117.53 -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Script_GaussianBlur.m: -------------------------------------------------------------------------------- 1 | img = imread('moon.tif'); 2 | 3 | sigma = 20; 4 | [img_filt,filt] = GaussianBlur(img,sigma); 5 | 6 | ax1 = subplot(2,2,1); 7 | imagesc(img); 8 | title('moon'); 9 | colormap(ax1, gray); 10 | 11 | ax2 = subplot(2,2,2); 12 | imagesc(img_filt); 13 | title('moon blurred with sigma=20'); 14 | colormap(ax2, gray); 15 | 16 | subplot(2,2,3); 17 | surf(filt); 18 | title('gaussian filter with sigma=20'); -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/Script_SobelMagnitude.m: -------------------------------------------------------------------------------- 1 | img = imread('cameraman.tif'); 2 | 3 | edge_mag = SobelMagnitude(img); 4 | 5 | ax1 = subplot(1,2,1); 6 | imagesc(img); 7 | colormap(ax1, gray); 8 | 9 | ax2 = subplot(1,2,2); 10 | imagesc(edge_mag); 11 | colormap(ax2, gray); -------------------------------------------------------------------------------- /3-Image_Analysis/4-Image_Filtering/SobelMagnitude.m: -------------------------------------------------------------------------------- 1 | function edge_mag = SobelMagnitude(img) 2 | % Use fspecial to generate the horizontal and vertical Sobel filters (sh and sv) 3 | sh = fspecial('sobel'); 4 | sv = sh'; 5 | 6 | % Apply both filters to the image to generate img_sh and img_sv 7 | img_sh = conv2(img, sh, 'same'); 8 | img_sv = conv2(img, sv, 'same'); 9 | 10 | % Compute edge_mag as the square root of the sum of the squared img_sh and img_sv results 11 | edge_mag = sqrt(img_sh.*img_sh + img_sv.*img_sv); 12 | end -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/Example_1_Grayscale_Image.m: -------------------------------------------------------------------------------- 1 | img = imread('cameraman.tif'); 2 | 3 | subplot(2,5,1); 4 | image(img); 5 | title('Original Image'); 6 | colormap(gray); 7 | 8 | subplot(2,5,2); 9 | imhist(img); 10 | hst = imhist(img); 11 | threshold = otsuthresh(hst) 12 | otsuthresh(hst)*255 13 | hold on; 14 | axis tight; 15 | xline(threshold*255, '-.r', 'Threshold'); % Or: plot(threshold*255*[1,1], ylim, '-.r'); 16 | 17 | % Thresholding 18 | subplot(2,5,6); 19 | % Creates a binary image (i.e., mask) representing the segmentation 20 | mask = (img < threshold*255); 21 | imagesc(mask); 22 | title('Thresholding'); 23 | 24 | subplot(2,5,7); 25 | % To remove some of the small isolated noisy pixels: 26 | % Chooses sigma, such that objects were smaller diameter in the segmentation, 27 | % we would consider to be likely false positives. So here, we want our 28 | % foreground structures to have a diameter of at least around 5 pixels 29 | gaussianfilter = fspecial('gaussian', [30,30], 5); 30 | mask_filtered = conv2(mask, gaussianfilter, 'same'); 31 | imagesc(mask_filtered); 32 | title('Gaussian Filtered'); 33 | % Smaller structures have been dimmed by the filtering, 34 | % but the larger structures are still bright 35 | 36 | subplot(2,5,8); 37 | % Re-threshold to the above Gaussian filtered result 38 | mask_filtered_threshold = (mask_filtered > 0.5); 39 | imagesc(mask_filtered_threshold); 40 | title('Re-thresholding Gaussian Filtered'); 41 | 42 | % Connected component analysis 43 | subplot(2,5,9); 44 | components = bwconncomp(mask_filtered_threshold) 45 | segmentation = zeros(size(mask)); 46 | segmentation(components.PixelIdxList{1}) = 1; 47 | imagesc(segmentation); 48 | title('Connected Component Analysis'); 49 | 50 | subplot(2,5,1); 51 | hold on; 52 | contour(segmentation, [0.5,0.5], 'r'); 53 | 54 | % Canny edge detection 55 | subplot(2,5,10); 56 | img_canny = edge(img, 'canny'); 57 | imagesc(img_canny); 58 | title('Canny Edge Detection'); -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/Example_2_Color_Image.m: -------------------------------------------------------------------------------- 1 | img = imread('peppers.png'); 2 | 3 | addpath('../Image_Intensity_and_Color_Distributions'); 4 | run('Example_3_Color_Image_HSV'); 5 | close; 6 | 7 | figure(1); 8 | subplot(1,2,1); 9 | imagesc(img); 10 | title('Original Image'); 11 | axis tight; 12 | 13 | % Converts Hue channel which are doubles that range from 0 to 1 into integer numbers that range from 1 to 256 14 | figure(2); 15 | imhist(round(imghsv(:,:,1)*255)+1, cmap); 16 | title('Circular Image Histogram'); 17 | hst = imhist(round(imghsv(:,:,1)*255)+1, cmap); 18 | otsuthresh(hst)*255 19 | threshold1 = otsuthresh(hst) 20 | hold on; 21 | axis tight; 22 | line(otsuthresh(hst)*255*[1,1], ylim, 'Color', 'r'); 23 | 24 | imghsv_hue_shifted = mod(0.5+imghsv(:,:,1), 1); 25 | figure(3); 26 | imhist(round(imghsv_hue_shifted(:,:,1)*255)+1, [cmap(128:end,:);cmap(1:127,:)]); 27 | title('Non-circular Image Histogram'); 28 | hst = imhist(round(imghsv_hue_shifted(:,:,1)*255)+1, [cmap(128:end,:);cmap(1:127,:)]); 29 | otsuthresh(hst)*255 30 | threshold2 = otsuthresh(hst) + 0.5 31 | hold on; 32 | axis tight; 33 | line(otsuthresh(hst)*255*[1,1], ylim, 'Color', 'r'); 34 | % Now we do not have the issue of a dense portion of the circular histogram 35 | % being split across the highest and lowest values. So standard non-circular 36 | % histogram thresholding algorithms can work. 37 | 38 | background_mask = (imghsv(:,:,1) >= threshold1) & (imghsv(:,:,1) < threshold2); 39 | foreground_mask = ~background_mask; 40 | 41 | figure(1); 42 | ax = subplot(1,2,2); 43 | imagesc(foreground_mask); 44 | title('Thresholding'); 45 | colormap(ax, gray); 46 | axis tight; -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/OtsuThreshold.m: -------------------------------------------------------------------------------- 1 | function [msk,thrsh] = OtsuThreshold(img) 2 | % Define the Otsu threshold 'thrsh' using the histogram of img 3 | hst = imhist(img); 4 | thrsh = otsuthresh(hst)*255; 5 | 6 | % Apply the threshold to 'img' to make 'msk' 7 | msk = (img > thrsh); 8 | end -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/Quiz_Convex_Hull.m: -------------------------------------------------------------------------------- 1 | load('convhull.mat'); 2 | 3 | subplot(1,2,1); 4 | imagesc(msk); 5 | 6 | subplot(1,2,2); 7 | convexhull = bwconvhull(msk); 8 | imagesc(convexhull); 9 | title('Convex Hull'); 10 | 11 | % Answer 12 | % hexagon -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/Quiz_Erosion_and_Dilation_Morphological_Opening.m: -------------------------------------------------------------------------------- 1 | img = imread('cameraman.tif'); 2 | 3 | subplot(2,3,1); 4 | hst = imhist(img); 5 | threshold = otsuthresh(hst)*255 6 | msk = (img < threshold); 7 | imagesc(msk); 8 | title('Original Image'); 9 | colormap(gray); 10 | 11 | %% Method I 12 | structuring_element = ones(7,7); 13 | 14 | subplot(2,3,2); 15 | % Erosion 16 | msk_erode = imerode(msk, structuring_element); 17 | imagesc(msk_erode); 18 | title('Eroded Image'); 19 | 20 | subplot(2,3,3); 21 | % Dilation 22 | msk_erode_dilate = imdilate(msk_erode, structuring_element); 23 | imagesc(msk_erode_dilate); 24 | title('Eroded-Dilated Image'); 25 | 26 | %% Method II 27 | subplot(2,3,6); 28 | msk_opening = imopen(msk, structuring_element); 29 | imagesc(msk_opening); 30 | title('Eroded-Dilated Image'); 31 | 32 | %% Display the number of connected components in the resulting image 33 | components1 = bwconncomp(msk_erode_dilate) 34 | components2 = bwconncomp(msk_opening) 35 | isequal(components1, components2) 36 | 37 | % Answer 38 | % 6 -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/Script_OtsuThreshold.m: -------------------------------------------------------------------------------- 1 | img = imread('mri.tif'); 2 | [msk,thrsh] = OtsuThreshold(img); 3 | 4 | subplot(1,2,1); 5 | imagesc(img); 6 | title('mri'); 7 | colormap(gray); 8 | 9 | subplot(1,2,2); 10 | imagesc(msk); 11 | title("Otsu's Thresholding"); 12 | colormap(gray); 13 | thrsh % = 36 -------------------------------------------------------------------------------- /3-Image_Analysis/5-Image_Segmentation/convhull.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/733a3c1e57d758e112b37a9edd5cb6c5d18a5a0b/3-Image_Analysis/5-Image_Segmentation/convhull.mat -------------------------------------------------------------------------------- /Final_Project/AddCoinToCountAndPlot.m: -------------------------------------------------------------------------------- 1 | function [coinvalue,x_plot,y_plot,col] = AddCoinToPlotAndCount(x,y,cls) 2 | % Initialize radians for defining x_plot and y_plot using cos and sin functions 3 | rads = 0 : 2*pi/32 : 2*pi; 4 | 5 | % Initialize parameters for radius and color of circle for each type of coin 6 | DimeRadius = 22; NickelRadius = 30; QuarterRadius = 40; 7 | DimeValue = 10; NickelValue = 5; QuarterValue = 25; 8 | 9 | % Use if-elseif statement to define x_plot, y_plot, col 10 | % When cls is 1, we found a dime 11 | if (cls == 1) 12 | coinvalue = DimeValue; 13 | x_plot = x + DimeRadius*cos(rads); 14 | y_plot = y + DimeRadius*sin(rads); 15 | col = 'r'; 16 | % When cls is 2, we found a nickel 17 | elseif (cls == 2) 18 | coinvalue = NickelValue; 19 | x_plot = x + NickelRadius*cos(rads); 20 | y_plot = y + NickelRadius*sin(rads); 21 | col = 'g'; 22 | % When cls is 3, we found a quarter 23 | elseif (cls == 3) 24 | coinvalue = QuarterValue; 25 | x_plot = x + QuarterRadius*cos(rads); 26 | y_plot = y + QuarterRadius*sin(rads); 27 | col = 'm'; 28 | end 29 | 30 | plot(x_plot,y_plot,col); 31 | end -------------------------------------------------------------------------------- /Final_Project/Final_project_script_1.m: -------------------------------------------------------------------------------- 1 | % Define the filter size we will use in step 2 2 | filtsize = 85; 3 | 4 | % Creating test image 'im' by splicing together two built-in images ('coins.png' and 'eight.tif'). 5 | % Also zero-padding (adding zeros around the border) with half the filter size (filtsize) we will use 6 | % so that the filter could be centered on any actual image pixel, including those near the border 7 | % 'coins.png' contains bright nickels and dimes on a dark background 8 | % 'eight.tif' contains dark quarters on a bright background, so we invert it to match 'coins.png' 9 | im1 = imread('coins.png'); 10 | [r1,c1] = size(im1); 11 | im2 = imread('eight.tif'); 12 | [r2,c2] = size(im2); 13 | filtsizeh = floor(filtsize/2); 14 | im = zeros(r1+r2+filtsize, c1+filtsize); 15 | im(filtsizeh+1:filtsizeh+r1+r2, filtsizeh+1:filtsizeh+c1) = [im1; 255-im2(:,1:c1)]; 16 | [r,c] = size(im); 17 | imagesc(im); colormap(gray); title('test image'); axis equal; 18 | 19 | % Initialize assessed/displayed variables as empty so that code is executable 20 | msk=[]; msk_dil=[]; msk_dil_erd=[]; centroid=[]; component_size=[]; 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | %%%%% Step 1. Localize the centroid of each coin %%%%% 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | % Otsu threshold 26 | [msk,~] = OtsuThreshold(im); 27 | 28 | figure; imagesc(msk); colormap(gray); title("Otsu's Threshold"); axis equal; 29 | 30 | % Dilate 31 | structuring_element = ones(9,9); 32 | msk_dil = imdilate(msk, structuring_element); 33 | 34 | figure; imagesc(msk_dil); colormap(gray); title('Dilated'); axis equal; 35 | 36 | % Erode 37 | structuring_element = ones(23,23); 38 | msk_dil_erd = imerode(msk_dil, structuring_element); 39 | 40 | figure; imagesc(msk_dil_erd); colormap(gray); title('Eroded'); axis equal; 41 | 42 | % Connected components to get centroids of coins 43 | cconnected_comps = bwconncomp(msk_dil_erd); 44 | props_struct = regionprops(connected_comps); 45 | N = connected_comps.NumObjects 46 | centroid = zeros(N,2); 47 | component_size = zeros(N,1); 48 | for i = 1 : N 49 | %centroid(i,1) = round(props_struct(i).Centroid(1)); 50 | %centroid(i,2) = round(props_struct(i).Centroid(2)); 51 | centroid(i,:) = round(props_struct(i).Centroid); 52 | component_size(i) = props_struct(i).Area; 53 | end 54 | 55 | centroid 56 | component_size 57 | 58 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Helper Functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 | function [msk,thrsh] = OtsuThreshold(img) 60 | % Define the Otsu threshold 'thrsh' using the histogram of img 61 | hst = imhist(img); 62 | thrsh = otsuthresh(hst)*255; 63 | 64 | % Apply the threshold to 'img' to make 'msk' 65 | msk = (img > thrsh); 66 | end -------------------------------------------------------------------------------- /Final_Project/Final_project_script_2.m: -------------------------------------------------------------------------------- 1 | % Define the filter size we will use in step 2 2 | filtsize = 85; 3 | 4 | % Creating test image 'im' by splicing together two built-in images ('coins.png' and 'eight.tif'). 5 | % Also zero-padding (adding zeros around the border) with half the filter size (filtsize) we will use 6 | % so that the filter could be centered on any actual image pixel, including those near the border 7 | % 'coins.png' contains bright nickels and dimes on a dark background 8 | % 'eight.tif' contains dark quarters on a bright background, so we invert it to match 'coins.png' 9 | im1 = imread('coins.png'); 10 | [r1,c1] = size(im1); 11 | im2 = imread('eight.tif'); 12 | [r2,c2] = size(im2); 13 | filtsizeh = floor(filtsize/2); 14 | im = zeros(r1+r2+filtsize, c1+filtsize); 15 | im(filtsizeh+1:filtsizeh+r1+r2, filtsizeh+1:filtsizeh+c1) = [im1; 255-im2(:,1:c1)]; 16 | [r,c] = size(im); 17 | imagesc(im); colormap(gray); title('test image'); axis equal; 18 | 19 | % Initialize assessed/displayed variables as empty so that code is executable 20 | msk=[]; msk_dil=[]; msk_dil_erd=[]; centroid=[]; component_size=[]; 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | %%%%% Step 1. Localize the centroid of each coin %%%%% 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | % Otsu threshold 26 | [msk,~] = OtsuThreshold(im); 27 | 28 | figure; imagesc(msk); colormap(gray); title("Otsu's Threshold"); axis equal; 29 | 30 | % Dilate 31 | structuring_element = ones(9,9); 32 | msk_dil = imdilate(msk, structuring_element); 33 | 34 | figure; imagesc(msk_dil); colormap(gray); title('Dilated'); axis equal; 35 | 36 | % Erode 37 | structuring_element = ones(23,23); 38 | msk_dil_erd = imerode(msk_dil, structuring_element); 39 | 40 | figure; imagesc(msk_dil_erd); colormap(gray); title('Eroded'); axis equal; 41 | 42 | % Connected components to get centroids of coins 43 | connected_comps = bwconncomp(msk_dil_erd); 44 | props_struct = regionprops(connected_comps); 45 | N = connected_comps.NumObjects 46 | centroid = zeros(N,2); 47 | component_size = zeros(N,1); 48 | for i = 1 : N 49 | %centroid(i,1) = round(props_struct(i).Centroid(1)); 50 | %centroid(i,2) = round(props_struct(i).Centroid(2)); 51 | centroid(i,:) = round(props_struct(i).Centroid); 52 | component_size(i) = props_struct(i).Area; 53 | end 54 | 55 | centroid 56 | component_size 57 | 58 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 | %%%%% Step 2. Measure features for each coin using a bank of matching filters %%%%% 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | % Define diameters to use for filters 62 | dimediameter = 31; 63 | nickeldiameter = 41; 64 | quarterdiameter = 51; 65 | 66 | % Initialize assessed variables 67 | D=[]; dimefilter=[]; nickelfilter=[]; quarterfilter=[]; 68 | 69 | % Use the MakeCircleMatchingFilter function to create matching filters for dimes, nickels, and quarters, respectively 70 | % (This is in a separate Matlab grader problem. Save your work, complete the corresponding grader problem and 71 | % embed the solution in the helper function list below) 72 | [dimefilter, ~, ~] = MakeCircleMatchingFilter(dimediameter, filtsize); 73 | [nickelfilter, ~, ~] = MakeCircleMatchingFilter(nickeldiameter, filtsize); 74 | [quarterfilter, ~, ~] = MakeCircleMatchingFilter(quarterdiameter, filtsize); 75 | 76 | figure; 77 | subplot(1,3,1); imagesc(dimefilter); colormap(gray); title('dime filter'); axis tight equal; 78 | subplot(1,3,2); imagesc(nickelfilter); colormap(gray); title('nickel filter'); axis tight equal; 79 | subplot(1,3,3); imagesc(quarterfilter); colormap(gray); title('quarter filter'); axis tight equal; 80 | 81 | % Evaluate each of the 3 matching filters on each coin to serve as 3 feature measurements 82 | filtsize 83 | 84 | D = zeros(N,3); % Feature Matrix 85 | for i = 1 : N 86 | local_region = msk_dil_erd(centroid(i,2)-filtsizeh:centroid(i,2)+filtsizeh, centroid(i,1)-filtsizeh:centroid(i,1)+filtsizeh); 87 | D(i,1) = corr(dimefilter(:), local_region(:)); 88 | D(i,2) = corr(nickelfilter(:), local_region(:)); 89 | D(i,3) = corr(quarterfilter(:), local_region(:)); 90 | end 91 | 92 | D 93 | 94 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Helper Functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 95 | function [msk,thrsh] = OtsuThreshold(img) 96 | % Define the Otsu threshold 'thrsh' using the histogram of img 97 | hst = imhist(img); 98 | thrsh = otsuthresh(hst)*255; 99 | 100 | % Apply the threshold to 'img' to make 'msk' 101 | msk = (img > thrsh); 102 | end -------------------------------------------------------------------------------- /Final_Project/Final_project_script_3.m: -------------------------------------------------------------------------------- 1 | % Define the filter size we will use in step 2 2 | filtsize = 85; 3 | 4 | % Creating test image 'im' by splicing together two built-in images ('coins.png' and 'eight.tif'). 5 | % Also zero-padding (adding zeros around the border) with half the filter size (filtsize) we will use 6 | % so that the filter could be centered on any actual image pixel, including those near the border 7 | % 'coins.png' contains bright nickels and dimes on a dark background 8 | % 'eight.tif' contains dark quarters on a bright background, so we invert it to match 'coins.png' 9 | im1 = imread('coins.png'); 10 | [r1,c1] = size(im1); 11 | im2 = imread('eight.tif'); 12 | [r2,c2] = size(im2); 13 | filtsizeh = floor(filtsize/2); 14 | im = zeros(r1+r2+filtsize, c1+filtsize); 15 | im(filtsizeh+1:filtsizeh+r1+r2, filtsizeh+1:filtsizeh+c1) = [im1; 255-im2(:,1:c1)]; 16 | [r,c] = size(im); 17 | imagesc(im); colormap(gray); title('test image'); axis equal; 18 | 19 | % Initialize assessed/displayed variables as empty so that code is executable 20 | msk=[]; msk_dil=[]; msk_dil_erd=[]; centroid=[]; component_size=[]; 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | %%%%% Step 1. Localize the centroid of each coin %%%%% 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | % Otsu threshold 26 | [msk,~] = OtsuThreshold(im); 27 | 28 | figure; imagesc(msk); colormap(gray); title("Otsu's Threshold"); axis equal; 29 | 30 | % Dilate 31 | structuring_element = ones(9,9); 32 | msk_dil = imdilate(msk, structuring_element); 33 | 34 | figure; imagesc(msk_dil); colormap(gray); title('Dilated'); axis equal; 35 | 36 | % Erode 37 | structuring_element = ones(23,23); 38 | msk_dil_erd = imerode(msk_dil, structuring_element); 39 | 40 | figure; imagesc(msk_dil_erd); colormap(gray); title('Eroded'); axis equal; 41 | 42 | % Connected components to get centroids of coins 43 | connected_comps = bwconncomp(msk_dil_erd); 44 | props_struct = regionprops(connected_comps); 45 | N = connected_comps.NumObjects 46 | centroid = zeros(N,2); 47 | component_size = zeros(N,1); 48 | for i = 1 : N 49 | %centroid(i,1) = round(props_struct(i).Centroid(1)); 50 | %centroid(i,2) = round(props_struct(i).Centroid(2)); 51 | centroid(i,:) = round(props_struct(i).Centroid); 52 | component_size(i) = props_struct(i).Area; 53 | end 54 | 55 | centroid 56 | component_size 57 | 58 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 | %%%%% Step 2. Measure features for each coin using a bank of matching filters %%%%% 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | % Define diameters to use for filters 62 | dimediameter = 31; 63 | nickeldiameter = 41; 64 | quarterdiameter = 51; 65 | 66 | % Initialize assessed variables 67 | D=[]; dimefilter=[]; nickelfilter=[]; quarterfilter=[]; 68 | 69 | % Use the MakeCircleMatchingFilter function to create matching filters for dimes, nickels, and quarters, respectively 70 | % (This is in a separate Matlab grader problem. Save your work, complete the corresponding grader problem and 71 | % embed the solution in the helper function list below) 72 | [dimefilter, ~, ~] = MakeCircleMatchingFilter(dimediameter, filtsize); 73 | [nickelfilter, ~, ~] = MakeCircleMatchingFilter(nickeldiameter, filtsize); 74 | [quarterfilter, ~, ~] = MakeCircleMatchingFilter(quarterdiameter, filtsize); 75 | 76 | figure; 77 | subplot(1,3,1); imagesc(dimefilter); colormap(gray); title('dime filter'); axis tight equal; 78 | subplot(1,3,2); imagesc(nickelfilter); colormap(gray); title('nickel filter'); axis tight equal; 79 | subplot(1,3,3); imagesc(quarterfilter); colormap(gray); title('quarter filter'); axis tight equal; 80 | 81 | % Evaluate each of the 3 matching filters on each coin to serve as 3 feature measurements 82 | filtsize 83 | 84 | D = zeros(N,3); % Feature Matrix 85 | for i = 1 : N 86 | local_region = msk_dil_erd(centroid(i,2)-filtsizeh:centroid(i,2)+filtsizeh, centroid(i,1)-filtsizeh:centroid(i,1)+filtsizeh); 87 | D(i,1) = corr(dimefilter(:), local_region(:)); 88 | D(i,2) = corr(nickelfilter(:), local_region(:)); 89 | D(i,3) = corr(quarterfilter(:), local_region(:)); 90 | end 91 | 92 | D 93 | 94 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 95 | %%%%% Step 3. Perform k-means clustering of features for unsupervised learning classifier %%%%% 96 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 97 | rng(0); cls_init=[]; cls=[]; totcount=[]; 98 | 99 | [cls_init,C] = kmeans(D, 3); 100 | 101 | cls_init 102 | 103 | % Relabel centroid classes based on average size of the objects in each class. Smallest will be dime, next nickel, and largest quarter 104 | dist1 = sqrt((centroid(:,1)-C(1,1)).^2 + (centroid(:,2)-C(1,2)).^2); 105 | dist2 = sqrt((centroid(:,1)-C(2,1)).^2 + (centroid(:,2)-C(2,2)).^2); 106 | dist3 = sqrt((centroid(:,1)-C(3,1)).^2 + (centroid(:,2)-C(3,2)).^2); 107 | 108 | class_average_object_size = zeros(3,1); 109 | class_average_object_size(1) = mean(component_size((dist1 < dist2) & (dist1 < dist3))); 110 | class_average_object_size(2) = mean(component_size((dist2 < dist1) & (dist2 < dist3))); 111 | class_average_object_size(3) = mean(component_size((dist3 < dist1) & (dist3 < dist2))); 112 | 113 | [~,classmap] = sort(class_average_object_size); 114 | 115 | cls = zeros(length(centroid),1); 116 | for i = 1 : length(centroid) 117 | if (cls_init(i) == classmap(1)) 118 | cls(i) = 1; 119 | elseif (cls_init(i) == classmap(2)) 120 | cls(i) = 2; 121 | elseif (cls_init(i) == classmap(3)) 122 | cls(i) = 3; 123 | end 124 | end 125 | 126 | cls 127 | 128 | % Visualize the result 129 | figure; imagesc(im); colormap(gray); title('Test Image'); hold on; axis equal; 130 | 131 | % Plot circles around each coin with different color/diameter unique to each type and count the change 132 | totcount = 0; 133 | for i = 1 : length(centroid) 134 | [coinvalue,~,~,~] = AddCoinToPlotAndCount(centroid(i,1), centroid(i,2), cls(i)); 135 | hold on; 136 | totcount = totcount + coinvalue; 137 | end 138 | title(['Total coin values = ', num2str(totcount), ' cents']); 139 | 140 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Helper Functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 141 | function [msk,thrsh] = OtsuThreshold(img) 142 | % Define the Otsu threshold 'thrsh' using the histogram of img 143 | hst = imhist(img); 144 | thrsh = otsuthresh(hst)*255; 145 | 146 | % Apply the threshold to 'img' to make 'msk' 147 | msk = (img > thrsh); 148 | end -------------------------------------------------------------------------------- /Final_Project/MakeCircleMatchingFilter.m: -------------------------------------------------------------------------------- 1 | function [filter,xc,yc] = MakeCircleMatchingFilter(diameter,W) 2 | % Initialize filter 3 | filter = zeros(W,W); 4 | 5 | % Define coordinates for the center of the W x W filter 6 | xc = (1 + W) / 2; 7 | yc = (1 + W) / 2; 8 | 9 | % Use nested for loops to check if each pixel lies in the foreground of the circle. If so, label it as foreground with a 1. 10 | for i = 1 : W 11 | for j = 1 : W 12 | if sqrt((j - xc)*(j - xc) + (i - yc)*(i - yc)) <= (diameter/2) 13 | filter(i,j) = 1; 14 | end 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /Final_Project/Script_AddCoinToCountAndPlot.m: -------------------------------------------------------------------------------- 1 | x = 1.2; 2 | y = 4.1; 3 | cls = 3; 4 | [coinvalue, x_plot, y_plot,col] = AddCoinToPlotAndCount(x, y, cls); 5 | figure; 6 | plot(x_plot, y_plot, [col,'o-']); -------------------------------------------------------------------------------- /Final_Project/Script_MakeCircleMatchingFilter.m: -------------------------------------------------------------------------------- 1 | diameter = 20; 2 | W = 30; 3 | [filter, xc, yc] = MakeCircleMatchingFilter(diameter, W); 4 | figure; imagesc(filter); colormap(gray); 5 | xc % should be 15.5 6 | yc % should be 15.5 7 | 8 | diameter = 20; 9 | W = 31; 10 | [filter, xc, yc] = MakeCircleMatchingFilter(diameter, W); 11 | figure; imagesc(filter); colormap(gray); 12 | xc % should be 16 13 | yc % should be 16 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB 2 | =================================================================== 3 | 4 |

5 |
6 | 7 |
8 |

9 | 10 | --- 11 | 12 | Instructor: [Jack Noble](https://www.coursera.org/instructor/jacknoble) 13 | 14 | 15 | 16 | 20 | 21 |
17 | A collection of Code Example Files, Programming Assignments and Final Project for Introduction to Data, Signal, and Image Analysis with MATLAB. 18 | I took this online course on Coursera platform during September-October, 2021. (Certificate of Completion) 19 |
22 | 23 | > DISCLAIMER: Please do not simply copy the code without trying to solve the problems yourself in the first place. The author reserves all rights but does not be liable in any event (e.g., plagiarism) caused by the use of the program. Remember that one can only learn programming by doing it. Have fun coding!😃 24 | 25 | ### Overview 26 | This course is the last part of the specialization [MATLAB Programming for Engineers and Scientists Specialization](https://www.coursera.org/specializations/matlab-programming-engineers-scientists), offered by Vanderbilt University. 27 | It provides an introduction on how to use MATLAB for data, signal, and image analysis. After completing the course, learners will understand how machine learning methods can be used in MATLAB for data classification and prediction; 28 | how to perform data visualization, especially for high dimensional datasets; how to perform image processing and analysis methods, including image filtering and image segmentation; 29 | and how to perform common signal analysis tasks, including filter design and frequency analysis. 30 | 31 | --- 32 | 33 | ### Naming convention 34 | 35 | - For file names starting with `Example`: code examples that are demonstrated in the lectures 36 | - For file names starting with `Quiz`: scripts and answers for quizzes 37 | - For file names starting with `` (e.g., [`EstimationErrorPlot.m`](./1-Data_Analysis/6-Data_Prediction/EstimationErrorPlot.m)): function definition required for completing the assignments 38 | - For file names starting with `Script` (e.g., [`Script_EstimationErrorPlot.m`](./1-Data_Analysis/6-Data_Prediction/Script_EstimationErrorPlot.m): scripts that are used to call the corresponding functions in the assignments 39 | 40 | --- 41 | 42 | ### Final project 43 | 44 | In the final project of this course, I developed an image analysis-based solution for counting coin change for a bank. 45 | A camera is placed above the bank teller's countertop which will photograph coins placed on the countertop. 46 | When someone spreads any combination of *quarters*, *nickels*, and *dimes* on the countertop, my program will analyze an image taken from the camera to: 47 | (1) localize the coins, (2) classify each coin as a quarter, nickel, or dime, (3) add up the total value of the coins shown in the image. 48 | 49 |

50 | 51 |

52 | 53 | #### Steps to achieve the goal 54 | 55 | 1. Localize the centroid of each coin 56 | 2. Measure features for each coin using a "bank" of matching filters 57 | 3. Perform k-means clustering of features for an unsupervised learning coin-type classifier, sum up the total value of coins, and visualize the results 58 | 59 | #### How to run the program? 60 | Simply run the script [`Final_project_script_3.m`](./Final_Project/Final_project_script_3.m), which is the final version of the implementation to solve the problem. The output should look identical to the image above. 61 | 62 | --- 63 | 64 | ### Recommended further readings 65 | - For Signal Analysis: *Oppenheim, Alan V.; Willsky, Alan S.; Nawab, Syed Hamid (1997): Signals and systems. 2. ed.* 66 | - For Image Analysis: *Šonka, Milan; Hlaváč, Václav; Boyle, Roger (2015): Image processing, analysis, and machine vision. 4. ed.* 67 | 68 | --- 69 | 70 | ### Contact 71 | If you have any question or suggestion, feel free to contact me at huaming.huang.tw@gmail.com. Contributions are also welcomed. Please open a [pull-request](https://github.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/compare) or an [issue](https://github.com/huaminghuangtw/Coursera-Introduction-to-Data-Signal-and-Image-Analysis-with-MATLAB/issues/new) in this repository. 72 | --------------------------------------------------------------------------------