You are on page 1of 31

Image Processing: 3

Assignment

Edge detection and morphological operations

Date: 01.03.2011 Name: Laura Stoilescu Address: Calslaan 28-5, Zip 7522MC, Enschede Email: l.i.stoilescu@student.utwente.nl Student Number: S1070053
1

Educational Program: Electrical Engineering- Telecommunication Networks

Contents
Contents.................................................................................................................2 Part 1-Finding the vessel contour...........................................................................3 Create a Gaussian PSF matrix with (1, 3, 5 and 9) as a scale parameter. The size of the matrix hsize must be chosen so that it would be a tradeoff between efficient computation and negligible truncation error.......................3 Derivatives....................................................................................................... 9 Plot the real and imaginary parts of the associated OTF; ..............................12 Apply the point spread function.....................................................................13 Explain the results;........................................................................................14 Using the results from the previous exercise, calculate the gradient magnitude and the Laplacian of the image. Describe and explain.................18 Use the Marr Hildreth operation to find an edge map of the image. Use the Laplacian found in question 3 and mention the disadvantages of using this method...........................................................................................................19 Apply a suitable threshold to the Marr Hildreth method and then apply hysteresis thresholding. Explain the results...................................................20 Describe in one sentence the main difference between the Marr Hildreth method and the Canny edge detector. Apply the Canny edge detector by using the function ut_edge. Use hysteresis thresholding and, display the resulting edge map and describe the results.................................................23 Part II: Estimation of the nominal diameter and the diameter of the stenose.....25 Determine and plot the local diameters (the diameter for each column)......25 Estimate the mean diameter..........................................................................26 APPENDIX.............................................................................................................27

The purpose of the first exercise is to develop a method to estimate the nominal diameter of a blood vessel presented in the im_test.png image. In the second exercise, the accuracy of this method will be experimentally evaluated.

Figure 1: The artificially created blood vessel image im_test.png based on a physical model of the X-ray imaging system

The nominal diameter of the blood vessels cross section is Dnom= 1.5mm= 37.5pixels The maximum exposure is equivalent to Emax= 2500 quant/mm2=4quant/pixel

The image intensifier has the OTF given by

where 0 is

the incident X-ray quanta per unit area and is considered to be 1lp/mm

Part 1-Finding the vessel contour


Create a Gaussian PSF matrix with (1, 3, 5 and 9) as a scale parameter. The size of the matrix hsize must be chosen so that it would be a tradeoff between efficient computation and negligible truncation error.

Analyzing the frequency components of the test image we see that we only have a low-frequency cluster gathered around the origin and the rest of the amplitude spectrum is filled with noise components. It is obvious a

low pass filter should be used. Since is given, the matrixs dimensions must be found for optimum convolution. The background noise in the image is given by a Poisson distribution which, for large values of expected number of occurrences, can be approximated by a Gaussian. By convolving the noisy image with the PSF, the resulting image will still have Gaussian distributed noise but the mean and standard deviation will be modified leading to a different weight in the image. A more quantitative useful property of the Gaussian function is its smoothness. If f(x, y) is considered as a function of real variables x and y, it is differentiable innitely many times. Although this property by itself is not too useful with discrete images, it implies that in the frequency domain the Gaussian drops as fast as possible among all functions of a given space-domain support. Thus, it is as a low-pass filter as one can get for a given spatial support. This holds approximately also for the discrete and truncated version of the Gaussian. By applying the Gaussian filter less background quantum noise is obtained at the cost of loosing detail. The scale parameter or the standard deviation and the matrix size give the blending resolution. The larger the variance (and, thus, the standard deviation), the heavier the blurring is. The larger the matrix, the more pixels are part of the blurring process. For the suggested values of the standard deviation we get different Gaussians depicted in Figure 2It is easily seen in the case of =1 (smallest given), the truncation error is by far the smallest but the number of operations needed for convolving this point spread function with the given image is the greatest of all the cases presented in Figure 2. For a standard deviation of 3 and 5 the shape of the Gaussian bell is not strongly affected (most power is still located in the windowed section in our matrix), the detail is not the best but I believe these cases meet the tradeoff characteristics we should follow. In the case of =3, the PSF gives a good description of the distribution and, having a small test image (200x250), the operational complexity is not a pressing condition. In this case (hsize=20) =3 is the best option.

