├── AddCoinToPlotAndCount.m ├── BandPassFilter.m ├── EstimationErrorPlot.m ├── Final_project_script_1.m ├── Final_project_script_2.m ├── Final_project_script_3.m ├── GaussianBlur.m ├── GaussianFilter.m ├── ImageResample.m ├── IsNyquistSatisfied.m ├── MahalanobisDistance.m ├── MakeCircleMatchingFilter.m ├── Making_waves.m ├── OtsuThreshold.m ├── Quizzes - Week 2 ├── Quizzes - Week 3 ├── Quizzes - Week 4 ├── README.md ├── SignalResample.m ├── SobelMagnitude.m ├── Spectrogram.m ├── cumulative_percent_variance_permode.m ├── ellipsoid_fit_data.m ├── my_fitpca.m ├── my_predictpca.m ├── myfft.m ├── myifft.m └── standard_deviation_distance.m /AddCoinToPlotAndCount.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 | % initialize parameters for radius and color of circle for each type of coin 5 | rD=22; 6 | rN=30; 7 | rQ=40; 8 | % use if-elseif statement to define x_plot, y_plot, col 9 | % when cls is 1, we found a dime 10 | % when cls is 2, we found a nickel 11 | % when cls is 3, we found a quarter 12 | if(cls==1) 13 | coinvalue=10; 14 | x_plot=x+rD*cos(rads); 15 | y_plot=y+rD*sin(rads); 16 | col='r'; 17 | elseif(cls==2) 18 | coinvalue=5; 19 | x_plot=x+rN*cos(rads); 20 | y_plot=y+rN*sin(rads); 21 | col='g'; 22 | else 23 | coinvalue=25; 24 | x_plot=x+rQ*cos(rads); 25 | y_plot=y+rQ*sin(rads); 26 | col='m'; 27 | end 28 | 29 | plot(x_plot,y_plot,col); 30 | end 31 | -------------------------------------------------------------------------------- /BandPassFilter.m: -------------------------------------------------------------------------------- 1 | function y = BandPassFilter(x, Fs, freq_range, W) 2 | %Create the filter using 'fir1' 3 | filt = fir1(W,freq_range/(Fs/2),'band') 4 | %Apply the filter using 'conv' 5 | y = conv(x,filt,'same') 6 | end 7 | 8 | 9 | Fs=10; 10 | x1 = repmat([1 0 -1 0],[1,10]); % this is a 2.5 Hz signal 11 | x2 = repmat([1 -1],[1,20]); % this is a 5 Hz signal 12 | x = x1 + x2; 13 | freq_range = [2,3]; % filter out the 5 Hz but keep the 2.5 Hz component 14 | W = 10; 15 | %%%%%%%%%%%%%%%%% 16 | y = BandPassFilter(x, Fs, freq_range, W); 17 | %%%%%%%%%%%%%%%%% 18 | % plot x1, x2, x=x1+x2, and BandPassFilter output 19 | t = 0:1/Fs:(length(y)-1)/Fs; 20 | plot(t(1:Fs),x1(1:Fs),'bo-') 21 | hold on 22 | plot(t(1:Fs),x2(1:Fs),'r*-') 23 | plot(t(1:Fs),x(1:Fs),'g') 24 | plot(t(1:Fs),y(1:Fs),'m--', 'LineWidth', 2) 25 | legend('x1-2.5Hz','x2-5.0Hz','x=x1+x2','output') 26 | -------------------------------------------------------------------------------- /EstimationErrorPlot.m: -------------------------------------------------------------------------------- 1 | function [mse,R,p,rg] = EstimationErrorPlot(prediction,target) 2 | 3 | mse = mean((target-prediction).^2); 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); 11 | title(sprintf('R=%.3f,p=%.3g,mse=%.3f',R,p,mse)); 12 | legend('True vs Predicted','Diagonal'); 13 | 14 | end 15 | 16 | 17 | load fisheriris 18 | D_train = meas(1:2:end,:); 19 | D_test = meas(2:2:end,:); 20 | mdl = fitlm(D_train(:,1:3),D_train(:,4)); 21 | prediction = predict(mdl,D_test(:,1:3)); 22 | [mse,R,p,rg] = EstimationErrorPlot(prediction,D_test(:,4)); 23 | -------------------------------------------------------------------------------- /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. 5 | % Also zero-padding (adding zeros around the border) with half the 6 | % filter size (filtsize) we will use so that the filter could be 7 | % centered on any actual image pixel, including those near the border. 8 | % 'coins.png' contains bright nickels and dimes on a dark background 9 | % 'eight.tif' contains dark quarters on a bright background, so we invert it 10 | % to match 'coins.png' 11 | im1 = imread('coins.png'); 12 | [r,c] = size(im1); 13 | im2 = imread('eight.tif'); 14 | [r2,c2] = size(im2); 15 | filtsizeh = floor(filtsize/2); 16 | im = zeros(r+r2+filtsize,c+filtsize); 17 | im(filtsizeh+1:filtsizeh+r+r2,filtsizeh+1:filtsizeh+c) = [im1;255-im2(:,1:c)]; 18 | [r,c] = size(im); 19 | imagesc(im);colormap(gray);title('test image');axis equal; 20 | 21 | % Initializing assessed/displayed variables as empty so that code is executable 22 | msk=[]; msk_dil=[]; msk_dil_erd=[]; centroid=[]; component_size=[]; 23 | 24 | %%%%% 1. Localize the centroid of each coin 25 | % Otsu threshold 26 | thrsh = otsuthresh(imhist(im))*255; 27 | msk = im > thrsh; 28 | 29 | figure; imagesc(msk); colormap(gray); title('Otsu'); axis equal; 30 | 31 | % Dilate 32 | msk_dil = imdilate(msk,ones(3,3)); 33 | 34 | figure; imagesc(msk_dil); colormap(gray); title('Dilated'); axis equal; 35 | 36 | % Erode 37 | msk_dil_erd = imerode(msk_dil,ones(6,6)); 38 | 39 | figure; imagesc(msk_dil_erd); colormap(gray); title('Eroded'); axis equal; 40 | 41 | % Connected components to get centroids of coins: 42 | component_size = bwconncomp(msk_dil_erd); 43 | props = regionprops(msk_dil_erd,'centroid'); 44 | centroid = vertcat(props.Centroid) 45 | for i=1:14 46 | for j=1:2 47 | if ceil(centroid(i,j))-centroid(i,j)>=0.5 48 | centroid(i,j) = ceil(centroid(i,j)); 49 | else 50 | centroid(i,j) = floor(centroid(i,j)); 51 | end 52 | end 53 | end 54 | 55 | centroid 56 | component_size 57 | 58 | 59 | %%%%%%%%%%%%%%%%%%%% Helper Functions %%%%%%%%%%%%%%%%%%%%% 60 | -------------------------------------------------------------------------------- /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. 5 | % Also zero-padding (adding zeros around the border) with half the 6 | % filter size (filtsize) we will use so that the filter could be 7 | % centered on any actual image pixel, including those near the border. 8 | % 'coins.png' contains bright nickels and dimes on a dark background 9 | % 'eight.tif' contains dark quarters on a bright background, so we invert it 10 | % to match 'coins.png' 11 | im1 = imread('coins.png'); 12 | [r,c] = size(im1); 13 | im2 = imread('eight.tif'); 14 | [r2,c2] = size(im2); 15 | filtsizeh = floor(filtsize/2); 16 | im = zeros(r+r2+filtsize,c+filtsize); 17 | im(filtsizeh+1:filtsizeh+r+r2,filtsizeh+1:filtsizeh+c) = [im1;255-im2(:,1:c)]; 18 | [r,c] = size(im); 19 | imagesc(im);colormap(gray);title('test image');axis equal; 20 | 21 | % Initializing assessed/displayed variables as empty so that code is executable 22 | msk=[]; msk_dil=[]; msk_dil_erd=[]; centroid=[]; component_size=[]; 23 | 24 | %%%%% 1. Localize the centroid of each coin 25 | % Otsu threshold 26 | msk = OtsuThreshold(im); 27 | figure; imagesc(msk); colormap(gray); title('Otsu'); axis equal; 28 | 29 | % Dilate 9x9 30 | msk_dil = imdilate(msk,ones(9,9)); 31 | figure; imagesc(msk_dil); colormap(gray); title('Dilated'); axis equal; 32 | 33 | % Erode 23x23 34 | msk_dil_erd = imerode(msk_dil,ones(23,23)); 35 | figure; imagesc(msk_dil_erd); colormap(gray); title('Eroded'); axis equal; 36 | 37 | 38 | % Connected components to get centroids of coins: 39 | cc = bwconncomp(msk_dil_erd); 40 | props_struct = regionprops(cc); 41 | centroid = zeros(length(props_struct),2); 42 | component_size = zeros(length(props_struct),1); 43 | for i=1:length(props_struct) 44 | centroid(i,:) = round(props_struct(i).Centroid); 45 | component_size(i) = props_struct(i).Area; 46 | end 47 | 48 | 49 | %%%%% 2. Measure features for each coin using a bank of matching filters 50 | % make matching filters to create features 51 | % Define diameters to use for filters 52 | dimediameter = 31; 53 | quarterdiameter = 51; 54 | nickeldiameter = 41; 55 | 56 | % Initialize assessed variables 57 | D=[]; nickelfilter = []; dimefilter = []; quarterfilter = []; 58 | 59 | % Use the MakeCircleMatchingFilter function to create matching filters for dimes, nickels, and quarters 60 | % (This is in a separate Matlab grader problem. Save your work, 61 | % complete the corresponding grader problem and embed the solution 62 | % in the helper function list below.) 63 | dimefilter = MakeCircleMatchingFilter(dimediameter,filtsize); 64 | nickelfilter = MakeCircleMatchingFilter(nickeldiameter,filtsize); 65 | quarterfilter = MakeCircleMatchingFilter(quarterdiameter,filtsize); 66 | 67 | figure; 68 | subplot(1,3,1); imagesc(dimefilter); colormap(gray); title('dime filter'); axis tight equal; 69 | subplot(1,3,2); imagesc(nickelfilter); colormap(gray); title('nickel filter'); axis tight equal; 70 | subplot(1,3,3); imagesc(quarterfilter); colormap(gray); title('quarter filter'); axis tight equal; 71 | 72 | % Evaluate each of the 3 matching filters on each coin to serve as 3 feature measurements 73 | D=zeros(length(centroid),3); 74 | for i=1:length(centroid) 75 | sliced=msk_dil_erd(centroid(i,2)-filtsizeh:centroid(i,2)+filtsizeh,centroid(i,1)-filtsizeh:centroid(i,1)+filtsizeh); 76 | sliced=sliced(:); 77 | D(i,1)=corr(dimefilter(:),sliced); 78 | D(i,2)=corr(nickelfilter(:),sliced); 79 | D(i,3)=corr(quarterfilter(:),sliced); 80 | end 81 | D 82 | 83 | %%%%%%%%%%%%%%%%%%%% Helper Functions %%%%%%%%%%%%%%%%%%%%% 84 | 85 | function [msk,thrsh] = OtsuThreshold(im) 86 | hst = imhist(im); 87 | res = otsuthresh(hst); 88 | thrsh = res*255; 89 | msk = im>thrsh; 90 | end 91 | 92 | function [filter,xc,yc] = MakeCircleMatchingFilter(diameter,W) 93 | % initialize filter 94 | filter = zeros([W W]); 95 | % define coordinates for the center of the WxW filter 96 | xc=(W+1)/2; 97 | yc=(W+1)/2; 98 | r = diameter/2; 99 | % Use double-for loops to check if each pixel lies in the foreground of the circle 100 | for i = 1:size(filter) 101 | for j = 1:size(filter) 102 | if double((i-yc).^2 + (j-xc).^2)<= r.^2 103 | filter(i,j)=1; 104 | end 105 | end 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /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. 5 | % Also zero-padding (adding zeros around the border) with half the 6 | % filter size (filtsize) we will use so that the filter could be 7 | % centered on any actual image pixel, including those near the border. 8 | % 'coins.png' contains bright nickels and dimes on a dark background 9 | % 'eight.tif' contains dark quarters on a bright background, so we invert it 10 | % to match 'coins.png' 11 | im1 = imread('coins.png'); 12 | [r,c] = size(im1); 13 | im2 = imread('eight.tif'); 14 | [r2,c2] = size(im2); 15 | filtsizeh = floor(filtsize/2); 16 | im = zeros(r+r2+filtsize,c+filtsize); 17 | im(filtsizeh+1:filtsizeh+r+r2,filtsizeh+1:filtsizeh+c) = [im1;255-im2(:,1:c)]; 18 | [r,c] = size(im); 19 | imagesc(im);colormap(gray);title('test image');axis equal; 20 | 21 | % Initializing assessed/displayed variables as empty so that code is executable 22 | msk=[]; msk_dil=[]; msk_dil_erd=[]; centroid=[]; component_size=[]; 23 | 24 | %%%%% 1. Localize the centroid of each coin 25 | % Otsu threshold 26 | msk = OtsuThreshold(im); 27 | figure; imagesc(msk); colormap(gray); title('Otsu'); axis equal; 28 | 29 | % Dilate 9x9 30 | msk_dil = imdilate(msk,ones(9,9)); 31 | figure; imagesc(msk_dil); colormap(gray); title('Dilated'); axis equal; 32 | 33 | % Erode 23x23 34 | msk_dil_erd = imerode(msk_dil,ones(23,23)); 35 | figure; imagesc(msk_dil_erd); colormap(gray); title('Eroded'); axis equal; 36 | 37 | 38 | % Connected components to get centroids of coins: 39 | cc = bwconncomp(msk_dil_erd); 40 | props_struct = regionprops(cc); 41 | centroid = zeros(length(props_struct),2); 42 | component_size = zeros(length(props_struct),1); 43 | for i=1:length(props_struct) 44 | centroid(i,:) = round(props_struct(i).Centroid); 45 | component_size(i) = props_struct(i).Area; 46 | end 47 | 48 | 49 | %%%%% 2. Measure features for each coin using a bank of matching filters 50 | % make matching filters to create features 51 | % Define diameters to use for filters 52 | dimediameter = 31; 53 | quarterdiameter = 51; 54 | nickeldiameter = 41; 55 | 56 | % Initialize assessed variable D 57 | D=[]; nickelfilter = []; dimefilter = []; quarterfilter = []; 58 | 59 | % Use the MakeCircleMatchingFilter function to create matching filters for dimes, nickels, and quarters 60 | % (This is in a separate Matlab grader problem. Save your work, 61 | % complete the corresponding grader problem and embed the solution 62 | % in the helper function list below.) 63 | nickelfilter = MakeCircleMatchingFilter(nickeldiameter,filtsize); 64 | dimefilter = MakeCircleMatchingFilter(dimediameter,filtsize); 65 | quarterfilter = MakeCircleMatchingFilter(quarterdiameter,filtsize); 66 | 67 | figure; 68 | subplot(1,3,1); imagesc(dimefilter); colormap(gray); title('dime filter'); axis tight equal; 69 | subplot(1,3,2); imagesc(nickelfilter); colormap(gray); title('nickel filter'); axis tight equal; 70 | subplot(1,3,3); imagesc(quarterfilter); colormap(gray); title('quarter filter'); axis tight equal; 71 | 72 | % Evaluate each of the 3 matching filters on each coin to serve as 3 feature measurements 73 | D = zeros(length(centroid),3); 74 | for i=1:length(centroid) 75 | D(i,1) = corr(dimefilter(:),reshape(msk_dil_erd(centroid(i,2)-filtsizeh:... 76 | centroid(i,2)+filtsizeh,centroid(i,1)-filtsizeh:centroid(i,1)+filtsizeh),[filtsize*filtsize,1])); 77 | D(i,2) = corr(nickelfilter(:),reshape(msk_dil_erd(centroid(i,2)-filtsizeh:... 78 | centroid(i,2)+filtsizeh,centroid(i,1)-filtsizeh:centroid(i,1)+filtsizeh),[filtsize*filtsize,1])); 79 | D(i,3) = corr(quarterfilter(:),reshape(msk_dil_erd(centroid(i,2)-filtsizeh:... 80 | centroid(i,2)+filtsizeh,centroid(i,1)-filtsizeh:centroid(i,1)+filtsizeh),[filtsize*filtsize,1])); 81 | end 82 | 83 | figure; 84 | subplot(1,3,1); imagesc(dimefilter); colormap(gray); title('dime filter'); axis tight equal; 85 | subplot(1,3,2); imagesc(nickelfilter); colormap(gray); title('nickel filter'); axis tight equal; 86 | subplot(1,3,3); imagesc(quarterfilter); colormap(gray); title('quarter filter'); axis tight equal; 87 | 88 | %%%%% 3. Perform k-means clustering of features for unsupervised learning classifier 89 | rng(0); 90 | cls_init=[]; cls=[]; totcount=[]; 91 | 92 | cls_init=kmeans(D,3,'Replicates',10); 93 | index_of_class_1=cls_init==1; 94 | index_of_class_2=cls_init==2; 95 | index_of_class_3=cls_init==3; 96 | Average_of_area_of_class_1=mean(component_size(index_of_class_1)); 97 | Average_of_area_of_class_2=mean(component_size(index_of_class_2)); 98 | Average_of_area_of_class_3=mean(component_size(index_of_class_3)); 99 | D=[D cls_init zeros(length(cls_init),1)]; 100 | for i=1:length(cls_init) 101 | if(cls_init(i)==1) 102 | D(i,5)=Average_of_area_of_class_1; 103 | elseif(cls_init(i)==2) 104 | D(i,5)=Average_of_area_of_class_2; 105 | else 106 | D(i,5)=Average_of_area_of_class_3; 107 | end 108 | end 109 | min_value=min([Average_of_area_of_class_1 Average_of_area_of_class_2 Average_of_area_of_class_3]); 110 | max_value=max([Average_of_area_of_class_1 Average_of_area_of_class_2 Average_of_area_of_class_3]); 111 | D=[D zeros(length(cls_init),1)]; 112 | for i=1:length(cls_init) 113 | if(D(i,5)==min_value) 114 | D(i,6)=1; 115 | elseif(D(i,5)==max_value) 116 | D(i,6)=3; 117 | else D(i,6)=2; 118 | end 119 | end 120 | 121 | cls_init 122 | % relabel centroid classes based on average size of the objects in each class. smallest will be dime, next nickel, and largest quarter 123 | 124 | cls=D(:,6); 125 | 126 | cls 127 | % Visualize the result 128 | figure; imagesc(im);colormap(gray);title('test image');hold on;axis equal; 129 | 130 | % plot circles around each coin with different color/diameter unique to each type and count the change 131 | 132 | for i=1:length(cls_init) 133 | [coinvalue,x_plot,y_plot,col] = AddCoinToPlotAndCount(centroid(i,1),centroid(i,2),cls(i)); 134 | totcount=[totcount coinvalue]; 135 | end 136 | totcount=sum(totcount); 137 | 138 | title([num2str(totcount),' cents']) 139 | 140 | 141 | %%%%%%%%%%%%%%%%%%%% Helper Functions %%%%%%%%%%%%%%%%%%%%% 142 | 143 | 144 | function filter = MakeCircleMatchingFilter(diameter,filtsize) 145 | filter = zeros(filtsize,filtsize); 146 | radius = diameter/2; 147 | c = (filtsize+1)/2; 148 | for i=1:filtsize 149 | for j=1:filtsize 150 | if (i-c)*(i-c) + (j-c)*(j-c) <= radius*radius 151 | filter(i,j) = 1; 152 | end 153 | end 154 | end 155 | end 156 | 157 | function [msk,thrsh] = OtsuThreshold(im) 158 | hst = imhist(im); 159 | res = otsuthresh(hst); 160 | thrsh = res*255; 161 | msk = im>thrsh; 162 | end 163 | 164 | function [coinvalue,x_plot,y_plot,col] = AddCoinToPlotAndCount(x,y,cls) 165 | rads = 0:2*pi/32:2*pi; 166 | rD=22; 167 | rN=30; 168 | rQ=40; 169 | if(cls==1) 170 | coinvalue=10; 171 | x_plot=x+rD*cos(rads); 172 | y_plot=y+rD*sin(rads); 173 | col='r'; 174 | elseif(cls==2) 175 | coinvalue=5; 176 | x_plot=x+rN*cos(rads); 177 | y_plot=y+rN*sin(rads); 178 | col='g'; 179 | else 180 | coinvalue=25; 181 | x_plot=x+rQ*cos(rads); 182 | y_plot=y+rQ*sin(rads); 183 | col='m'; 184 | end 185 | plot(x_plot,y_plot,col); 186 | end 187 | -------------------------------------------------------------------------------- /GaussianBlur.m: -------------------------------------------------------------------------------- 1 | function [img_filt,filt] = GaussianBlur(img,sigma) 2 | % Use fspecial to generate the Gaussian filter 3 | W = ceil(6*sigma); 4 | filt = fspecial('gaussian',[W,W],sigma); 5 | % Apply the filter to the image using convolution 6 | img_filt = conv2(img,filt,'same'); 7 | end 8 | 9 | 10 | 11 | sigma = 20; 12 | img = imread('moon.tif'); 13 | [img_filt,filt] = GaussianBlur(img,sigma); 14 | imagesc(img) 15 | title('moon') 16 | colormap(gray) 17 | figure(); 18 | imagesc(img_filt) 19 | title('moon blurred with sigma=20') 20 | colormap(gray) 21 | figure; 22 | surf(filt) 23 | title('gaussian filter with sigma=20') 24 | -------------------------------------------------------------------------------- /GaussianFilter.m: -------------------------------------------------------------------------------- 1 | function y = GaussianFilter(x, sigma) 2 | % Compute W by rounding up 6*sigma 3 | W = ceil(6*sigma); 4 | % Use fspecial to create our Gaussian filter 5 | gaussian_filter = fspecial('gaussian', [1,W], sigma); 6 | % convolve the signal with the filter 7 | y = conv(x, gaussian_filter,'same'); 8 | end 9 | 10 | 11 | x = [0 0 0 1 0 0 0]; 12 | sigma = 1.5; 13 | y = GaussianFilter(x, sigma) 14 | -------------------------------------------------------------------------------- /ImageResample.m: -------------------------------------------------------------------------------- 1 | function img_resample = ImageResample(img, dim) 2 | % define r,c,nr,nc 3 | nr = dim(1); 4 | nc = dim(2); 5 | [r, c] = size(img); 6 | % use the meshgrid function to determine sampling coordinates 7 | [C, R] = meshgrid(1:(c-1)/(nc-1):c, 1:(r-1)/(nr-1):r); 8 | % use interp2 to interpolate 9 | img_resample = interp2(double(img), C, R); 10 | end 11 | 12 | 13 | 14 | [C,R] = meshgrid(1:10,1:15); % inputs are ordered columns, then rows 15 | img = uint8(C.*R); 16 | size(img) % = 15 x 10 17 | dim = [20;25]; 18 | img_resample = ImageResample(img, dim); 19 | size(img_resample) % = 20 x 25 20 | imagesc(img); 21 | figure 22 | imagesc(img_resample) 23 | -------------------------------------------------------------------------------- /IsNyquistSatisfied.m: -------------------------------------------------------------------------------- 1 | function [y,Fs_min] = IsNyquistSatisfied(fmax,Fs) 2 | Fs_min = fmax * 2 3 | if Fs_min >= Fs 4 | y = false 5 | else 6 | y = true 7 | end 8 | end 9 | 10 | 11 | fmax = 16000; 12 | Fs = 28800; 13 | [y,Fs_min] = IsNyquistSatisfied(fmax,Fs) % false, with Fs_min=32000 14 | 15 | fmax = 16000; 16 | Fs = 44100; 17 | [y,Fs_min] = IsNyquistSatisfied(fmax,Fs) % true, with Fs_min=32000 18 | -------------------------------------------------------------------------------- /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 9 | 10 | 11 | mdl.class(1).eigvects = [0.7071 0.7071]; 12 | mdl.class(1).eigvals = 4; 13 | mdl.class(1).mu = [2 2]; 14 | v = [2,2]; 15 | md = MahalanobisDistance(mdl.class(1),v) % md = 0 because v = mu 16 | v = [2,2] + 2*[0.7071 0.7071]; 17 | md = MahalanobisDistance(mdl.class(1),v) % md = 1 because v is 2/sqrt(eigval)=2/2=1 standard deviations from mean along eigenvector 18 | v = [2,2] - 6*[0.7071 0.7071]; 19 | md = MahalanobisDistance(mdl.class(1),v) % md = 3 because v is 6/sqrt(eigval)=6/2=3 standard deviations from mean along eigenvector 20 | v = [2,2] + [-0.7071 0.7071]; 21 | md = MahalanobisDistance(mdl.class(1),v) % md = 0 because v lies in a direction from mu that is orthogonal to the eigenvector 22 | -------------------------------------------------------------------------------- /MakeCircleMatchingFilter.m: -------------------------------------------------------------------------------- 1 | function [filter,xc,yc] = MakeCircleMatchingFilter(diameter,W) 2 | % initialize filter 3 | filter=zeros(W,W); 4 | % define coordinates for the center of the WxW filter 5 | if(rem(W,2)==0) 6 | xc=W/2+0.5; 7 | yc=W/2+0.5; 8 | else 9 | xc=(W+1)/2; 10 | yc=xc; 11 | end 12 | % Use double-for loops to check if each pixel lies in the foreground of the circle 13 | for i=1:W 14 | for j=1:W 15 | if(sqrt((i-xc)^2+(j-yc)^2)<=(diameter/2)) 16 | filter(i,j)=1; 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /Making_waves.m: -------------------------------------------------------------------------------- 1 | % Define T, Fs, and f (vector of sound frequencies) 2 | T = 3; 3 | Fs = 44100; 4 | f = [330 247 208 165 123 82]; 5 | % Compute time vector, t 6 | t = [0:1/Fs:T-1/Fs]; 7 | % Use a for-loop to construct y as a sum of cosines 8 | y = zeros(1,132300); 9 | for i = 1:length(f) 10 | for j = 1:length(t) 11 | y(j) = y(j) + cos(2*pi*f(i)*t(j)); 12 | end 13 | end 14 | plot(y,t) 15 | -------------------------------------------------------------------------------- /OtsuThreshold.m: -------------------------------------------------------------------------------- 1 | function [msk,thrsh] = OtsuThreshold(img) 2 | % Define the Otsu threshold 'thrsh' using the histogram of img 3 | thrsh = otsuthresh(imhist(img))*255; 4 | % Apply the threshold to 'img' to make 'msk' 5 | msk = img > thrsh; 6 | end 7 | 8 | 9 | img = imread('mri.tif'); 10 | [msk,thrsh] = OtsuThreshold(img); 11 | 12 | imagesc(img) 13 | title('mri') 14 | colormap(gray) 15 | figure(); 16 | imagesc(msk) 17 | colormap(gray) 18 | thrsh % = 36 19 | -------------------------------------------------------------------------------- /Quizzes - Week 2: -------------------------------------------------------------------------------- 1 | Quiz 1 - Loading and Inspecting Datasets 2 | 3 | # 0.15 4 | 5 | Quiz 2 - Detecting Outliers 6 | 7 | # 1) 9829 8 | # 2) 14009 9 | # 3) - 10 | 11 | Quiz 3 - Histogram plots 12 | 13 | # 7 14 | 15 | Quiz 4 - Scatter plots 16 | 17 | # exp(j*pi)+1=0 18 | 19 | Quiz 5 - PCA 20 | 21 | # 1) 120 22 | # 2) 12 23 | # 3) - 24 | 25 | Quiz 6 - Smartphone activity classifier 26 | 27 | # 96.9345 28 | 29 | Quiz 7 - Predicting Fuel Efficiency Using Regression Trees 30 | 31 | # 1) fitrtree 32 | # 2) - 33 | 34 | Quiz 8 - Predicting Fuel Efficiency Using Gaussian Process Regression 35 | 36 | # 1) fitrgp 37 | # 2) - 38 | # 3) Gaussian Process regression 39 | -------------------------------------------------------------------------------- /Quizzes - Week 3: -------------------------------------------------------------------------------- 1 | Quiz 1 - Reverse Audio 2 | 3 | load ReverseAudio.mat 4 | % [y_orig,Fs,format] = wavread('---') 5 | reverse = y_rev(:,1); 6 | original = flipud(reverse) 7 | subplot(2,1,1) 8 | plot (reverse) 9 | title('Reverse') 10 | subplot(2,1,2) 11 | plot (original) 12 | title('Original') 13 | % sound(reverse, Fs) 14 | sound(original,Fs) 15 | 16 | # matlab 17 | 18 | Quiz 2 - Spectrum plotting 19 | 20 | function MagnitudeSpectrumPlot(yfft,f,col) 21 | if nargin<3 22 | col = 'b' 23 | end 24 | plot(f,abs(yfft),col); 25 | xlabel('Frequency (Hz)') 26 | ylabel('|Y(f)|') 27 | end 28 | load crickets.mat 29 | soundsc(crickets,Fs) 30 | [yfft, f] = myfft(crickets,Fs); 31 | MagnitudeSpectrumPlot(yfft,f,'*') 32 | 33 | # VU 34 | 35 | Quiz 3 - Filter Quality Analysis 36 | 37 | Fs = 1000; 38 | freq_range = [100,200]; 39 | filt10 = fir1(10,freq_range/(Fs/2)); 40 | filt100 = fir1(100,freq_range/(Fs/2)); 41 | filt1000 = fir1(1000,freq_range/(Fs/2)); 42 | [yfft, f] = myfft(filt10,Fs) 43 | MagnitudeSpectrumPlot(yfft,f,'*') % check Y near X = 90 44 | [yfft, f] = myfft(filt100,Fs) 45 | MagnitudeSpectrumPlot(yfft,f,'*') % check Y near X = 90 46 | [yfft, f] = myfft(filt1000,Fs) 47 | MagnitudeSpectrumPlot(yfft,f,'*') % check Y near X = 90 48 | 49 | # 1) 0.77 50 | # 2) 0.059 51 | # 3) 0.00068 52 | -------------------------------------------------------------------------------- /Quizzes - Week 4: -------------------------------------------------------------------------------- 1 | Quiz 1 - Cropping 2 | 3 | imread('logo.tif'); 4 | data = imread('logo.tif'); 5 | crop = data(30:50,20:90); 6 | imagesc(crop) 7 | 8 | # MATH 9 | 10 | Quiz 2 - Color Images 11 | 12 | load RGB 13 | im = cat(3,R,G,B); 14 | imshow(im) 15 | 16 | # Color Images In MATLAB 17 | 18 | Quiz 3 - Motion 19 | 20 | filter = fspecial('motion'); 21 | img = imread('cameraman.tif'); 22 | conved = conv2(img,filter,'same'); 23 | meanIntensityValue = mean2(conved); 24 | 25 | # - 26 | 27 | Quiz 4 - Convex Hull 28 | 29 | load convhull.mat 30 | CH = bwconvhull(msk); 31 | imshow(CH); 32 | 33 | # hexagon 34 | 35 | Quiz 5 - Dilation and Erosion 36 | 37 | img = imread('cameraman.tif'); 38 | thrsh = otsuthresh(imhist(img))*255; 39 | msk = img <= thrsh; 40 | msk_erode = imerode(msk,ones(7,7)); 41 | dilated = imdilate(msk_erode,ones(7,7)); 42 | ConnectedComponent = bwconncomp(dilated) 43 | 44 | subplot(3,1,1) 45 | plot(msk) 46 | subplot(3,1,2) 47 | plot(msk_erode) 48 | subplot(3,1,3) 49 | plot(dilated) 50 | 51 | # 6 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MATLAB Programming for Engineers and Scientists ([Certificate](https://www.coursera.org/account/accomplishments/specialization/certificate/GVN48LCNEPZW)) 2 | 3 | - Computer programming in general and the MATLAB language in particular. 4 | - Program efficiency and an introduction to algorithm complexity. 5 | - Advanced MATLAB features such as the App Designer, Live Scripts and Object-Oriented Programming. 6 | - Image processing, data visualization and an introduction to machine learning. 7 | 8 | ## 1. Introduction to Programming with MATLAB 9 | - Fundamental computer programming concepts such as variables, control structures, functions and many others. 10 | - The powerful support MATLAb provides for working with matrices. 11 | - Various data types and how to handle them in MATLAB. 12 | - File input/output. 13 | 14 | ## Mastering Programming with MATLAB 15 | - Advanced concepts related to functions such as recursion and function handles. 16 | - The basics of Object Oriented Programming. 17 | - Writing efficient programs. 18 | - Writing Live Scripts and create professional graphical user interfaces. 19 | 20 | ## Introduction to Data, Signal, and Image Analysis with MATLAB 21 | - How signals, images, and data are represented and manipulated in MATLAB. 22 | - Applying machine learning methods for data classification and prediction in MATLAB. 23 | - Experience with methods for data visualization, including high dimensional datasets in MATLAB. 24 | - Essential signal frequency analysis and image processing methods in MATLAB. 25 | -------------------------------------------------------------------------------- /SignalResample.m: -------------------------------------------------------------------------------- 1 | function y = SignalResample(x, xFs, yFs) 2 | 3 | % Find the total time duration 'T' 4 | T = (length(x)-1)/xFs 5 | % Alternative: T = x(end) - x(1) 6 | 7 | % Using 'T', define a time vector 'tx' 8 | tx = [0:1/xFs:T] 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); 14 | % Alternative: y = [x(1):1/yFs:x(end)] 15 | 16 | end 17 | 18 | x = [1:0.5:5.5]; 19 | xFs = 2; 20 | yFs = 4; 21 | y = SignalResample(x, xFs, yFs) 22 | 23 | x = [1:0.5:5.5]; 24 | xFs = 2; 25 | yFs = 1; 26 | y = SignalResample(x, xFs, yFs) 27 | -------------------------------------------------------------------------------- /SobelMagnitude.m: -------------------------------------------------------------------------------- 1 | function edge_mag = SobelMagnitude(img) 2 | % Use fspecial to generate the horizontal and vertical Sobel filters (sh and sv) 3 | img = im2double(img) 4 | sh = fspecial('sobel') 5 | sv = sh' 6 | % Apply both filters to the image to generate img_sh and img_sv 7 | img_sh = imfilter(img,sh); 8 | img_sv = imfilter(img,sv); 9 | % Compute edge_mag as the square root of the sum of the squared img_sh and img_sv results 10 | sum = img_sh.^2 + img_sv.^2; 11 | edge_mag = sqrt(sum); 12 | 13 | 14 | 15 | img = imread('cameraman.tif'); 16 | edge_mag = SobelMagnitude(img); 17 | imagesc(img); colormap(gray); 18 | figure; imagesc(edge_mag); colormap(gray); 19 | -------------------------------------------------------------------------------- /Spectrogram.m: -------------------------------------------------------------------------------- 1 | load gong % loads gong sound y and sampling frequency Fs 2 | % can play in MATLAB Online with soundsc(y,Fs) 3 | soundsc(y(1:4*Fs),Fs) 4 | % call spectrogram to get s,f,t 5 | [s,f,t] = spectrogram(y,256,[],[],Fs); 6 | % Use imagesc to display it 7 | imagesc(f,t,log(abs(s'))) 8 | 9 | colorbar 10 | axis xy 11 | xlabel('Frequency (Hz)') 12 | ylabel('Time (s)') 13 | -------------------------------------------------------------------------------- /cumulative_percent_variance_permode.m: -------------------------------------------------------------------------------- 1 | load humanactivity.mat 2 | D = feat; % [24075 x 60] matrix containing 60 feature measurements from 24075 samples 3 | 4 | % compute eigvals 5 | [eigvects,~,eigvals] = pca(D); 6 | 7 | % compute the cumulative_percent_variance_permode vector. 8 | percvar = 100*eigvals/sum(eigvals); 9 | cumulative_percent_variance_permode = cumsum(percvar); 10 | 11 | % Define N as the number of eigenvectors needed to capture at least 99.9% of the variation in D. 12 | %N = length(cumulative_percent_variance_permode (cumulative_percent_variance_permode >= 99.9)) 13 | %cumulative_percent_variance_permode 14 | N=5; 15 | -------------------------------------------------------------------------------- /ellipsoid_fit_data.m: -------------------------------------------------------------------------------- 1 | load fisheriris 2 | D = meas; % [150 x 4] data feature matrix containing 4 features of 150 samples 3 | % compute D_pca and eigvals using the pca function 4 | [eigvects,D_pca,eigvals] = pca(D); 5 | % Define D_pca_x and D_pca_y, the first two dimensions of the data in the D_pca feature space 6 | D_pca_x = D_pca(:,1); 7 | D_pca_y = D_pca(:,2); 8 | % scatter plot the data with asterisks '*' 9 | plot(D_pca_x,D_pca_y,'*') 10 | % Define ellipse_x and ellipse_y, x and y coordinates for the PCA ellipsoid in the first 2 dimensions as a function of theta 11 | theta = 2*pi*[0:100]/100; 12 | 13 | ellipse_x = 2*sqrt(eigvals(1))*cos(theta); 14 | ellipse_y = 2*sqrt(eigvals(2))*sin(theta); 15 | %Plot the ellipse with red dashed lines 'r--' 16 | 17 | %Use axis equal to correct aspect ratio 18 | axis equal 19 | -------------------------------------------------------------------------------- /my_fitpca.m: -------------------------------------------------------------------------------- 1 | function mdl = my_fitpca(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), eigenvalues (3rd output), and mean feature vector (6th output) 6 | % create a subfield 'class' within the output struct mdl, which is a vector of length numclasses 7 | % mdl.class(i) has subfields 'eigvects' (the eigenvectors matrix output from 'pca', transposed), 'eigvals' (the eigenvalues output from 'pca'), and 'mu' (the mean feature vector). 8 | for i = 1:numclasses 9 | [eigvects,~,eigvals,~,~,mu] = pca(D(class==class_labels(i),:)); 10 | mdl.class(i).eigvects = eigvects'; 11 | mdl.class(i).eigvals = eigvals; 12 | mdl.class(i).mu = mu; 13 | end 14 | end 15 | 16 | 17 | D = [1 3 2 4;1 3 4 5]'; 18 | class = [0;0;1;1]; 19 | mdl = my_fitpca(D,class); 20 | mdl.class(1) % eigvects: [0.7071 0.7071]; eigvals: 4; mu: [2 2]; 21 | mdl.class(2) % eigvects: [0.8944 0.4472]; eigvals: 2.5000; mu: [3 4.5000]; 22 | 23 | 24 | D = [1 3 2 4 5 ;1 3 4 5 6; 6 3 2 1 7]'; 25 | class = [0;0;1;1;2]; 26 | mdl = my_fitpca(D,class); 27 | mdl.class(1) % eigvects: [-0.4851 -0.4851 0.7276]; eigvals: 8.5000; mu: [2 2 4.5000] 28 | mdl.class(2) % eigvects: [0.8165 0.4082 -0.4082]; eigvals: 3.0000; mu: [3 4.5000 1.5000] 29 | 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!) 30 | -------------------------------------------------------------------------------- /my_predictpca.m: -------------------------------------------------------------------------------- 1 | function [class,score] = my_predictpca(mdl,data) 2 | % Initialize output 'class' and 'score' to Mx1 zero vectors 3 | [r,c] = size(data); 4 | class = zeros(r,1); 5 | score = zeros(r,1); 6 | % Loop over the M 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 | for j = 1:length(mdl.class) 13 | mdscore(j) = MahalanobisDistance(mdl.class(j),data(i,:)); 14 | end 15 | [score(i),class(i)] = min(mdscore); 16 | end 17 | end 18 | % embed your MahalanobisDistance function you created in the previous assignment here: 19 | function [md,b,std_per_mode] = MahalanobisDistance(pcamdl,v) 20 | % compute b, our PCA coordinates for v 21 | b = pcamdl.eigvects*(v-pcamdl.mu)'; 22 | % compute std_per_mode, the standard deviation distance from the mean for v for each mode of variation 23 | std_per_mode = abs(b)./sqrt(pcamdl.eigvals); 24 | % compute md, the Mahalanobis distance 25 | md = sqrt(sum(std_per_mode.^2)); 26 | end 27 | 28 | 29 | load fisheriris 30 | [~,~,class] = unique(species); 31 | %split into 50/50 training and testing data 32 | D_train = meas(1:2:end,:); 33 | class_train = class(1:2:end); 34 | D_test = meas(2:2:end,:); 35 | class_test = class(2:2:end); 36 | 37 | % Create pca model struct with pca model for each class using the training set (this is what 'my_fitpca' would do) 38 | for i=1:3 39 | [eigvects,~,eigvals,~,~,mu] = pca(D_train(class_train==i,:)); 40 | mdl.class(i).eigvects = eigvects; mdl.class(i).eigvals = eigvals; mdl.class(i).mu = mu; 41 | end 42 | 43 | % Use our new function to estimate classification on the testing set 44 | [class_est, score_est] = my_predictpca(mdl,D_test); 45 | sum(class_est==class_test)/length(class_est)*100 % We should find 97.3333% classification accuracy! 46 | -------------------------------------------------------------------------------- /myfft.m: -------------------------------------------------------------------------------- 1 | function [yfft, f] = myfft(y,Fs) 2 | %compute the standard fft 3 | yfft = fft(y); 4 | yfft = yfft(1:ceil((length(y)+1)/2)); 5 | %trim away the redundant part 6 | sampnum = [0:(length(yfft)-1)]'; 7 | %compute the frequencies to which each fft entry corresponds. 8 | f = sampnum*Fs/length(y); 9 | end 10 | 11 | 12 | % Even length y 13 | Fs = 10; 14 | y = [0 0 0 0 1 0 0 0 0 0]'; 15 | [yfft, f] = myfft(y,Fs); 16 | abs(yfft') 17 | 18 | 19 | % Odd length y 20 | Fs = 10; 21 | y = [0 0 0 0 1 0 0 0 0]'; 22 | [yfft, f] = myfft(y,Fs); 23 | abs(yfft') % All 1's (constant) 24 | f' % you should get 0:10/9:40/9 25 | -------------------------------------------------------------------------------- /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 = ifft([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 = ifft([yfft; conj(flipud(yfft(2:end)))]); 10 | end 11 | % perform ifft 12 | end 13 | 14 | 15 | 16 | % Even length y 17 | Fs = 10; 18 | yfft = [0 0 1 0 0 0 0 0 0 0]'; % magnitude spectrum with single frequency corresponds to a single cosine 19 | f = 0:5; 20 | y = myifft(yfft,Fs,f); 21 | t = 0:1/Fs:(length(y)-1)/Fs; 22 | plot(t,y) 23 | yEven = y' % = [0.1053 0.0831 0.0258 -0.0423 -0.0926 ...] 24 | 25 | % Odd length y 26 | Fs = 10; 27 | yfft = [0 0 1 0 0 0 0 0 0]'; 28 | f = 0:10/9:40/9; 29 | y = myifft(yfft,Fs,f); 30 | t = 0:1/Fs:(length(y)-1)/Fs; 31 | figure 32 | plot(t,y) 33 | yOdd = y' % = [ 0.1176 0.0869 0.0109 -0.0709 -0.1156 ...] 34 | -------------------------------------------------------------------------------- /standard_deviation_distance.m: -------------------------------------------------------------------------------- 1 | function dist = standard_deviation_distance(v,x) 2 | signed = x - mean(v) 3 | dist = signed / std(v) 4 | end 5 | 6 | v = [10 12 14]; 7 | x = 7; 8 | dist = standard_deviation_distance(v,x)% =-2.5 9 | --------------------------------------------------------------------------------