|
Image Processing : Extracting and Analyzing Shapes |
|
After using a morphological operation to expose the basic elements within an image, it is often useful to then extract and analyze specific information about those image elements. The following examples use the LABEL_REGION function and the CONTOUR procedure to identify and extract information about specific image objects.
The LABEL_REGION function labels all of the regions within a binary image, giving each region a unique index number. Use this function in conjunction with the HISTOGRAM function to view the population of each region. See Using LABEL_REGION to Extract Image Object Information in the following section for an example.
The CONTOUR procedure draws a contour plot from image data, and allows the selection of image objects occurring at a specific contour level. Further processing using PATH_* keywords returns the location and coordinates of polygons that define a specific contour level. See Using CONTOUR to Extract Image Object Information for an example.
The following example identifies unique regions within the image of the Rhinosporidium seeberi parasitic protozoans and prints out region populations. Complete the following steps for a detailed description of the process.
| Example Code See labelregionexample.pro in the examples/doc/image subdirectory of the IDL installation directory for code that duplicates this example. |
DEVICE, DECOMPOSED = 0, RETAIN = 2 LOADCT, 0
file = FILEPATH('r_seeberi.jpg', $
SUBDIRECTORY = ['examples','data'])
READ_JPEG, file, image, /GRAYSCALE
dims = SIZE(image, /DIMENSIONS) padImg = REPLICATE(0B, dims[0]+20, dims[1]+20) padImg[10,10] = image
dims = SIZE(padImg, /DIMENSIONS) WINDOW, 0, XSIZE = 2*dims[0], YSIZE = 2*dims[1], $ TITLE = 'Opened, Thresholded and Labeled Region Images' TVSCL, padImg, 0
radius = 5 strucElem = SHIFT(DIST(2*radius+1), radius, radius) LE radius
| Tip Enter PRINT, strucElem to view the structure created by the previous statement. |
openImg = MORPH_OPEN(padImg, strucElem, /GRAY) TVSCL, openImg, 1
This original image (left) and opened image (right) appear in the following figure.
![]() |
WINDOW, 2, XSIZE = 400, YSIZE = 300 PLOT, HISTOGRAM(openImg)
| Note Using an intensity histogram as a guide for determining threshold values is described in the section, Determining Intensity Values for Threshold and Stretch. |
threshImg = openImg GE 170 WSET, 0 TVSCL, threshImg, 2
regions = LABEL_REGION(threshImg)
hist = HISTOGRAM(regions)
FOR i=1, N_ELEMENTS (hist) - 1 DO PRINT, 'Region', i, $ ', Pixel Popluation = ', hist(i), $ ' Percent = ', 100.*FLOAT(hist[i])/(dims[0]*dims[1])
LOADCT, 12 TVSCL, regions, 3
In the following figure, the image containing the labeled regions (right) shows 19 distinct foreground regions.
![]() |
| Tip Display the color table by entering XLOADCT at the command line. By viewing the color table, you can see that region index values start in the lower-left corner of the image. Realizing this makes it easier to relate the region populations printed in the Output Log with the regions shown in the image. |
WINDOW, 1, $ TITLE = 'Surface Representation of Region Populations' FOR i = 1, N_ELEMENTS(hist)-1 DO $ regions[WHERE(regions EQ i)] = hist[i] SURFACE, regions
The previous command results in the following display of the region populations.
It is possible to extract information about an image feature using the CONTOUR procedure. The following example illustrates how to select an image feature and return the area of that feature, in this case, calculating the size of a gas pocket in a CT scan of the thoracic cavity. Complete the following steps for a detailed description of the process.
| Example Code See extractcontourinfo.pro in the examples/doc/image subdirectory of the IDL installation directory for code that duplicates this example. |
| Note For more information on computing statistics for defined image objects see Working with Regions of Interest (ROIs) |
DEVICE, DECOMPOSED = 0, RETAIN = 2 LOADCT, 5
file = FILEPATH('ctscan.dat', $
SUBDIRECTORY = ['examples', 'data'])
dims = [256, 256]
image = READ_BINARY(file, DATA_DIMS = dims)
WINDOW, 0, XSIZE = dims[0], YSIZE = dims[1] TVSCL, image
WINDOW, 2 CONTOUR, image, /XSTYLE, /YSTYLE, NLEVELS = 255, $ /FILL
| Note Replace NLEVELS = 255 with NLEVELS = MAX(image) if your display uses less than 256 colors. |
CONTOUR, image, /XSTYLE, /YSTYLE, LEVELS = 40, $ PATH_INFO = info, PATH_XY = xy, /PATH_DATA_COORDS
The PATH_INFO variable, info, contains information about the paths of the contours, which when used in conjunction with PATH_XY, traces closed contour paths. Specify PATH_DATA_COORDS when using PATH_XY if you want the contour positions to be measured in data units instead of the default normalized units.
FOR i = 0, (N_ELEMENTS(info) - 1) DO PLOTS, $ xy[*, info[i].offset:(info[i].offset + info[i].n - 1)], $ LINESTYLE = (i < 5), /DATA
x = REFORM(xy[0, info[2].offset:(info[2].offset + $ info[2].n - 1)]) y = REFORM(xy[1, info[2].offset:(info[2].offset + $ info[2].n - 1)])
x = [x, x[0]] y = [y, y[0]]
ARROW, 10, 10, (MIN(x) + MAX(x))/2, COLOR = 180, $ (MIN(y) + MAX(y))/2, THICK = 2, /DATA
The gas pocket is indicated with an arrow as shown in the following figure.
![]() |
PRINT, '' PRINT, ' x , y' PRINT, [TRANSPOSE(x), TRANSPOSE(y)], FORMAT = '(2F15.6)'
The FORMAT statement tells IDL to format two 15 character floating point values that have 6 characters following the decimal of each value.
area = POLY_AREA(x, y) PRINT, 'area = ', ROUND(area), ' square pixels'
The result, 121 square pixels, appears in the Output Log.
IDL Online Help (March 06, 2007)