Figure 2: The Gaussian LPFs obtained for each value of Sigma. The matrix size is considered to be 20x20 for this example

Choosing a suitable size for the PSF matrix has major influence in the final task of the exercise. If the truncation error is too high, the PSFs plotted for different standard deviation values will have almost the same characteristic, independent on s value. The effect can be seen either on the PSFs representations or on the filtered images (Figure 2 , Figure 3and Figure 4). In Figure 3 the effect of filtering for the greater values of the standard deviation = [3, 5, 9] appears to be roughly the same.

Figure 3 : Filtered images with the given standard deviations and hsize=20

Plotting the OTFs obtained for each PSF gives an insight upon the cutting frequencies of each filter. As we expected, the lowest value for also gives the best protection from outpassing the cutoff frequency. In Figure 4 the amplitude spectrum for is depicted and, in this case (hsize=20) only for =9 we can see the sidelobes. For a more dramatic view, I chose hsize=5 and the result can be seen in Figure 5.

Figure 4: Amplitude Spectrum of the PSFs with the given standard deviations and hsize=20

Figure 5: Amplitude spectrum of the PSFs for hsize=5

The matrix dimensions for which the four values of the standard deviation are properly discriminated is hsize=55, meaning that the PSF matrix is a quadratic matrix of 55x55.

Figure 6: PSF for all standard deviation values at hsize=55

For these values, we get the PSFs depicted in Figure 6with the associated OTFs shown in Figure 7 and the resulting, filtered images in Figure 8.

Figure 7: Amplitude spectrum of the OTFs for hsize=55

In Figure 8 we can see that with a properly chosen size, the PSF matrix applied to the image gives different results even with large standard deviation.

Figure 8: Filtered images with the PSFs for which hsize was chosen 55

All filtered images resulted by applying the imfilter function, are arrays of the same data type as the input array. The artifacts near the boundary of the filtered images are strong edges formed due to the neighborhood of the infinite periodic array and were removed by replicating the nearest array border values in the input array values outside the bounds of the array.
8

The replicate option improves the result in another way. In the filtered images the vessel contrasts more with the background which seemed counterintuitive. Pixels near the border were convolved with the pixels outside the array (assumed to have value zero) which lead to decreasing contrast. The phenomenon propagates through the entire image by convolving pixels with closer and closer values. But, by choosing to duplicate the missing pixels with the closest ones to the border, the blood vessel is convolved with itself and contrast is actually increased.

Figure 9: How the filtered images would have looked like without the Replicate option set

Derivatives

Give an expression of the derivative with respect to x of the Gaussian PSF, hx; The bi-dimensional Gaussian has the form given below:

which is a symmetric function so both partial derivatives will have the same form, namely:

In MATLAB, I used the symbolic representation of a function and found the corresponding forms for each derivative which match the hand-computed ones:

x = sym('x','real'); y = sym('y','real'); s = sym ('s','real'); f=(exp(-(x^2+y^2)/(2*pi*s^2)))/(2*pi*s^2); xder=simple(diff(f,x)); yder=simple(diff(f,y)); xxder=simple(diff(f,x,2)); yyder=simple(diff(f,y,2)); xyder=simple(diff(diff(f,y),x)); reset(symengine)

The notations were kept similar to the mathematical notations and the results were:
f = 1/ (2*pi*s^2*exp ((x^2 + y^2)/ (2*pi*s^2))) xder = -x/(2*pi^2*s^4*exp((x^2 + y^2)/(2*pi*s^2))) yder = -y/(2*pi^2*s^4*exp((x^2 + y^2)/(2*pi*s^2))) xxder = -(pi*s^2 - x^2)/(2*pi^3*s^6*exp((x^2 + y^2)/(2*pi*s^2))) yyder = -(pi*s^2 - y^2)/(2*pi^3*s^6*exp((x^2 + y^2)/(2*pi*s^2))) xyder =(x*y)/(2*pi^3*s^6*exp((x^2 + y^2)/(2*pi*s^2)))

Using the option pretty, it is easier to check if the formulas correspond by doing a visual match. The normalizing factor makes the integral of the two-dimensional

Gaussian equal to one. This normalization, however, assumes the variables are real, and the Gaussian is defined over the entire plane or on the line. This normalization factor must be taken into account if we want to smooth an image, initially stored in a file of bytes, one byte per pixel, and write
10

