From dfeaaf255f0a9fc8228238a164456989bc92b832 Mon Sep 17 00:00:00 2001 From: Apostolof Date: Sat, 11 May 2019 19:34:32 +0300 Subject: [PATCH] Init second assignment, Add Image2Graph --- Assignment_2/Image2Graph.m | 33 +++++++++++++++++++++++++++++++++ Assignment_2/Image2Graph.m~ | 36 ++++++++++++++++++++++++++++++++++++ Assignment_2/README.md | 7 +++++++ Assignment_2/aff_d2a.png | Bin 0 -> 5016 bytes Assignment_2/dip_hw_2.mat | Bin 0 -> 12900 bytes 5 files changed, 76 insertions(+) create mode 100644 Assignment_2/Image2Graph.m create mode 100644 Assignment_2/Image2Graph.m~ create mode 100644 Assignment_2/README.md create mode 100644 Assignment_2/aff_d2a.png create mode 100644 Assignment_2/dip_hw_2.mat diff --git a/Assignment_2/Image2Graph.m b/Assignment_2/Image2Graph.m new file mode 100644 index 0000000..5d81366 --- /dev/null +++ b/Assignment_2/Image2Graph.m @@ -0,0 +1,33 @@ +function myAffinityMat = Image2Graph (imIn) +%Image2Graph produces a graph, in the form of a matrix, from an image +% Usage myAffinityMat = Image2Graph (imIn), where: +% Inputs +% - imIn is the input image +% Output +% - myAffinityMat is the graph produced + + % Initializes helper variables + imageWidth = size(imIn, 2); + imageHeight = size(imIn, 1); + + % Initializes output matrix +% myAffinityMat = zeros(imageWidth * imageHeight, imageWidth * ... +% imageHeight); + +% for row = 1:imageHeight +% for column = 1:imageWidth +% % Calculates distance matrix for the current element +% diff = imIn - imIn(row, column, :); +% dist = sum(diff .^ 2, 3) .^ 0.5; +% +% % Calculates affinity matrix +% myAffinityMat((row - 1) * imageWidth + column, :) = ... +% reshape((1 ./ exp(dist)).', 1, []); +% end +% end + + som = reshape(imIn, 1, [], 3); + diff = repmat(som, imageWidth * imageHeight, 1, 1) - permute(som, [2 1 3]); + dist = sum(diff .^ 2, 3) .^ 0.5; + myAffinityMat = 1 ./ exp(dist); +end diff --git a/Assignment_2/Image2Graph.m~ b/Assignment_2/Image2Graph.m~ new file mode 100644 index 0000000..aed0513 --- /dev/null +++ b/Assignment_2/Image2Graph.m~ @@ -0,0 +1,36 @@ +function myAffinityMat = Image2Graph (imIn) +%Image2Graph produces a graph, in the form of a matrix, from an image +% Usage myAffinityMat = Image2Graph (imIn), where: +% Inputs +% - imIn is the input image +% Output +% - myAffinityMat is the graph produced + + imageWidth = size(imIn, 2); + imageHeight = size(imIn, 1); + imageChannels = size(imIn, 3); + + %myAffinityMat = 1 / exp(norm(imIn(:, :))); + myAffinityMat = zeros(imageWidth * imageHeight, imageWidth * imageHeight); + + for row = 1:imageHeight + for column = 1:imageWidth + diff = imIn - imIn(row, column, :); + %diffT = permute(diff, [2 1 3]); + + dist = sum(diff .^ 2, 3) .^ 0.5; + +% dist = zeros(imageWidth, imageHeight); +% for channel = 1:imageChannels +% dist = dist + sqrt(sum (diff(:, :, channel) * diffT(:, :, channel))); +% dist = dist + sqrt(diff(:, :, channel) * diffT(:, :, channel)); +% end + + som = 1 ./ exp(dist); + som2 = reshape(som, 1, []); + som2 = reshape(som.', 1, []); + + myAffinityMat((row - 1) * imageWidth + column, :) = reshape((1 ./ exp(dist), 1, []); + end + end +end diff --git a/Assignment_2/README.md b/Assignment_2/README.md new file mode 100644 index 0000000..1f12eeb --- /dev/null +++ b/Assignment_2/README.md @@ -0,0 +1,7 @@ +# Second deliverable + +In the second deliverable we were tasked to implement a number of functions that: +- produce a graph representation of an image +- do image segmentation using spectral clustering +- do image segmentation using the normalized cuts (N-cuts) method, in both an imperative and recursive way +- execute a series of experiments to test the results of our code \ No newline at end of file diff --git a/Assignment_2/aff_d2a.png b/Assignment_2/aff_d2a.png new file mode 100644 index 0000000000000000000000000000000000000000..6872028e270a0061cbc73fe699655b4373a8fa0c GIT binary patch literal 5016 zcmeAS@N?(olHy`uVBq!ia0y~yVEzNdb2*rRBHOe71p_J00*}aI1_r((Aj~*bn@<`j z$X?><>&pI^m0Lj4a`rLLxj-S664!{5;QX|b^2DN424BYzA4ex0g^-L?1>eMyjPU%T z>|z}S&%9(kn~1v-K=n!>_0C19i6xo&c?uz!xv30>hPu9qmAXa-hL#G3mR3flR;K1Q zyTaTU7=&(mx;TbZ%z1m`V((!C9@c}W57w?M3tc86c*MlaSagp(6ZgJzmh}t_4%h#G z0UG{bw~IXk!;#K928IsdzYGil>c1En6#Tw0GdRq7!OqZNagm>ap>UBr1H&U)D%`z{ z{ebeCt;^II80O!q_V=&Qm_NWS8ozV<{?jt0?XbP0l+XkK0E@<* literal 0 HcmV?d00001 diff --git a/Assignment_2/dip_hw_2.mat b/Assignment_2/dip_hw_2.mat new file mode 100644 index 0000000000000000000000000000000000000000..8883aba882b0e215e809b2cf72b66342ad4912c9 GIT binary patch literal 12900 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