comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Filtering based on Hessian Matrix
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Return to the default flat view Create a new topic Submit Reply
Filtering based on Hessian Matrix [message #40174] Thu, 15 July 2004 12:34 Go to previous message
stef is currently offline  stef
Messages: 6
Registered: April 2004
Junior Member
Hi there,

I'm posting here a wonderful filter (my humble opinion) to detect
bright or dark lines, blobs etc..., mainly in a try to give back a
little bit to the community. It's a great place here!

It is based on the eigenvalues of the Hessian Matrix (a matrix of
partial
secondary derivatives). It's currently standard procedure to use a
filter similar to this prior to segmentation or vessel tracking (there
are 20+ papers out there, google for 'vessel enhancement hessian
matrix').

There's a demo included in the source code. I use the filter to detect
the coronary vessels. I do have a 3D version of the filter, write me a
mail if you're interested. However, the 3D filter is much slower,
since the analytical solution for the eigenvalues of a 3 by 3 Matrix
is not trivial. So I was forced to use a triple FOR loop (shame on me,
other solutions highly appreciated) and then use LA_EIGENQL on each
voxel. If anyone has a C-Coded version of this filter, I'd be glad to
write an IDL Wrapper for it.

Have a great day,
Stefan


;+
; Copyright (c) Dept. Radiology, University of California San
Francisco (UCSF)
; written by: Stefan Tuchschmid, stefan.tuchschmid@netpictures.ch
;
; NAME:
; CV_Vessel_Filter_2D
;
; PURPOSE:
; This function is a 2D version of the vesselness enhancement filter
; [A. Frangi, W. Niessen, K.L. Vincken, and M.A. Viergever
; Multiscale vessel enhancement filtering.
; Proc. MICCAI'98, pp.130-137, 1998. ]
; It is based on the eigenvalues of a Hessian matrix (a matrix of
partial
; secondary derivatives)
;
; This version detects bright lines, but could easily be adapted to
; detect dark lines, or dark and brigh blobs, etc..
;
; CATEGORY:
; Filtering
;
;
; EXAMPLE:
;
; ;Read the image
; path=FILEPATH('md5290fc1.jpg',SUBDIR=['examples','data'])
; READ_JPEG, path, img
;
; ;Create window:
; WINDOW, 0, XSIZE=600, YSIZE=600
;
; ;Show original image
; TVSCL, img, 0
;
; ;Filter image
; filtered=CV_Vessel_Filter_2D(img)
;
; ;Show filtered image
; TVSCL, filtered, 1
;
;
; MODIFICATION HISTORY:
; Written by: Stefan Tuchschmid, stefan.tuchschmid@netpictures.ch



FUNCTION CV_Vessel_Filter_2D, image

image=FLOAT(image)

x_size=(SIZE(image, /DIMENSIONS))[0]
y_size=(SIZE(image, /DIMENSIONS))[1]


; Smooth image, kernel can be changed
; a larger kernel will detect bigger vessels
smooth_kernel=[[1,2,1],$
[2,4,2],$
[1,2,1]]

smooth_image=CONVOL(image, smooth_kernel, 16)


; Calculate the Hessian Matrix
x_deriv_kernel=[-1,0,1]
y_deriv_kernel=TRANSPOSE([-1,0,1])

Lx=CONVOL(smooth_image, x_deriv_kernel)
Ly=CONVOL(smooth_image, y_deriv_kernel)

Lxy=CONVOL(Lx, y_deriv_kernel)

Lxx=CONVOL(Lx, x_deriv_kernel)
Lyy=CONVOL(Ly, y_deriv_kernel)


; Analyticaly solve for the eigenvalues
t1=(Lxx+Lyy)/2
t2=SQRT((Lxx+Lyy)^2- 4*(Lxx*Lyy-Lxy^2))/2

lambda_1 = REFORM(t1+t2,x_size*y_size)
lambda_2 = REFORM(t1-t2,x_size*y_size)

lambda_array=[[lambda_1],[lambda_2]]

; Sort the eigenvalues
dummy=MAX(ABS(lambda_array), max_subscript, DIMENSION=2,
SUBSCRIPT_MIN=min_subscript)
lambda_max=lambda_array[max_subscript]
lambda_min=lambda_array[min_subscript]


; Filter response:
; bright blob : both eigenvalues large AND negative
; dark blob : both eigenvalues large AND positive
; bright line: one eigenvalue small, other large AND negative
; dark line: one eigenvalue small, other large AND positive
; flat structure: both eigenvalues small

; Here, we want to detect bright lines
lambda_max = TEMPORARY(lambda_max) < 0.0
lambda_min = TEMPORARY(lambda_min) < 0.0

filtered_image = REFORM(-lambda_max, x_size, y_size)

; Alternative Filter
; filtered_image = REFORM(-lambda_max+lambda_min, x_size, y_size)


RETURN, filtered_image
END


PRO CV_Vessel_Filter_2D_Demo, image

;Read the image
path=FILEPATH('md5290fc1.jpg',SUBDIR=['examples','data'])
READ_JPEG, path, img

;Create window:
WINDOW, 0, XSIZE=600, YSIZE=600

;Show original image
TVSCL, img, 0

;Filter image
filtered=CV_Vessel_Filter_2D(img)

;Show filtered image
TVSCL, filtered, 1
END
[Message index]
 
Read Message
Read Message
Previous Topic: adding a 4th dimension to 3D array during concatenation
Next Topic: Plot function failing!

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 15:57:02 PDT 2025

Total time taken to generate the page: 0.00464 seconds