the result to another file with the same format, the values in the smoothed image should be in the same range as those of the unsmoothed image. Also, when we compute image derivatives, it is sometimes important to know the actual value of the derivatives, not just a scaled version of them. Create a matrix which contains a sampled version of hx; The test image is a function of a discrete variable, so we cannot take arbitrarily small: the smallest we can go is one pixel. If our unit of measure is the pixel, we have =1
disp=5; hsize=55; side=(hsize-1)/2; [x,y] = meshgrid(-side:side,-side:side); hx=-x/(2*pi*disp^4).*exp(-(x.*x + y.*y)./(2*disp^2)); figure,surf ( hx, 'DisplayName','hx'),title('PSF of hx');

In this part of the code, in hx was introduced the exact formula found at exercise 2a) after initially creating the array in which the PSF will be hosted. This is realized with meshgrid which transforms the domain specified by the input vectors into arrays which can be used to evaluate bi-dimensional functions and three-dimensional plots. The rows and columns are the vectors given as input respectively. The PSF variables (x and y) vary on the given vectors, so we have to do matrix operations instead of scalar ones. The first order derivative of the Gaussian function will have one zero-crossing, the second-order, has two and so on.

11

Figure 10: The partial derivative with respect to x of the Gaussian PSF, noted as hx

Plot the real and imaginary parts of the associated OTF; The OTF is easily computed using psf2otf and the real/imaginary part are separable using abs(OTF) and imag (OTF).
HX=psf2otf(hx,size(im)); figure,surf (fftshift((abs(HX))), 'DisplayName', 'HX'), title('Real part-OTF of hx'); figure,surf (fftshift((imag(HX))), 'DisplayName', 'HX'), title('Imaginary part- OTF of hx');

The resulted transfer functions and their magnitude spectrum are shown below for both real and imaginary part. The characteristic of each part is shown by the variation directions of the lobes: the real part of the OTF is an even function so the variations will be found only in the positive sense of the axis while the imaginary part is an odd function so we will find variations in both directions.

12

Figure 11: First row- Real part of the OTF (right) and the corresponding magnitude spectrum (left); The second row - Imaginary part of the OTF (right) and the corresponding magnitude spectrum(left)

Apply the point spread function

For obtaining the first derivative of the discrete picture was used an approximation of the combination: differentiation and low-pass-filtering as it would be the case for a continuous image.

The approximation is due to the fact that in the continuous case, the differentiation is defined in an infinitesimally small neighborhood of a point, but in the discrete case, the neighborhood is finite. So instead the

13

differentiation a low-pass-filtered image is replaced by a convolution with a differentiated low-pass filter.

In Error: Reference source not found we see no comprehensible data due to the fact that in the original image we only have variation on the vertical axis. On the horizontal axis we only have noise variations Explain the results;
close all disp=5; hsize=55; side=(hsize-1)/2; [x,y] = meshgrid(-side:side,-side:side); arg=exp(-(x.*x + y.*y)./(2*disp^2)); % Compute derivatives hx=-x/(2*pi*disp^4).*arg; hy=-y/(2*pi*disp^4).*arg; hxx=arg.*(x.^2-disp^2)./(2*pi*disp^6); hyy=arg.*(y.^2-disp^2)./(2*pi*disp^6); hxy=(x.*y)/(2*pi*disp^6).*arg; % Apply the filters imfx=imfilter(im,hx,'replicate','conv'); imfy=imfilter(im,hy,'replicate','conv'); imfxx=imfilter(im,hxx,'replicate','conv'); imfyy=imfilter(im,hyy,'replicate','conv'); imfxy=imfilter(im,hxy,'replicate','conv'); HX=psf2otf(hx,size(im)); HY=psf2otf(hy,size(im)); HXX=psf2otf(hxx,size(im)); HYY=psf2otf(hxx,size(im)); HXY=psf2otf(hxy,size(im)); figure(7); subplot 221, subplot 222, subplot 223, subplot 224, surf surf surf surf (hx, 'DisplayName', 'hx'),title('PSF of hx'); (hxx, 'DisplayName', 'hxx'),title('PSF of hxx'); (hxy, 'DisplayName', 'hxy'),title('PSF of hxy'); (hyy, 'DisplayName', 'hyy'),title('PSF of hyy');

