You are here: Start » Program Examples » Chocolate Cookies Inspection 3D
Chocolate Cookies Inspection 3D
Aim
The task of this example is to segment cookies, count them and measure their dimensions.
Input
Surfaces of cookies grabbed by a 3D Scan Sensor.
Output
Image of segmented cookies, number of cookies, dimensions and completeness verification.
Hints
Having acquired surfaces, try to find a filter which would enable you to convert them into images. Then you could use Region Analysis to perform segmentation. After extracting blobs representing cookies it is possible to count them and measure their dimensions with MeasureObjectWidth3D.
Solution (FIS)
-
Load surfaces into your program. You can do this by creating a separate step macrofilter (e.g. you can call it "AcquireSurface"). Add EnumerateFiles and LoadObject filters. In the first filter set the proper directory to the surfaces. Connect outFilePath to inFile and outObject to macrofilter outputs. Name the output outSurface.
-
Go back to Main and add CropSurface. Connect the output outSurface to inSurface. Click on the filter and in Properties window in the bottom left corner and set the values inMinZ and inMaxZ to 12 and 23 respectively. Set inPreserveDimensions to True.
-
Add the CreateImageFromSurface filter. Connect outSurface to inSurface. Click on the filter and in the Properties window set inPixelOffset to 0.
-
Now create a new step macrofilter which you can name e.g. "SegmentAndCountCookies". Connect outImage and outSurface to macrofilter inputs. Inside of the macrofilter, add ExtractBlobs_Intensity.
-
Connect macrofilter input inImage to inImage. Click on the filter and set these values in the Properties window:
- inThresholdParams.MinIntensity to 1 to remove small noise,
- inBlobSplittingParams.MinArea to 200000 so that only blobs of area no lower than that are taken into account,
- inBlobSplittingParams.MaxArea to 900000 so that only blobs of area no greater than that are taken into account.
-
Next, add the ClassifyRegions filter. Connect outBlobs to inRegions. Click on the filter and in the Properties window set following parameters:
-
Add RegionUnion_OfArray. Connect outAccepted to inArray.
-
Add the CropSurfaceToRegion filter. Connect macrofilter input inSurface to inSurface and outRegion to inRegion. Click on the filter and in the Properties window set inPreserveDimensions to True.
-
Add an empty Formula and perform following operations:
- Add a new macrofilter input representing the number of cookies you are expecting to get (e.g. "inExpectedNumberOfCookies" of Integer type) and set its default value to 12. Connect it to the newly-created formula,
- Right-click on the outAccepted output, select Property Outputs and choose the Count property. Connect it to the formula as inNumberOfCookies input,
-
Create a new output in the formula outIsCountOK like this:
outIsCountOK = inExpectedNumberOfCookies == inNumberOfCookies
-
Connect the outIsCountOK output to the macrofilter outputs.
-
Go back to Main and create another step macrofilter (e.g. "FindSurfaceMinimalPoint"). Connect outSurface from the SegmentAndCountCookies macrofilter to the newly-created macrofilter as an input.
-
Connect outBlobs from the SegmentAndCountCookies macrofilter as an array connection. It will cause the macrofilter to execute in an array mode (see also: Arrays in FabImage Studio).
-
Inside the macrofilter add FillRegionHoles. Connect the macrofilter input inRegion to inRegion.
-
Add ErodeRegion. Connect outRegion from the previous filter to inRegion of the current one. Set inRadiusX to 30 to remove noise on edges.
-
Add the SurfaceMinimalPoint filter and connect the macrofilter input inSurface to inSurface and outRegion to inRoi. Drag the outMinimalPoint output to the macrofilter outputs.
-
Go back to Main and create a new step macrofilter to create local coordinate systems for each cookie (you may call it e.g. "CreateLocalCoordinateSystem3D"). Connect outSurface and outBlobs from the SegmentAndCountCookies macrofilter to it as new inputs: inSurfaceFormat and inRegion (as an array connection) respectively. The macrofilter will be executed in the array mode as well as the FindSurfaceMinimalPoint macrofilter.
-
Inside the macrofilter, add RegionBoundingBox_OrNil. Connect macrofilter input inRegion to inRegion.
-
Add the CreateCoordinateSystemFromRectangle filter. Connect outBoundingRectangle to inRectangle.
-
Next, add ConvertCoordinateSystem2DTo3D. Connect outCoordinateSystem to inCoordinateSystem. Then, connect macrofilter input inSurfaceFormat to inSurfaceFormat.
-
Drag the outCoordinateSystem output to the macrofilter outputs.
-
Go back to Main. Create another step macrofilter (e.g. "MeasureObjectDimensions"). Connect outSurface from the SegmentAndCountCookies macrofilter and outCoordinateSystem from the previous macrofilter to inputs of the current one as inSurface and inScanFieldAlignment respectively.
-
Inside of the macrofilter, add two MeasureObjectWidth3D filters and connect macrofilter inputs inSurface and inScanFieldAlignment to inSurface and inScanFieldAlignment in both filters.
-
Now click on the first filter and make following changes in the Properties window:
- Click on inScanField and mark the scanning path to compute the height of the cookie,
- Set inScanCount to 10 to increase the number of scans to be performed,
- Set inScanWidth to 10 to increase the width of scanning field,
- Set inStripeScanParams.StripePolarity to Valid - to detect only actual points of the surface representing cookie,
- Set inMaxProfileGapWidth to 10 which will be the maximal allowed value of profile gap.
-
Click on the other MeasureObjectWidth3D filter and make following changes in the Properties window:
- Click on inScanField and mark the scanning path to compute the width of the cookie,
- Set inScanCount to 10 to increase the number of scans to be performed,
- Set inScanWidth to 10 to increase the width of scanning field,
- Set inStripeScanParams.StripePolarity to Valid - to detect only actual points of the surface representing cookie,
- Set inMaxProfileGapWidth to 400 which will be the maximal allowed value of profile gap,
- Set inOutlierSuppression to Tukey which will be a best method to ignore incorrectly detected points in this case.
-
Connect both outObjectWidth outputs to the macrofilter outputs as outVerticalDimension and outHorizontalDimension respectively.
-
Add an empty Formula and connect to it:
- Outputs from the previous macrofilter,
- outMinimalPoint.Z (first, you need to right-click on the outMinimalPoint, select Property Outputs and choose "Z")
-
Add following inputs in the formula:
- inMinVerticalDimension with a default value 7,
- inMinHorizontalValue with a default value 39,
- inMinHeight with a default value 17.
-
Create following outputs in the formula:
outIsVerticalDimensionOK = inVerticalDimension > inMinVerticalDimension
outIsHorizontalDimensionOK = inHorizontalDimension > inMinHorizontalDimension
outIsHeightOK = inSurfaceMinimalPoint > inMinHeight
outInspectionResult = outIsVerticalDimensionOK and outIsHorizontalDimensionOK and outIsHeightOK
Used Filters
Icon | Name | Description |
---|---|---|
![]() |
ConvertCoordinateSystem2DTo3D | Converts a coordinate system connected with the surface image to a coordinate system connected with the surface. |
![]() |
ClassifyRegions | Use this filter when to you have an array of regions and you want to select some of them for further processing. |
![]() |
CropSurfaceToRegion | Removes points that are not present in a given region. |
![]() |
CreateImageFromSurface | Allows for creating depth image from an ordered cloud of points. |
![]() |
CreateCoordinateSystemFromRectangle | Most often used to define an object alignment from a filter like RegionBoundingRectangle. |
![]() |
SurfaceMinimalPoint | Finds the surface point with minimal Z coordinate. |
![]() |
FillRegionHoles | Extends the input region so that it contains also all the pixels previously lying in its holes. |
![]() |
MeasureObjectWidth3D | Measures the width of an object using stripe detection. |
![]() |
RegionUnion_OfArray | Computes a region containing all the pixels that any of the input regions contains. |
![]() |
ErodeRegion | Making the region thinner or removing small parts. |
![]() |
LoadObject | Loads an object from a file. |
![]() |
CropSurface | Removes from the surface points that are not contained in a given rectangular box. |
![]() |
RegionBoundingRectangle_OrNil | Computes the smallest rectangle containing a region; returns NIL if the region is empty. |
![]() |
EnumerateFiles | Enumerates the files present in a disk directory. |
![]() |
ExtractBlobs_Intensity | Segments an image into blobs by thresholding. |
Further Readings
- Blob Analysis - Article presents detailed information about the Blob Analysis technique.
- Formulas - Detailed information about using formulas.
- Geometry 3D - List of filters useful in 3D geometry.
- Surface - Filters performing operations on surfaces in FabImage Studio.