Click here to show toolbars of the Web Online Help System: show toolbars |
//****************************************************************************** // // File name: Mblob.cs // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: This program loads an image of some nuts, bolts and washers, // determines the number of each of these, finds and marks // their center of gravity using the Blob analysis module. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved //****************************************************************************** using System; using System.Collections.Generic; using System.Text; using Matrox.MatroxImagingLibrary; namespace MBlob { class Program { // Target MIL image file specifications. private const string IMAGE_FILE = MIL.M_IMAGE_PATH + "BoltsNutsWashers.mim"; private const int IMAGE_THRESHOLD_VALUE = 26; // Minimum and maximum area of blobs. private const int MIN_BLOB_AREA = 50; private const int MAX_BLOB_AREA = 50000; // Radius of the smallest particles to keep. private const int MIN_BLOB_RADIUS = 3; // Minimum hole compactness corresponding to a washer. private const double MIN_COMPACTNESS = 1.5; static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilGraphicList = MIL.M_NULL; // Graphic list identifier. MIL_ID MilBinImage = MIL.M_NULL; // Binary image buffer identifier. MIL_ID MilBlobResult = MIL.M_NULL; // Blob result buffer identifier. MIL_ID MilBlobContext = MIL.M_NULL; // Blob Context identifier. MIL_INT TotalBlobs = 0; // Total number of blobs. MIL_INT BlobsWithHoles = 0; // Number of blobs with holes. MIL_INT BlobsWithRoughHoles = 0; // Number of blobs with rough holes. MIL_INT n = 0; // Counter. MIL_INT SizeX = 0; // Size X of the source buffer MIL_INT SizeY = 0; // Size Y of the source buffer double[] CogX = null; // X coordinate of center of gravity. double[] CogY = null; // Y coordinate of center of gravity. // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Restore source image into image buffer. MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilImage); // Allocate a graphic list to hold the subpixel annotations to draw. MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref MilGraphicList); // Associate the graphic list to the display. MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphicList); // Display the buffer. MIL.MdispSelect(MilDisplay, MilImage); // Allocate a binary image buffer for fast processing. MIL.MbufInquire(MilImage, MIL.M_SIZE_X, ref SizeX); MIL.MbufInquire(MilImage, MIL.M_SIZE_Y, ref SizeY); MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilBinImage); // Pause to show the original image. Console.Write("\nBLOB ANALYSIS:\n"); Console.Write("--------------\n\n"); Console.Write("This program determines the number of bolts, nuts and washers\n"); Console.Write("in the image and finds their center of gravity.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Binarize image. MIL.MimBinarize(MilImage, MilBinImage, MIL.M_FIXED + MIL.M_GREATER_OR_EQUAL, IMAGE_THRESHOLD_VALUE, MIL.M_NULL); // Remove small particles and then remove small holes. MIL.MimOpen(MilBinImage, MilBinImage, MIN_BLOB_RADIUS, MIL.M_BINARY); MIL.MimClose(MilBinImage, MilBinImage, MIN_BLOB_RADIUS, MIL.M_BINARY); // Allocate a context. MIL.MblobAlloc(MilSystem, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilBlobContext); // Enable the Center Of Gravity feature calculation. MIL.MblobControl(MilBlobContext, MIL.M_CENTER_OF_GRAVITY + MIL.M_BINARY, MIL.M_ENABLE); // Allocate a blob result buffer. MIL.MblobAllocResult(MilSystem, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilBlobResult); // Calculate selected features for each blob. MIL.MblobCalculate(MilBlobContext, MilBinImage, MIL.M_NULL, MilBlobResult); // Exclude blobs whose area is too small. MIL.MblobSelect(MilBlobResult, MIL.M_EXCLUDE, MIL.M_AREA, MIL.M_LESS_OR_EQUAL, MIN_BLOB_AREA, MIL.M_NULL); // Get the total number of selected blobs. MIL.MblobGetResult(MilBlobResult, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref TotalBlobs); Console.Write("There are {0} objects ", TotalBlobs); // Read and print the blob's center of gravity. CogX = new double[TotalBlobs]; CogY = new double[TotalBlobs]; if (CogX != null && CogY != null) { // Get the results. MIL.MblobGetResult(MilBlobResult, MIL.M_DEFAULT, MIL.M_CENTER_OF_GRAVITY_X + MIL.M_BINARY, CogX); MIL.MblobGetResult(MilBlobResult, MIL.M_DEFAULT, MIL.M_CENTER_OF_GRAVITY_Y + MIL.M_BINARY, CogY); // Print the center of gravity of each blob. Console.Write("and their centers of gravity are:\n"); for (n = 0; n < TotalBlobs; n++) { Console.Write("Blob #{0}: X={1,5:0.0}, Y={2,5:0.0}\n", n, CogX[n], CogY[n]); } } else { Console.Write("\nError: Not enough memory.\n"); } // Draw a cross at the center of gravity of each blob. MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_RED); MIL.MblobDraw(MIL.M_DEFAULT, MilBlobResult, MilGraphicList, MIL.M_DRAW_CENTER_OF_GRAVITY, MIL.M_INCLUDED_BLOBS, MIL.M_DEFAULT); // Reverse what is considered to be the background so that // holes are seen as being blobs. MIL.MblobControl(MilBlobContext, MIL.M_FOREGROUND_VALUE, MIL.M_ZERO); // Add a feature to distinguish between types of holes.Since area // has already been added to the context, and the processing // mode has been changed, all blobs will be re-included and the area // of holes will be calculated automatically. MIL.MblobControl(MilBlobContext, MIL.M_COMPACTNESS, MIL.M_ENABLE); // Calculate selected features for each blob. MIL.MblobCalculate(MilBlobContext, MilBinImage, MIL.M_NULL, MilBlobResult); // Exclude small holes and large (the area around objects) holes. MIL.MblobSelect(MilBlobResult, MIL.M_EXCLUDE, MIL.M_AREA, MIL.M_OUT_RANGE, MIN_BLOB_AREA, MAX_BLOB_AREA); // Get the number of blobs with holes. MIL.MblobGetResult(MilBlobResult, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref BlobsWithHoles); // Exclude blobs whose holes are compact (i.e.nuts). MIL.MblobSelect(MilBlobResult, MIL.M_EXCLUDE, MIL.M_COMPACTNESS, MIL.M_LESS_OR_EQUAL, MIN_COMPACTNESS, MIL.M_NULL); // Get the number of blobs with holes that are NOT compact. MIL.MblobGetResult(MilBlobResult, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref BlobsWithRoughHoles); // Print results. Console.Write("\nIdentified objects:\n"); Console.Write("{0} bolts\n", TotalBlobs - BlobsWithHoles); Console.Write("{0} nuts\n", BlobsWithHoles - BlobsWithRoughHoles); Console.Write("{0} washers\n\n", BlobsWithRoughHoles); Console.Write("Press <Enter> to end.\n\n"); Console.ReadKey(); // Free all allocations. MIL.MgraFree(MilGraphicList); MIL.MblobFree(MilBlobResult); MIL.MblobFree(MilBlobContext); MIL.MbufFree(MilBinImage); MIL.MbufFree(MilImage); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); } } }