Sorting, Classifying and Choosing Objects
Sorting, classifying and choosing objects are three types of general programming tasks that are often an important part of machine vision inspections. For example, it might be asked how to sort detected objects by the Y coordinate, how to decide which objects are correct on the basis of a computed feature, or how to select the region having the highest area. In Adaptive Vision Studio, by design, there are no filters that do just that. Instead, for maximum flexibility such tasks are divided into two steps:
- Firstly, an array of values (features) describing the objects of interest has to be created.
- Secondly, both the array of objects, and the array of the corresponding values, have to be passed to an appropriate sorting, classifying or choosing filter.
This approach makes it possible to use arbitrary criteria, also ones that are very specific to a particular project and have not been anticipated by the original creators of the software.
Sorting Elements of an Array
Let us consider the question of how to sort an array of objects by one of the coordinates or by some other computed feature. We will show how to achieve this on an example with manual sorting of characters from left to right for an OCR. Here is the input image with an overlay of the detected character regions:
After passing this array of character regions to the RecognizeCharacters filter with the inCharacterSorting input set to None, we will get the result "MAEPXEL", which has all characters recognized correctly, but in a random order.
Here is a sample program fragment that sorts the input regions by the X coordinates of their mass centers:
The final result is "EXAMPLE", which is both correct and in order.
Classifying Elements of an Array
An example of object classification has already been shown in the very first program example, in the First Program: Simple Blob Analysis article, where blobs were classified by the elongation feature with a dedicated filter, ClassifyRegions. Classification is a common step in many programs that process multiple objects and there is a group Classify of general filters which can classify objects by various criteria. The general scheme of object classification is:
- Detect objects – for example using Template Matching or segmentation (e.g. ThresholdToRegion + SplitRegionIntoBlobs).
- Compute some features – for example the area, elongation, mean brightness etc.
- Classify the objects – using one of the Classify filters.
The general idea of how to use the ClassifyByRange filter is shown below:
There are four elements:
- The objects to be classified are connected to the inArray input.
- The values corresponding to the objects are connected to the inValues input.
- The inMinimum and inMaximum inputs define the acceptable ranges for the values.
- The 3 outputs contain 3 arrays – containing the objects whose values were respectively: in the range, below the range and above the range.
Other filters that can be used for classification are: ClassifyByPredicate – when instead of associated real values we have associated booleans (True / False) and ClassifyByCase – when instead of associated real values we have associated indices of classes that the corresponding objects belong to.
Choosing an Element out of an Array
Choosing differs from sorting and classification mainly in that it is intended to produce a single value instead of an array. Let us consider the example of finding the orientation of a meter's needle:
There are two segments (blue) detected with the ScanExactlyNStripes filter along a circle (red). At this stage we have an array of two segments, but we do not know, which is the smaller and which is the bigger. This information is necessary to determine the orientation (green).
To solve this problem we need to compute an array of the segment's lengths using the SegmentLength filter and then get the appropriate elements with the GetSortedElements filter. This filter will produce the smaller element on the first output and the bigger element on the second output (see the picture below). Alternatively, we could use two separate filters: GetMinimumElement and GetMaximumElement.
Choosing one Object out of Several Individual Objects
Sometimes we have several individual objects to choose from instead of an array. For example we might want to choose one of two images for display in the HMI depending on whether some check-box is checked or not. In such case it is advisable to use the ChooseByPredicate filter, which requires two objects on the inputs and returns one of them on the output. Which one is chosen is determined by the inCondition input.
Warning: For efficiency reasons you should use the ChooseByPredicate filter only if the two input objects can be obtained without lengthy computations. If there are two alternative ways to compute a single value, then variant macrofilters should be used instead.
The ChooseByPredicate filter is very similar to the ternary (?:) operator from the C/C++ programming language.
Choosing an Object out of the Loop
Yet another case is choosing an object out of objects that appear in different iterations. As with arrays, also here we need an associated criterion, which can be real numbers, boolean values or status of a conditional value. The available filters are:
- LoopMaximum – chooses the object whose associated value was the highest.
- LoopMinimum – chooses the object whose associated value was the lowest.
- LastMarkedObject – chooses the most recent object whose associated boolean value was True.
- LastNotNil – chooses the most recent object which actually existed (was different than Nil).
|Previous: Recording Images||Next: Optimizing Image Analysis for Speed|