program IrregaulrRegions ; { Helper tools for extracting, inserting, and processing irregular regions } { Copyright (C) 2007, Digital Optics Ltd, Auckland, New Zealand } { Version 1.0 } { Last update: October 2007 } { INSTRUCTIONS: 1. Use the ROI tools (either rectangular or polygon) to mark out an irregular region in the image. 2. Use Extract to copy the region of interest from the image so you can work on it in isolation (ie. without modifying the rest of the image). 3. Process the extracted region until you are satisfied with it. You can use any V++ or VPascal operation - the most useful will probably be things like brightness, contrast, gamma, sharpening, smoothing, and rank filters. 4. Don't be concerned about what the background looks like (ie. the area outside the shape you marked out) as this will be ignored when inserting it back into the original image. 5. Use Insert to put the modified region back into the original image at the original location. It doesn't matter if you have deleted the original ROI (either polygon or rectangle), as this module remembers exactly where to put the region. 6. The bright and dark processing option is no longer required. Simply extract and process the bright and dark areas independently. 7. Please address questions about this module to: info@digitaloptics.co.nz } toolbar 'Irregular Regions' ; var Image ; // original image Chords ; // chord table (normalized) rOrgX,rOrgY ; // region origin rSizeX,rSizeY ; // region size procedure FreehandTools ; button btn_Text,'Irregular Regions:|This is the freehand region processing toolbar' ; begin end; procedure FindRegionBoundary ; { Calculate the origin and size of the current chord table region } var j,xMin,yMin,xMax,yMax ; begin if IsArray( Chords ) then begin { init } xMin := $7FFFFFFF ; yMin := $7FFFFFFF ; xMax := 0 ; yMax := 0 ; { search table } for j := 0 to GetYMax( Chords ) do begin if Chords[0,j] < xMin then xMin := Chords[0,j] ; if Chords[1,j] > xMax then xMax := Chords[1,j] ; if Chords[2,j] < yMin then yMin := Chords[2,j] ; if Chords[2,j] > yMax then yMax := Chords[2,j] ; end; { calculate boundary } rOrgX := xMin ; rOrgY := yMin ; rSizeX := xMax - xMin + 1 ; rSizeY := yMax - yMin + 1 ; end; end; { FindRegionBoundary } procedure Extract ; button btn_Text,'Extract|Extract an irregular region from an image' ; { Extracts a rectangular or polygonal area from an image and displays it on screen } var Vertices ; Rect ; Data ; Area ; begin GetActiveImage( Image ) ; if not IsNull( Image ) then begin { look for a polygon } Vertices := GetPolygon( Image ) ; { no polygon ? } if IsNull( Vertices ) then begin { look for a rectangle instead } Rect := GetROI( Image ) ; if not IsNull( Rect ) then begin { create vertex array manually } Vertices := CreateArray( typ_Longint,2,4 ) ; { insert coordinates of rectangle corners } Vertices[0,0] := Rect[0,0] ; // TL Vertices[1,0] := Rect[1,0] ; Vertices[0,1] := Rect[2,0] ; // TR Vertices[1,1] := Rect[1,0] ; Vertices[0,2] := Rect[2,0] ; // BR Vertices[1,2] := Rect[3,0] ; Vertices[0,3] := Rect[0,0] ; // BL Vertices[1,3] := Rect[3,0] ; end; end; { extract area and put on screen } if IsArray( Vertices ) then begin { extract data } Chords := CreateChordTable( Vertices ) ; Data := ExtractChords( Image,Chords ) ; { create new image } FindRegionBoundary ; NormalizeChordTable( Chords ) ; Area := CreateImage( TypeOf( Data ),rSizeX,rSizeY ) ; InsertChords( Area,Chords,Data ) ; Show( Area ) ; end else WriteError( 'Define a region of interest on the image using the ROI or Polygon ROI tools' ) ; end; end; { Extract } procedure Insert ; button btn_Text,'Insert|Insert a modified region back into the original image' ; { Insert modified region data back into an image } var Area1,Area2 ; Data ; ix,iy ; begin if IsImage( Image ) and IsArray( Chords ) then begin { get the modified region image } GetActiveImage( Area1 ) ; if IsImage( Area1 ) then begin { check size match } GetXYSize( Area1,ix,iy ) ; if ( ix = rSizeX ) and ( iy = rSizeY ) then begin { create a display image to lock in BCG changes } CreateDisplayImage( Area1 ) ; GetActiveImage( Area2 ) ; Hide( Area2 ) ; { check type match } if TypeOf( Area2 ) <> TypeOf( Image ) then ConvertType( Area2,TypeOf( Image ) ) ; { insert data back into original image } if Query( 'Insert data back into original image?' ) = id_Yes then begin { save current image for undo } StoreUndoInfo( Image,'Insert',uf_Image ) ; { extract new data from modified region image } Data := ExtractChords( Area2,Chords ) ; { insert at original position in image } OffsetChordTable( Chords,rOrgX,rOrgY ) ; InsertChords( Image,Chords,Data ) ; OffsetChordTable( Chords,-rOrgX,-rOrgY ) ; // revert to normalized chords { update display } Update( Image ) ; end; end else WriteError( 'Region size does not match original area' ) ; end; end else WriteError( 'Extract and process a region first' ) ; end; { Insert } begin { init } rOrgX := 0 ; rOrgY := 0 ; rSizeX := 0 ; rSizeY := 0 ; end.