program ManualCount ; { This module allows the user to manually count two types of objects by placing flags on one type of object and then on the other. The counted positions are stored so the user can check progress on either of the object types and alter the count of either type. } { Created by Digital Optics Ltd, August 2002 } { Contact info@digitaloptics.co.nz with feedback or questions } { USER INSTRUCTIONS This module assumes you are manually counting two different types of objects, referred to as type A and type B. To start, load the image you wish to count and press one of the image select buttons (the name of the selected image is shown on the status bar). Optionally, you can press A or B to select the first type you will be counting. The default is to start with type A so let's assume we start by counting type A. Select the built-in flag tool (from the toolbar) and click on all of the type A objects. You will see a small yellow cross (ie. a flag) on each one you have clicked. When you're ready, click the Count button (it has a greek sigma symbol) to count the type A objects. Next, click on B to select type B and repeat the process to count the type B objects. At any time, you can click on "Totals" to see the current counts for A and B. You can switch between A and B at any time, even before the counts are complete, since the module keeps track of the ticked objects and will clear and restore flags as necessary. If you add or remove flags to alter your count then simply press the Count button again to revise the total for the selected object type. Open and compile this module to create a toolbar with the following buttons: Select image Select an image from a list Select active Select the active image A Select type A objects for counting B Select type B objects for counting Count Count the flagged cells as either type A or B Totals Show the current running totals Clear Clear the count for the currently selected object type Reset Clear everything and start again INSTALLATION If you want this module to load automatically when V++ starts then open the module list dialog box, select ManualCount.v, press the Startup button and select "Load and run this module at startup". Once the module is installed for automatic loading, you do not need to open this file in order to use the toolbar. USING FLAGS In order to make the most of this module, you should be familiar with using flags in V++. Note that you click on the image to add flags and can use the backspace key to delete them (in reverse order). In addition, you can delete any flag by clickingon it with the Ctrl key held down. } toolbar 'Manual Count' ; const btn_Text = -1 ; TypeA = 'A' ; TypeB = 'B' ; var CellImage ; // selected image SType ; // selected cell type Inherit ; // set true to inherit existing flags AFlags ; // flagged positions for type A cells BFlags ; // flagged positions for type B cells procedure PrepareCount ; { Prepare for counting a new image } begin Free( AFlags ) ; Free( BFlags ) ; Inherit := true ; if IsImage( CellImage ) then WriteStatus( 'Selected "',GetName( CellImage ),'"' ) ; end; procedure SelectImageFromList ; button btn_CameraQuery,'Select an image' ; { Select an image from a list } begin if SelectImage( 'Select an image from the list',CellImage ) = id_Ok then PrepareCount ; end; procedure SelectActiveImage ; button 132,'Select the active image' ; { Select the active image } begin GetActiveImage( CellImage ) ; PrepareCount ; end; procedure ProcessExistingFlags( var CFlags ) ; { Determine whether to remove existing flags from the image } var XFlags ; begin if IsImage( CellImage ) then begin { check for existing flags } XFlags := GetFlags( CellImage ) ; { delete inherited flags? } if Inherit then begin if IsArray( XFlags ) then if Query( 'Do you want to delete the existing flags?' ) = id_Yes then begin DeleteFlags( CellImage ) ; Inherit := false ; end; end else begin { check for uncounted changes } if GetYSize( XFlags ) <> GetYSize( CFlags ) then if Query( 'The number of flags has changed. Do you want to update the count for type ',SType,'?' ) = id_Yes then CFlags := XFlags ; { clear the flags } DeleteFlags( CellImage ) ; end; end; end; procedure ShowCounted( Coords ) ; { Draw a flag at each counted position } var j ; begin if IsArray( Coords ) and IsImage( CellImage ) then for j := 0 to GetYMax( Coords ) do SetFlag( CellImage,Coords[0,j],Coords[1,j] ) ; end; procedure SelectTypeA ; button btn_A,'-Select cell type A' ; { Display and count cells of type A } begin if SType <> TypeA then begin ProcessExistingFlags( BFlags ) ; ShowCounted( AFlags ) ; Inherit := false ; WriteStatus( 'Selected type A' ) ; SType := TypeA ; end; end; procedure SelectTypeB ; button btn_B,'Select cell type B' ; { Display and count cells of type B } begin if SType <> TypeB then begin ProcessExistingFlags( AFlags ) ; ShowCounted( BFlags ) ; Inherit := false ; WriteStatus( 'Selected type B' ) ; SType := TypeB ; end; end; procedure CountCells ; button 96,'-Count flagged cells' ; var XFlags ; begin { ensure image is selected } if IsNull( CellImage ) then SelectImageFromList ; { process image } if IsImage( CellImage ) then begin { retrieve flags } XFlags := GetFlags( CellImage ) ; { process new count } if not IsNull( XFlags ) then begin { store flag positions } if SType = TypeA then AFlags := XFlags else BFlags := XFlags ; { info } WriteInfo( 'Type ',SType,chr(13),GetYSize( XFlags ),' cells counted' ) ; Inherit := false ; end else WriteError( 'Put flags on the cells you wish to count' ) ; end; end; procedure ShowCounts ; button btn_Text,'Totals|Show current totals' ; begin WriteInfo( 'Type A: ',GetYSize( AFlags ),' cells counted',chr(13),chr(13), 'Type B: ',GetYSize( BFlags ),' cells counted' ) ; end; procedure ClearCurrentCount ; button 17,'-Clear current cell count' ; { Clear the count for the currently selected cell type } begin { clear flags } if IsImage( CellImage ) then DeleteFlags( CellImage ) ; { cleared stored positions } if SType = TypeA then Free( AFlags ) else Free( BFlags ) ; end; procedure Reset ; button btn_TrashEmpty,'Reset' ; { Clear everything and start again } begin if IsImage( CellImage ) then DeleteFlags( CellImage ) ; Free( CellImage ) ; Free( AFlags ) ; Free( BFlags ) ; SType := TypeA ; Inherit := true ; end; begin Reset ; end.