You are here: Start » Tutorial Exercises » Counting Saw Teeth (count_teeth)

Counting Saw Teeth (count_teeth)

Aim

Create an application that finds the number of blade's teeth.

Input

A single image of the saw blade.

Image is stored in count_teeth directory.

Output

A number of teeth.

Hints

Teeth of blade are located evenly around the mounting hole of the blade.

Locate central mounting point using DetectSingleCircle. Measure a blade radius using the measuring distance tool.

Blade teeth can be measured like stripes using ScanMultipleStripes.

Create circular path for scanning path using CreateCirclePath filter. This filter converts geometrical shape to the set of straight segments. It is necessary to select value of inPointCount that will make possible of scanning each tooth.

Solution (AVS)

  1. Add filter LoadImage to get image from the file.

  2. Measure the diameter of the mounting hole using the measuring tool.

  3. Add DetectSingleCircle filter and set the value of expected circle radius with the measured radius.

  4. Reduce a DetectSingleCircle ROI to the middle part of an image to increase a detection speed.

  5. Resize the hole radius to a value that will create a new circle that will cross all teeth. Measure the diameter of saw blade using the measuring tool. Use ResizeCircle filter with the measured value.

  6. Convert the newly created circle to a circular path. Using CreateCirclePath filter and set the value of inPointCount to 50.

  7. Add ScanMultipleStripes filter to find stripes crossing the prepared path. Set inStripeScanParams.StripePolarity to Dark.

  8. Expand outStripes of ScanMultipleStripes filter and get Count value.

  9. Show outStripes.Count in a new preview window.

Main macrofilter calculates the teeth count by scanning stripes around a circular path.

Solution (C++)

▼Click here to hide C++ solution.

Created single function that finds the count of teeth.

void CalculateTeeth(const Image& inputImage)
{
    // Create ROI to reduce circle detection time.
    Region detectingRoi;
    CreateRectangleRegion(roiRectangle, NIL, NIL, detectingRoi);

    // Find circle on input image in narrowed ROI
    atl::Conditional<HoughCircle> circle;
    DetectSingleCircle (inputImage,
                        detectingRoi, 
                        22.0f,               // Radius
                        20.0f,               // Minimal score
                        10.0f,               // Minimal edge magnitude threshold
                        circle);

    if (circle != atl::NIL)
    {
        Circle2D scanCircle = circle.Get().Circle;
        scanCircle.r = 125.0f;

        Path scanningPath;
        CreateCircularPath(scanCircle, 50, scanningPath);

        ScanMap scanMap;
        CreateScanMap(inputImage, scanningPath, NIL, 5, 
                      avl::InterpolationMethod::Bilinear, scanMap);

        StripeScanParams stripeParams;
        stripeParams.inStripePolarity = Polarity::Dark;

        atl::Array<Stripe1D> stripes;
        ScanMultipleStripes(inputImage, scanMap, stripeParams, 0, NIL, stripes, 
                            dummy(Array<real>), dummy(Array<real>));

        ShowPreview(inputImage, circle.Get().Circle, stripes, stripes.Size());
    }

    std::cout << "Mounting circle was not found." << std::endl;
}

Additional Tasks

  • Unroll the image along the circular path into a single straight image using ImageAlongPath.
  • Find the mounting using the Blob Analysis techniques.