clear hx hy hxx hyy hxy; h=fspecial('gaussian',40,7); imf=imfilter(im,h,'replicate'); figure (8); subplot 231,imshow(im,[]),title('Original'); subplot 232,imshow(imfy,[]),title('fy'); subplot 233,imshow(imfyy,[]),title('fyy'); subplot 234,imshow(imfx,[]),title('fx'); subplot 235,imshow(imfxx,[]),title('fxx'); subplot 236,imshow(imfxy,[]),title('fxy'); % Compute OTFs

14

HXr=fftshift(abs(HX)); HYr=fftshift(abs(HY)); HXXr=fftshift(abs(HXX)); HYYr=fftshift(abs(HYY)); HXYr=fftshift(abs(HXY)); figure (10); subplot 231,imshow(fftshift(H{3}),[]),title('Original'); subplot 232,imshow(HXr,[]),title('Real Part -Hx'); subplot 233,imshow(HYr,[]),title('Real Part -Hy'); subplot 234,imshow(HXXr,[]),title('Real Part -Hxx'); subplot 235,imshow(HYYr,[]),title('Real Part -Hyy'); subplot 236,imshow(HXYr,[]),title('Real Part -Hxy'); clear HX HY HXX HYY HXY;

Partial derivatives of f(x, y), the continuous image, can be used to measure the extent and direction of edges, abrupt changes of image brightness that occur along curves in the image plane. Derivatives, or rather their estimates, are cast as convolution operators. We start by computing the derivatives of the test image in the horizontal direction. Derivatives with a large magnitude, either positive or negative, are elements of vertical edges. The partial derivative of a continuous image function f (x, y) with respect to the horizontal variable x is defined as the local slope of the plot of the function along the x direction. The same goes for the derivatives in the vertical direction. For computing derivatives in discrete images, a model describing the images behavior between pixel values is needed. Following the derivatives definition as a slope:

We can describe the relationship between pixels as a linear trend since the first-order difference is exactly the derivative of a linear function that goes through both points:

More generally, if the discrete image is formed by samples of the continuous image, then the latter interpolates the former. Interpolation can be expressed as a hybrid-domain convolution. In the uni-dimensional case, the first derivative of a function in a given point represents the slope of the tangent to the function in that point. If the function in decreasing then the derivative will be negative and vice versa. In the 2D cases, such as images, the same scenario applies.

15

Starting from the upper part of the image and proceeding downwards to where the blood vessel starts, the y derivative decreases and actually becomes negative when the gray levels drop. As soon as the gray levels start to increase, there is a positive slope and the derivative increases, becoming positive. The dark grey levels from the y derivative actually have values close to 0 (because differentiating a constant yields 0), black is close to -4 and white is close to +4. The symmetry in values comes from the fact that the blood vessel is symmetrical. The same approach can be applied to a comparison between the first and the second derivatives with respect to y. Starting from the upper part of the left image, the gray levels decrease at the edges of the blood vessels (because the first derivative is negative) and this can be seen as the upper dark band in the right image. The gray levels from the left image then increase so the second derivative becomes positive. In the end, the gray levels from the left image decrease and the second derivative becomes negative once more, hence the second dark band (Figure 12).

Figure 12: Original image convolved with dispersion 5 PSF, the first and second order derivatives with respect to both axes.

The normalization factor present in all PSFs and OTFs influences negatively the result of the image processing due to: In discrete images we dont want the integral of f(x, y) to be normalized but rather the its sum;
16

Our grids are invariably finite so we only want the values we actually use instead of every value for x and y between two given points

Figure 13: The point spread functions of hx, hxx (first row) and hxy, hyy (second row)

Figure 14: The real part of all transfer functions

17

Using the results from the previous exercise, calculate the gradient magnitude and the Laplacian of the image. Describe and explain.

The gradient magnitude is defined as the Laplacian of the image is defined as Matlab code for computing and displaying them is:
gradient=sqrt(imfx.*imfx+imfy.*imfy); laplacian=imfxx+imfyy; figure(9) subplot 121,imshow(gradient,[]),title('Gradient magnitude'); subplot 122, imshow(laplacian,[]),title('Laplacian');

and . The

Figure 15: Gradient Magnitude and Laplacian

The gradient method detects the edges by looking for the maximum and minimum in the first derivative of the image. The Laplacian method searches for zero crossings in the second derivative of the image to find edges. An edge has the one-dimensional shape of a ramp and calculating the derivative of the image can highlight its location. Taking the gradient of an edge along a preferred direction, we get a maximum located at the center of the edge in the original signal. A pixel location should hold a value greater than a noise threshold to be considered an edge. Edges will have higher pixel intensity values than those surrounding it. So once a threshold is set, the gradient value can be compared to the threshold value and whenever the threshold is exceeded, an edge is detected. As a result, another alternative to finding the location of an edge is to locate the zeros in the second derivative Taking the second derivative, in the edges location we should now find a zero-crossing (places where one pixel is positive and a neighbor is
18

negative) since we are now searching for the slope in a maximum point. Edge magnitude is approximated in digital images by a convolution sum. The sign of the result from two adjacent pixels provides edge orientation and tells us which side of edge brighter. When we apply differential operators to images, the zeroes rarely fall exactly on a pixel. Typically, they fall between pixels. We can isolate these zeroes by nding zero crossings. One nice property of zero crossings is that they provide closed paths (except, of course, where the path extends outside the image border). There are, however, two typical problems with zero-crossing methods: they produce two-pixel thick edges (the positive pixel on one side and the negative one on the other, and they can be extremely sensitive to noise. Zero-crossings of Laplacian operators only tell you where the edge is (actually where the edge lies between), not how strong the edge is. To get the strength of the edge, and to pick which of the two candidate pixels is the better approximation, we can look at the gradient magnitude at the position of the Laplacian zero crossings. Since the second derivative equals 0 when the first derivative changes sign, edges can be detected because of their effect on the first derivative. For example, the Laplacian is negative near the edges of the blood vessel, because that is where the first derivative changed its sign, as can be seen in Figure 12.
Use the Marr Hildreth operation to find an edge map of the image. Use the Laplacian found in question 3 and mention the disadvantages of using this method.
edge_map=false(size(laplacian)); edge_map(laplacian>0)=true; edge_map=bwmorph(edge_map,'remove'); figure(11) subplot 121, imshow(laplacian,[]),title('Laplacian'); subplot 122, imshow(edge_map,[]),title('Edge map');

19

The Marr-Hildreth edge detection method is simple and operates by convolving the image with the Laplacian of the Gaussian function, or, as a fast approximation by Difference of Gaussians. Then, zero-crossings are detected in the filtered result to obtain the edges. If the edge threshold is zero, the edges form a closed loop. A major drawback of this approach is that it is too sensitive: the gradient might change sign even in places where the image varies only slightly, so the gradient magnitude is close to zero, but did actually change sign. As such, the Marr Hildreth method gives a lot of false edges, assuming an edge to be any part of the image where a variation occurs. Also, the localization error may be severe at curved edges. A solution would be using another operator such as Canny based on the search for local directional maxima in the gradient magnitude, or the differential approach based on the search for zero-crossings of the differential expression that corresponds to the second-order derivative in the gradient direction (Both of these operations preceded by a Gaussian smoothing step).
Apply a suitable threshold to the Marr Hildreth method and then apply hysteresis thresholding. Explain the results.

Hysteresis thresholding masks the edge map found by the Marr Hildreth method by the gradient magnitude of the image, eliminating any non edge pixel but keeping the gradient magnitudes of the edge pixels. Next, a marker image is constructed, which is the gradient map found in the previous step, thresholded with a relatively high value (only pixels with a higher value than the threshold will remain), to make sure only strong

20

variations are found. The marker will disregard some weaker edges which might be relevant but this issue is resolved in a later stage. Likewise, a mask image is constructed by thresholding the gradient map with a low value. This makes sure that all edges, whether strong or weak, are retained. The thresholds for the marker and the mask can be selected empirically, by inspecting the gradient map. Alternatively, a semi automatic approach can be used: I have taken the low and the high thresholds to be 20% and, respectively, 80% of the maximum value of the gradient magnitude map. This ensures that the code still works for other images, with different characteristics. The final step is the propagation of the marker into the mask. This is done by considering an edge segment from the mask image to be relevant only if it contains an edge element from the marker image.

21

22

Figure 16: First row- gradient map obtained by masking the gradient magnitude with the Marr - Hildreth edge map (left), gradient map after applying a threshold of half the maximum value of the gradient magnitude (right); Second row- The marker (left) and the mask (right). The thresholds are 80% of the maximum value of the gradient magnitude for the marker and 20% of the maximum value for the mask; Third row- The resulting image after propagating the marker into the mask. The contour of the blood vessel can now be observed

Hysteresis thresholding offers a definite improvement to the Marr Hildreth method, by eliminating false positives, i.e. weak edges. This method guarantees that only strong edges are found. Hopefully, these correspond to actual edges. Of course, if two objects have a very similar color, no algorithm will be able to distinguish between them, except cases in which depth information is used. In all other cases, hysteresis thresholding is a viable option that gives good results. A manner of automatic threshold selection, such as the one used here, is also useful. Describe in one sentence the main difference between the Marr Hildreth method and the Canny edge detector. Apply the Canny edge detector by using the function ut_edge. Use hysteresis thresholding and, display the resulting edge map and describe the results. The most obvious difference between the Marr Hildreth edge detector and the Canny edge detector is that the Marr Hildreth method uses the zero crossings of the Laplacian to find edges, while the Canny approach uses the gradient magnitude and the gradient angle to detect edges. The ut_edge function either returns an edge map with their corresponding magnitudes, or, if using the hysteresis thresholding option, a binary edge map. The algorithm is similar to the Marr Hildreth method in the sense that it propagates strong edges found with a high threshold into a mask image that contains both strong and weak edges, found by using a lower threshold. The threshold themselves represent fractions of pixels that are assigned to the candidate edges so they are inversely proportional to the value of the thresholds used in the Marr Hildreth approach. A small threshold means a small number of pixels that will be assigned to the edge map. Compared to the Marr Hildreth method, the Canny approach is a definite improvement, The edges are smoother, having less ripples in them, and better approximating the actual contour of the blood vessel. This is not surprising actually: the gradient image itself is a much better approximation of the contour of the blood vessel.

23

Figure 17: The Laplacian and the Gradient magnitude of the image

t_canny=[0.2 0.001]; edge_map_canny=ut_edge(im,'c','s',7,'h',t_canny); figure(13),imshow(edge_map_canny,[]), title(['Edge map after applying the Canny edge detector with thresholds ',num2str(thresholds_canny(1)),' and ',num2str(thresholds_canny(2))]);

Figure 18: Edge map after applying the Canny edge detector with thresholds 0.2 and 0.001

24

Figure 19: The edge maps found using Marr-Hildreth edge detector (left) and Canny edge detector (right)

Part II: Estimation of the nominal diameter and the diameter of the stenose
Determine and plot the local diameters (the diameter for each column). I have also calculated the diameters based on the Marr Hildreth edge map. The edge map found by the Marr Hildreth method contained errors in the first and last columns. They can be seen in the edge map from Figure 16. The first two columns contain more than one non zero elements. These were corrected by assigning to these columns the values of their neighbors.

25

36 35 34 33 32 31 30 29 28

20

40

60

80

100

120

140

160

180

200

Figure 20: Plot of the local diameters. It can be seen there is a great variation

42 40 38 36 34 32 30 28 26 24

20

40

60

80

100

120

140

160

180

200

Figure 21: The local diameters found by using the Marr - Hildreth approach.

Estimate the mean diameter. The mean diameter is simply the average of all the local diameters. The resulting value for the Canny edge map is of 30.915 pixels, which is 21.3 % lower than the actual diameter of 37.5 pixels. The mean found for the Marr Hildreth method is 29.425 pixels, which is 27.44 % lower than the actual diameter. These values can be seen below.

26

42 Canny local diameters Canny mean diameter Actual diameter Marr - Hildreth local diameters Marr - Hildreth mean diameter

40

38

36

34

32

30

28

26

24

20

40

60

80

100

120

140

160

180

200

Figure 22: General overview of the obtained results

APPENDIX
clc; %% Part 1 delta = 40e-6; c=1e1; N=250; M=200; s=[1 3 5 9]; H=cell(size(s)); hsize=55;

% pixel distance (m)

im=double(imread('im_test.png')); for i=1:4 h=fspecial('gaussian',hsize,s(i)); imf=imfilter(im,h,'replicate'); % image intensifier coef = 1000; fdelta = 1/(delta*2); [u,v] = freqspace([N,M],'meshgrid'); u = u*fdelta; v = v*fdelta; OTF = fftshift(exp(-sqrt(u.^2 + v.^2)/coef)); IM = (fft2(im)).*OTF; im = real(ifft2(IM)); H{i}=psf2otf(h,size(im)); % Plot the filtered images figure(1); subplot(2,2,i); imshow(imf,[]),title(['sigma=',num2str(s(i))]);

27

% Plot the PSFs in 3D figure(2); subplot(2,2,i); surf (h, 'DisplayName', 'h'),title(['sigma=',num2str(s(i))]); % Plot the magnitude spectrum of the PSFs figure(3); subplot(2,2,i); imshow(fftshift(log(abs(H{i})+1e+01)),[]),title([' sigma=',num2str(s(i))]); end

%% 2. Derivatives %a. Expression for derivatives x = sym('x','real'); y = sym('y','real'); s = sym ('s','real'); f=(exp(-(x^2+y^2)/(2*pi*s^2)))/(2*pi*s^2); xder=simple(diff(f,x)); yder=simple(diff(f,y)); xxder=simple(diff(f,x,2)); yyder=simple(diff(f,y,2)); xyder=simple(diff(diff(f,y),x)); reset(symengine) %% 2b. PSF hx matrix containing the sampled version with sigma=5 and delta=1 clc close all disp=5; hsize=55; side=(hsize-1)/2; [x,y] = meshgrid(-side:side,-side:side); hx=-x/(2*pi*disp^4).*exp(-(x.*x + y.*y)./(2*disp^2)); HX=psf2otf(hx,size(im)); figure(4),surf ( hx, 'DisplayName','hx'),title('PSF of hx'); figure(5); subplot 221,surf (fftshift((abs(HX))), 'DisplayName', 'HX'),title('Real part-OTF of hx'); subplot 223,surf (fftshift((imag(HX))), 'DisplayName', 'HX'),title('Imaginary part- OTF of hx'); subplot 222, imshow (fftshift((abs(HX))),[]),title('Magnitude spectrum for Real part-OTF of hx'); subplot 224, imshow (fftshift((imag(HX))),[]),title('Magnitude spectrum for Imaginary part- OTF of hx'); %% 2c. Apply PSF imfx=imfilter(im,hx,'replicate','conv'); figure(6),imshow(imfx,[]),title('fx');

28

%% 2d. Compute all derivatives close all disp=5; hsize=55; side=(hsize-1)/2; [x,y] = meshgrid(-side:side,-side:side); arg=exp(-(x.*x + y.*y)./(2*disp^2)); % Compute derivatives hx=-x/(2*pi*disp^4).*arg; hy=-y/(2*pi*disp^4).*arg; hxx=arg.*(x.^2-disp^2)./(2*pi*disp^6); hyy=arg.*(y.^2-disp^2)./(2*pi*disp^6); hxy=(x.*y)/(2*pi*disp^6).*arg; % Apply the filters imfx=imfilter(im,hx,'replicate','conv'); imfy=imfilter(im,hy,'replicate','conv'); imfxx=imfilter(im,hxx,'replicate','conv'); imfyy=imfilter(im,hyy,'replicate','conv'); imfxy=imfilter(im,hxy,'replicate','conv'); HX=psf2otf(hx,size(im)); HY=psf2otf(hy,size(im)); HXX=psf2otf(hxx,size(im)); HYY=psf2otf(hxx,size(im)); HXY=psf2otf(hxy,size(im)); figure(7); subplot 221, subplot 222, subplot 223, subplot 224, surf surf surf surf (hx, 'DisplayName', 'hx'),title('PSF of hx'); (hxx, 'DisplayName', 'hxx'),title('PSF of hxx'); (hxy, 'DisplayName', 'hxy'),title('PSF of hxy'); (hyy, 'DisplayName', 'hyy'),title('PSF of hyy');

clear hx hy hxx hyy hxy; h=fspecial('gaussian',40,7); imf=imfilter(im,h,'replicate'); figure (8); subplot 231,imshow(im,[]),title('Original'); subplot 232,imshow(imfy,[]),title('fy'); subplot 233,imshow(imfyy,[]),title('fyy'); subplot 234,imshow(imfx,[]),title('fx'); subplot 235,imshow(imfxx,[]),title('fxx'); subplot 236,imshow(imfxy,[]),title('fxy'); % Compute OTFs HXr=fftshift(abs(HX)); HYr=fftshift(abs(HY)); HXXr=fftshift(abs(HXX)); HYYr=fftshift(abs(HYY)); HXYr=fftshift(abs(HXY)); figure (10); subplot 231,imshow(fftshift(H{3}),[]),title('Original'); subplot 232,imshow(HXr,[]),title('Real Part -Hx');

29

subplot subplot subplot subplot

233,imshow(HYr,[]),title('Real Part -Hy'); 234,imshow(HXXr,[]),title('Real Part -Hxx'); 235,imshow(HYYr,[]),title('Real Part -Hyy'); 236,imshow(HXYr,[]),title('Real Part -Hxy');

clear HX HY HXX HYY HXY; %% 3 Gradient magnitude and Laplacian gradient=sqrt(imfx.*imfx+imfy.*imfy); laplacian=imfxx+imfyy; figure(10) subplot 121,imshow(gradient,[]),title('Gradient magnitude'); subplot 122, imshow(laplacian,[]),title('Laplacian'); %% 4 Marr-Hildreth edge_map=false(size(laplacian)); edge_map(laplacian>0)=true; edge_map=bwmorph(edge_map,'remove'); figure(11) subplot 121, imshow(laplacian,[]),title('Laplacian'); subplot 122, imshow(edge_map,[]),title('Edge map'); %% 5 - Hysteresis thresholding the gradient magnitude gradient_map=gradient; gradient_map(edge_map~=1)=0; gradient_map_thresh=gradient_map; max_grad=max(gradient_map(:)); low_thresh=0.2*max_grad; mid_thresh=0.5*max_grad; high_thresh=0.8*max_grad; gradient_map_thresh(gradient_map<mid_thresh)=0; marker=gradient_map; mask=gradient_map; marker(mask<high_thresh)=0; mask(gradient_map<low_thresh)=0; final=imreconstruct(marker,mask); figure(12) subplot 121, imshow(gradient_map,[]),title('The gradient map without thresholding'); subplot 122, imshow(gradient_map_thresh,[]),title(['Thresholded gradient map ',num2str(mid_thresh)]); figure(13) subplot 121, imshow(marker,[]),title(['The gradient marker. ',num2str(high_thresh)]); subplot 122, imshow(mask,[]),title(['The gradient mask.',num2str(low_thresh)]); figure(14),imshow(final,[]),title('The final image containing the contour of the blood vessel'); %% 6 The Canny edge detector clc t_canny=[0.2 0.001];

30

edge_map_canny=ut_edge(im,'c','s',7,'h',t_canny); figure(15),imshow(edge_map_canny,[]), title(['Edge map after applying the Canny edge detector with thresholds ',num2str(thresholds_canny(1)),' and ',num2str(thresholds_canny(2))]); %% Part II % 1.Determination of the local diameters diam=zeros(1,size(im,2)); [l c]=find(edge_map_canny); diam_mh=diam; final_fix=final; % fix the errors in the first and last columns of the M-H edge map final_fix(:,1)=final_fix(:,2); final_fix(:,200)=final_fix(:,199); [l_mh c_mh]=find(final_fix); c_length=size(c,1)/2; % always an even number j=1; for i=1:c_length diam(i)=l(j+1)-l(j); diam_mh(i)=l_mh(j+1)-l_mh(j); j=j+2; end figure(16),plot(diam,'LineWidth',2) figure(17),plot(diam_mh,'LineWidth',2) %% 2. Estimation of the nominal diameter mean_diam=mean(diam); mean_mh=mean(diam_mh); actual_diam=37.5.*ones(1,size(diam,2)); hold on figure(23) plot(repmat(mean_diam,1,size(diam,2)),'g','LineWidth',2); plot(actual_diam,'r','LineWidth',3); plot(diam_mh(1,15:200),'black','LineWidth',1); plot(repmat(mean_mh,1,size(diam,2)),'y','LineWidth',2); plot(diam,'b','LineWidth',1) legend('Canny local diameters','Canny mean diameter','Actual diameter','Marr - Hildreth local diameters','Marr - Hildreth mean diameter') hold off

31