// Main function: // -------------- static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilRemoteApplication = MIL.M_NULL; // Remote Application identifier if running on a remote computer MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifiers. MIL_ID MilOrgImage = MIL.M_NULL; THREAD_PARAM TParTopLeft = new THREAD_PARAM(); // Parameters passed to top left thread. THREAD_PARAM TParBotLeft = new THREAD_PARAM(); // Parameters passed to bottom left thread. THREAD_PARAM TParTopRight = new THREAD_PARAM(); // Parameters passed to top right thread. THREAD_PARAM TParBotRight = new THREAD_PARAM(); // Parameters passed to bottom right thread. double Time = 0.0; // Timer variables. double FramesPerSecond = 0.0; MIL_INT LicenseModules = 0; // List of available MIL modules. // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Allocate and display the main image buffer. MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilImage); MIL.MbufClear(MilImage, 0); MIL.MdispSelect(MilDisplay, MilImage); // Allocate an image buffer to keep the original. MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilOrgImage); // Allocate a destination child buffer for each thread. MIL.MbufChild2d(MilImage, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParTopLeft.SrcImage); MIL.MbufChild2d(MilImage, 0, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParBotLeft.DstImage); MIL.MbufChild2d(MilImage, IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParTopRight.SrcImage); MIL.MbufChild2d(MilImage, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParBotRight.DstImage); // Allocate synchronization events. MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopLeft.DoneEvent); MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotLeft.DoneEvent); MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopRight.DoneEvent); MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotRight.DoneEvent); // Inquire MIL licenses. MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); // Initialize remaining thread parameters. TParTopLeft.System = MilSystem; TParTopLeft.OrgImage = MilOrgImage; TParTopLeft.DstImage = TParTopLeft.SrcImage; TParTopLeft.ReadyEvent = TParBotLeft.DoneEvent; TParTopLeft.NumberOfIteration = 0; TParTopLeft.Radius = 0; TParTopLeft.Exit = 0; TParTopLeft.LicenseModules = LicenseModules; TParTopLeft.SlaveThreadParam = TParBotLeft; TParBotLeft.System = MilSystem; TParBotLeft.OrgImage = 0; TParBotLeft.SrcImage = TParTopLeft.DstImage; TParBotLeft.ReadyEvent = TParTopLeft.DoneEvent; TParBotLeft.NumberOfIteration = 0; TParBotLeft.Radius = 0; TParBotLeft.Exit = 0; TParBotLeft.LicenseModules = LicenseModules; TParBotLeft.SlaveThreadParam = null; TParTopRight.System = MilSystem; TParTopRight.OrgImage = MilOrgImage; TParTopRight.DstImage = TParTopRight.SrcImage; TParTopRight.ReadyEvent = TParBotRight.DoneEvent; TParTopRight.NumberOfIteration = 0; TParTopRight.Radius = 0; TParTopRight.Exit = 0; TParTopRight.LicenseModules = LicenseModules; TParTopRight.SlaveThreadParam = TParBotRight; TParBotRight.System = MilSystem; TParBotRight.OrgImage = 0; TParBotRight.SrcImage = TParTopRight.DstImage; TParBotRight.ReadyEvent = TParTopRight.DoneEvent; TParBotRight.NumberOfIteration = 0; TParBotRight.Radius = 0; TParBotRight.Exit = 0; TParBotRight.LicenseModules = LicenseModules; TParBotRight.SlaveThreadParam = null; // Initialize the original image to process. MIL.MbufLoad(IMAGE_FILE, MilOrgImage); // Start the 4 threads. MIL_THREAD_FUNCTION_PTR TopThreadDelegate = new MIL_THREAD_FUNCTION_PTR(TopThread); MIL_THREAD_FUNCTION_PTR BotLeftThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotLeftThread); MIL_THREAD_FUNCTION_PTR BotRightThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotRightThread); GCHandle TParTopLeftHandle = GCHandle.Alloc(TParTopLeft); GCHandle TParBotLeftHandle = GCHandle.Alloc(TParBotLeft); GCHandle TParTopRightHandle = GCHandle.Alloc(TParTopRight); GCHandle TParBotRightHandle = GCHandle.Alloc(TParBotRight); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopLeftHandle), ref TParTopLeft.Id); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotLeftThreadDelegate, GCHandle.ToIntPtr(TParBotLeftHandle), ref TParBotLeft.Id); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopRightHandle), ref TParTopRight.Id); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotRightThreadDelegate, GCHandle.ToIntPtr(TParBotRightHandle), ref TParBotRight.Id); // Start the timer. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Set events to start operation of top left and top right threads. MIL.MthrControl(TParTopLeft.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED); MIL.MthrControl(TParTopRight.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED); // Report that the threads are started and wait for a key press to stop them. Console.Write("\nMULTI-THREADING:\n"); Console.Write("----------------\n\n"); Console.Write("4 threads running...\n"); Console.Write("Press <Enter> to stop.\n\n"); Console.ReadKey(); // Signal the threads to exit. TParTopLeft.Exit = 1; TParTopRight.Exit = 1; // Wait for all threads to terminate. MIL.MthrWait(TParTopLeft.Id, MIL.M_THREAD_END_WAIT); MIL.MthrWait(TParBotLeft.Id, MIL.M_THREAD_END_WAIT); MIL.MthrWait(TParTopRight.Id, MIL.M_THREAD_END_WAIT); MIL.MthrWait(TParBotRight.Id, MIL.M_THREAD_END_WAIT); // Stop the timer and calculate the number of frames per second processed. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); FramesPerSecond = (TParTopLeft.NumberOfIteration + TParBotLeft.NumberOfIteration + TParTopRight.NumberOfIteration + TParBotRight.NumberOfIteration) / Time; // Print statistics. Console.Write("Top left iterations done: {0,4}.\n", TParTopLeft.NumberOfIteration); Console.Write("Bottom left iterations done: {0,4}.\n", TParBotLeft.NumberOfIteration); Console.Write("Top right iterations done: {0,4}.\n", TParTopRight.NumberOfIteration); Console.Write("Bottom right iterations done: {0,4}.\n\n", TParBotRight.NumberOfIteration); Console.Write("Processing speed for the 4 threads: {0:0.0} Images/Sec.\n\n", FramesPerSecond); Console.Write("Press <Enter> to end.\n\n"); Console.ReadKey(); // Free threads. MIL.MthrFree(TParTopLeft.Id); MIL.MthrFree(TParBotLeft.Id); MIL.MthrFree(TParTopRight.Id); MIL.MthrFree(TParBotRight.Id); // Free events. MIL.MthrFree(TParTopLeft.DoneEvent); MIL.MthrFree(TParBotLeft.DoneEvent); MIL.MthrFree(TParTopRight.DoneEvent); MIL.MthrFree(TParBotRight.DoneEvent); // Free buffers. MIL.MbufFree(TParTopLeft.SrcImage); MIL.MbufFree(TParTopRight.SrcImage); MIL.MbufFree(TParBotLeft.DstImage); MIL.MbufFree(TParBotRight.DstImage); MIL.MbufFree(MilOrgImage); MIL.MbufFree(MilImage); // Free the GCHandles TParTopLeftHandle.Free(); TParBotLeftHandle.Free(); TParTopRightHandle.Free(); TParBotRightHandle.Free(); // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }
static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilRemoteApplication = MIL.M_NULL; // Remote Application identifier if running on a remote computer 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 MilExtremeResult = 0; // Extreme result buffer identifier. int MaxLabelNumber = 0; // Highest label value. MIL_INT LicenseModules = 0; // List of available MIL modules. // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Restore source image and display it. MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilImage); MIL.MdispSelect(MilDisplay, MilImage); // Pause to show the original image. Console.Write("\nIMAGE PROCESSING:\n"); Console.Write("-----------------\n\n"); Console.Write("This program extracts the dark particles in the image.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Binarize the image with an automatically calculated threshold so that // particles are represented in white and the background removed. MIL.MimBinarize(MilImage, MilImage, MIL.M_BIMODAL + MIL.M_LESS_OR_EQUAL, MIL.M_NULL, MIL.M_NULL); // Print a message for the extracted particles. Console.Write("These particles were extracted from the original image.\n"); // If MIL IM module is available, count and label the larger particles. MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); if ((LicenseModules & MIL.M_LICENSE_IM) != 0) { // Pause to show the extracted particles. Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Close small holes. MIL.MimClose(MilImage, MilImage, IMAGE_SMALL_PARTICLE_RADIUS, MIL.M_BINARY); // Remove small particles. MIL.MimOpen(MilImage, MilImage, IMAGE_SMALL_PARTICLE_RADIUS, MIL.M_BINARY); // Label the image. MIL.MimLabel(MilImage, MilImage, MIL.M_DEFAULT); // The largest label value corresponds to the number of particles in the image. MIL.MimAllocResult(MilSystem, 1, MIL.M_EXTREME_LIST, ref MilExtremeResult); MIL.MimFindExtreme(MilImage, MilExtremeResult, MIL.M_MAX_VALUE); MIL.MimGetResult(MilExtremeResult, MIL.M_VALUE, ref MaxLabelNumber); MIL.MimFree(MilExtremeResult); // Multiply the labeling result to augment the gray level of the particles. MIL.MimArith(MilImage, (int)(256 / (double)MaxLabelNumber), MilImage, MIL.M_MULT_CONST); // Display the resulting particles in pseudo-color. MIL.MdispLut(MilDisplay, MIL.M_PSEUDO); // Print results. Console.Write("There were {0} large particles in the original image.\n", MaxLabelNumber); } // Pause to show the result. Console.Write("Press <Enter> to end.\n\n"); Console.ReadKey(); // Free all allocations. MIL.MbufFree(MilImage); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }
// Main function. // -------------- static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilRemoteApplication = MIL.M_NULL; // Remote Application identifier if running on a remote computer MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID[] MilGrabImages = new MIL_ID[NB_GRAB_IMAGE_MAX]; MIL_ID MilCompressedImage = MIL.M_NULL; ConsoleKeyInfo Selection = new ConsoleKeyInfo('1', ConsoleKey.D1, false, false, false); int NbFrames = 0; int n = 0; int NbFramesReplayed = 0; double FrameRate = 0; double TimeWait = 0; double TotalReplay = 0; double GrabScale = GRAB_SCALE; HookDataObject UserHookData = new HookDataObject(); MIL_INT LicenseModules = 0; MIL_INT FrameCount = 0; MIL_INT FrameMissed = 0; MIL_INT CompressAttribute = 0; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, MIL.M_NULL); // Allocate an image and display it. MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (MIL_INT)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X) * GrabScale), (MIL_INT)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_DISP, ref MilImageDisp); MIL.MbufClear(MilImageDisp, 0x0); MIL.MdispSelect(MilDisplay, MilImageDisp); // Grab continuously on display at the specified scale. MIL.MdigControl(MilDigitizer, MIL.M_GRAB_SCALE, GrabScale); MIL.MdigGrabContinuous(MilDigitizer, MilImageDisp); // Print a message Console.WriteLine(); Console.WriteLine("SEQUENCE ACQUISITION:"); Console.WriteLine("--------------------"); Console.WriteLine(); // Inquire MIL licenses. MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); // If sequence is saved to disk, select between grabbing an // uncompressed, JPEG or JPEG2000 sequence. if (SAVE_SEQUENCE_TO_DISK && ((LicenseModules & (MIL.M_LICENSE_JPEGSTD | MIL.M_LICENSE_JPEG2000)) != 0)) { Console.WriteLine("Choose the sequence format:"); Console.WriteLine("1) Uncompressed images."); if ((LicenseModules & MIL.M_LICENSE_JPEGSTD) != 0) { Console.WriteLine("2) Compressed images with a lossy JPEG algorithm."); } if ((LicenseModules & MIL.M_LICENSE_JPEG2000) != 0) { Console.WriteLine("3) Compressed images with a lossy JPEG 2000 algorithm."); } Selection = Console.ReadKey(); } else { Console.WriteLine("Press <Enter> to record images."); Console.ReadKey(); } // Set the buffer attribute. switch (Selection.Key) { case ConsoleKey.NumPad1: case ConsoleKey.D1: case ConsoleKey.Enter: Console.WriteLine(); Console.WriteLine("Recording uncompressed images..."); Console.WriteLine(); CompressAttribute = MIL.M_NULL; break; case ConsoleKey.NumPad2: case ConsoleKey.D2: Console.WriteLine(); Console.WriteLine("Recording JPEG images..."); Console.WriteLine(); CompressAttribute = MIL.M_COMPRESS + MIL.M_JPEG_LOSSY; break; case ConsoleKey.NumPad3: case ConsoleKey.D3: Console.WriteLine(); Console.WriteLine("Recording JPEG 2000 images..."); Console.WriteLine(); CompressAttribute = MIL.M_COMPRESS + MIL.M_JPEG2000_LOSSY; break; default: Console.WriteLine(); Console.WriteLine("Invalid selection !."); Console.WriteLine(); Console.WriteLine("Using uncompressed images."); Console.WriteLine(); CompressAttribute = MIL.M_NULL; while (Console.KeyAvailable) { Console.ReadKey(); } break; } // Allocate a compressed buffer if required. if (CompressAttribute != MIL.M_NULL) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL) * GrabScale), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + CompressAttribute, ref MilCompressedImage); MIL.MbufControl(MilCompressedImage, MIL.M_Q_FACTOR, COMPRESSION_Q_FACTOR); } // Allocate the grab buffers to hold the sequence buffering. MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE); for (NbFrames = 0, n = 0; n < NB_GRAB_IMAGE_MAX; n++) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL) * GrabScale), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB, ref MilGrabImages[n]); if (MilGrabImages[n] != MIL.M_NULL) { NbFrames++; MIL.MbufClear(MilGrabImages[n], 0xFF); } else { break; } } MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE); // Free buffers to leave some space for possible temporary buffers. for (n = 0; n < 2 && NbFrames > 0; n++) { NbFrames--; MIL.MbufFree(MilGrabImages[NbFrames]); } // Halt continuous grab. MIL.MdigHalt(MilDigitizer); // Open the AVI file if required. if (SAVE_SEQUENCE_TO_DISK) { Console.WriteLine("Saving the sequence to an AVI file..."); Console.WriteLine(); MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_OPEN); } // Initialize User's archiving function hook data structure. UserHookData.MilSystem = MilSystem; UserHookData.MilDisplay = MilDisplay; UserHookData.MilImageDisp = MilImageDisp; UserHookData.MilCompressedImage = MilCompressedImage; UserHookData.SaveSequenceToDisk = SAVE_SEQUENCE_TO_DISK; UserHookData.NbGrabbedFrames = 0; UserHookData.NbArchivedFrames = 0; // get a handle to the DigHookUserData object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle UserHookDataHandle = GCHandle.Alloc(UserHookData); MIL_DIG_HOOK_FUNCTION_PTR UserHookFunctionDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(ArchiveFunction); // Acquire the sequence. The processing hook function will // be called for each image grabbed to archive and display it. // If sequence is not saved to disk, stop after NbFrames. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, SAVE_SEQUENCE_TO_DISK ? MIL.M_START : MIL.M_SEQUENCE, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Wait for a key press. Console.WriteLine("Press <Enter> to continue."); Console.WriteLine(); Console.ReadKey(true); // Stop the sequence acquisition. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, MIL.M_STOP, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Free the GCHandle when no longer used UserHookDataHandle.Free(); // Read and print final statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref FrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref FrameRate); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_MISSED, ref FrameMissed); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames archived ({1} missed), at {2:0.0} frames/sec ({3:0.0}ms/frame).", UserHookData.NbArchivedFrames, FrameMissed, FrameRate, 1000.0 / FrameRate); // Sequence file closing if required. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, FrameRate, MIL.M_CLOSE); } // Playback the sequence until a key is pressed. if (UserHookData.NbArchivedFrames > 0) { do { // If sequence must be loaded. if (SAVE_SEQUENCE_TO_DISK) { // Inquire information about the sequence. Console.WriteLine(); Console.WriteLine("Playing back sequence from the AVI file..."); Console.WriteLine(); Console.WriteLine("Press <Enter> to end."); Console.WriteLine(); Console.WriteLine(); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref FrameCount); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_COMPRESSION_TYPE, ref CompressAttribute); // Open the sequence file. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN); } // Copy the images to the screen respecting the sequence frame rate. TotalReplay = 0.0; NbFramesReplayed = 0; for (n = 0; n < FrameCount; n++) { // Reset the time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET, MIL.M_NULL); // If image was saved to disk. if (SAVE_SEQUENCE_TO_DISK) { // Load image directly to the display. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImageDisp, n, 1, MIL.M_READ); NbFramesReplayed++; Console.Write("Frame #{0} \r", NbFramesReplayed); } else { // Copy the grabbed image to the display. MIL.MbufCopy(MilGrabImages[n], MilImageDisp); NbFramesReplayed++; Console.Write("Frame #{0} \r", NbFramesReplayed); } // Check for a pressed key to exit. if (Console.KeyAvailable && (n >= (NB_GRAB_IMAGE_MAX - 1))) { Console.ReadKey(true); break; } // Wait to have a proper frame rate. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref TimeWait); TotalReplay += TimeWait; TimeWait = (1 / FrameRate) - TimeWait; MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_WAIT, ref TimeWait); TotalReplay += (TimeWait > 0) ? TimeWait : 0.0; } // Close the sequence file. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE); } // Print statistics. Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames replayed, at a frame rate of {1:0.0} frames/sec ({2:0.0} ms/frame).", NbFramesReplayed, n / TotalReplay, 1000.0 * TotalReplay / n); Console.WriteLine(); Console.WriteLine("Press <Enter> to end (or any other key to playback again)."); Console.WriteLine(); }while (Console.ReadKey(true).Key != ConsoleKey.Enter); } // Free all allocated buffers. MIL.MbufFree(MilImageDisp); for (n = 0; n < NbFrames; n++) { MIL.MbufFree(MilGrabImages[n]); } if (MilCompressedImage != MIL.M_NULL) { MIL.MbufFree(MilCompressedImage); } // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MIL.M_NULL); }
private void CameraOpen() { try { //mil app open MIL.MappAlloc(MIL.M_NULL, MIL.M_DEFAULT, ref _MilApplication); //mil throw 관리 MIL.MappControl(_MilApplication, MIL.M_ERROR, MIL.M_THROW_EXCEPTION); //설치된 보드 드라이버 수 가져오기 var insSysCount = MIL.MappInquire(MIL.M_INSTALLED_SYSTEM_COUNT); for (int i = 0; i < insSysCount; i++) { MIL_ID tmpSystem = MIL.M_NULL; StringBuilder sb = new StringBuilder(); //보드 종류 문자열로 뽑아내기 MIL.MappInquire(_MilApplication, MIL.M_INSTALLED_SYSTEM_DESCRIPTOR + i, sb); var boardCount = 0; //같은 종류의 보드 몇 개까지 존재하는지 확인 while (sb.ToString() != "M_SYSTEM_HOST") { MIL_ID systemId = MIL.M_NULL; try { //보드 alloc MIL.MsysAlloc(sb.ToString(), boardCount, MIL.M_DEFAULT, ref systemId); } catch { //해당 보드는 메인보드에서 인식되지 않음 (없음) break; } //alloc된 보드 추가 var cam = new MatroxCamera(); //Digitizer 몇개 존재하는지 확인 var digCount = MIL.MsysInquire(systemId, MIL.M_DIGITIZER_NUM); //임의의 dcf file 추가 (원하는 dcf로 변경) var dcfPath = AppDomain.CurrentDomain.BaseDirectory + @"\camfile.dcf"; //보드에 연결된 카메라 수만큼 돎 for (int ii = 0; ii < digCount; ii++) { MIL_ID digitId = MIL.M_NULL; //digitizer alloc MIL.MdigAlloc(systemId, ii, dcfPath, MIL.M_DEFAULT, ref digitId); cam.SystemID = systemId; cam.DigitizerID = digitId; } MatroxCameraList.Add(cam); boardCount++; } } } catch (Exception err) { MessageBox.Show(err.Message + "\n" + err.StackTrace); } }
// Main function. // // ---------------// static int Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilRemoteApplication = MIL.M_NULL; MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID[] MilGrabBufferList = new MIL_ID[BUFFERING_SIZE_MAX]; MIL_ID MilCompressContext = MIL.M_NULL; MIL_ID MilDecompressContext = MIL.M_NULL; MIL_INT LicenseModules = 0; MIL_INT MilSystemLocation = MIL.M_NULL; MIL_INT MilGrabBufferListSize; MIL_INT ProcessFrameCount = 0; MIL_INT NbFrames = 0; MIL_INT n = 0; double EncodingDesiredFrameRate = 0.0; double ProcessFrameRate = 0.0; MIL_INT SeqProcessFilePathSize = 0; StringBuilder SeqProcessFilePath = null; ProcessingHookDataStruct ProcessingUserHookData = new ProcessingHookDataStruct(); EncodingFrameEndHookDataStruct EncodingFrameEndUserHookData = new EncodingFrameEndHookDataStruct(); DecodingFrameEndHookDataStruct DecodingFrameEndUserHookData = new DecodingFrameEndHookDataStruct(); MIL_INT SeqSystemType = MIL.M_NULL; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, ref MilImageDisp); MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MilSystemLocation = MIL.MsysInquire(MilSystem, MIL.M_LOCATION, MIL.M_NULL); if (MIL.MappInquire(MilRemoteApplication, MIL.M_PLATFORM_OS_TYPE, MIL.M_NULL) != MIL.M_OS_WINDOWS) { if (MilSystemLocation == MIL.M_REMOTE) { Console.WriteLine("The Distributed MIL server must run on a Windows system."); } else { Console.WriteLine("This example only works with a Windows system."); } Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return(0); } // Inquire MIL licenses. MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); if ((LicenseModules & MIL.M_LICENSE_JPEGSTD) != MIL.M_LICENSE_JPEGSTD) { Console.WriteLine("Need a Compression/Decompression license to run this example."); Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return(0); } // Allocate the grab buffers and clear them. MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE); for (MilGrabBufferListSize = 0; MilGrabBufferListSize < BUFFERING_SIZE_MAX; MilGrabBufferListSize++) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilGrabBufferList[MilGrabBufferListSize]); if (MilGrabBufferList[MilGrabBufferListSize] != MIL.M_NULL) { MIL.MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF); } else { break; } } MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE); // Free buffers to leave space for possible temporary buffers. for (n = 0; n < 2 && MilGrabBufferListSize > 0; n++) { MilGrabBufferListSize--; MIL.MbufFree(MilGrabBufferList[MilGrabBufferListSize]); } if (MilGrabBufferListSize == 0) { Console.WriteLine("!!! No grab buffers have been allocated. Need to set more Non-Paged Memory. !!!"); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); return(1); } /* Initialize the User's processing function data structure only for Display. */ ProcessingUserHookData.MilDigitizer = MilDigitizer; ProcessingUserHookData.MilSeqContext = MIL.M_NULL; ProcessingUserHookData.MilImageDisp = MilImageDisp; ProcessingUserHookData.ProcessedImageCount = 0; ProcessingUserHookData.ProcessingOperation = ProcessingHookOperation.DISPLAY; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle hUserData = GCHandle.Alloc(ProcessingUserHookData); // Start the sequence acquisition. The preprocessing and encoding hook function // is called for every frame grabbed. MIL_DIG_HOOK_FUNCTION_PTR ProcessingFunctionDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(ProcessingFunction); /* Start a digProcess to show the live camera output. */ MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_START, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); /* Print a message. */ Console.Write("\nH.264 IMAGE SEQUENCE COMPRESSION.\n"); Console.Write("---------------------------------\n\n"); Console.Write("Press <Enter> to start compression.\r"); Console.ReadKey(); /* Stop digProcess. */ MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_STOP, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); /* Inquire the dig process frame rate */ MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref EncodingDesiredFrameRate); Console.Write("Grabbing frames at {0:0.00} frames/sec.\n", EncodingDesiredFrameRate); // Creates a context for the H.264 compression engine. Compression will be done // using hardware or software depending on the system hardware configuration. MIL.MseqAlloc(MilSystem, MIL.M_DEFAULT, MIL.M_SEQ_COMPRESS, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilCompressContext); // Specify the destination of the compressed file and the target container type. // The last argument specifies to generate an MP4 file. MIL.MseqDefine(MilCompressContext, MIL.M_SEQ_OUTPUT(0) + MIL.M_SEQ_DEST(0), MIL.M_FILE, (MilSystemLocation != MIL.M_REMOTE ? SEQUENCE_FILE : REMOTE_SEQUENCE_FILE), MIL.M_FILE_FORMAT_MP4); // Set the compression parameters. // Sets the compression parameters valid for any resolution under 1920X1080. // Any resolution higher than that will generate an warning that can be disabled using // MseqControl with M_SETTING_AUTO_ADJUSTMENT. See documentation for more details. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_BIT_RATE_MODE, MIL.M_VARIABLE); // MIL.M_VARIABLE or MIL.M_CONSTANT MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_BIT_RATE, 5000); // 5 Mbps bit rate MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_BIT_RATE_MAX, 5000); // 5 Mbps bit rate MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_FRAME_RATE, EncodingDesiredFrameRate); // 60Hz frame rate. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_FRAME_RATE_MODE, MIL.M_VARIABLE); // Attempts to update the file header with the encoding frame rate // if lower than the specified frame rate. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_QUALITY, 100); // 1=best speed, 100=best quality MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_PROFILE, MIL.M_PROFILE_HIGH); // MIL.M_PROFILE_BASELINE, MIL.M_PROFILE_MAIN, MIL.M_PROFILE_HIGH MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_LEVEL, MIL.M_LEVEL_4_2); // MIL.M_LEVEL_1, MIL.M_LEVEL_1B, MIL.M_LEVEL_1_1, MIL.M_LEVEL_1_2, MIL.M_LEVEL_1_3, // MIL.M_LEVEL_2, MIL.M_LEVEL_2_1, MIL.M_LEVEL_2_2, // MIL.M_LEVEL_3, MIL.M_LEVEL_3_1, MIL.M_LEVEL_3_2, // MIL.M_LEVEL_4, MIL.M_LEVEL_4_1, MIL.M_LEVEL_4_2, // MIL.M_LEVEL_5, MIL.M_LEVEL_5_1 MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_STREAM_GROUP_OF_PICTURE_SIZE, 30); // Interval between I-Frame // Initialize the optional encoding end function data structure. EncodingFrameEndUserHookData.EncodedImageCount = 0; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle EncodingFrameEndUserHookDataHandle = GCHandle.Alloc(EncodingFrameEndUserHookData); // Register the encoding end function to the sequence context. MIL_SEQ_HOOK_FUNCTION_PTR FrameEncodingEndFunctionDelegate = new MIL_SEQ_HOOK_FUNCTION_PTR(FrameEncodingEndFunction); MIL.MseqHookFunction(MilCompressContext, MIL.M_FRAME_END, FrameEncodingEndFunctionDelegate, GCHandle.ToIntPtr(EncodingFrameEndUserHookDataHandle)); // Provide a sample image to initialize the encoding engine accordingly. MIL.MseqControl(MilCompressContext, MIL.M_CONTEXT, MIL.M_BUFFER_SAMPLE, MilGrabBufferList[0]); // Start the encoding process, waits for buffer to be fed for encoding. MIL.MseqProcess(MilCompressContext, MIL.M_START, MIL.M_ASYNCHRONOUS); // Display the type of compression used. Console.Write("Live image capture and compression to file using "); MIL.MseqInquire(MilCompressContext, MIL.M_CONTEXT, MIL.M_CODEC_TYPE, ref SeqSystemType); if (SeqSystemType == MIL.M_HARDWARE + MIL.M_QSV) { Console.WriteLine("Hardware acceleration."); } else // MIL.M_SOFTWARE + MIL.M_QSV { Console.WriteLine("Software implementation."); } // Set the sequence context id in the user hook data structure to start // feeding buffers for encoding in ProcessingFunction. // ProcessingUserHookData.MilSeqContext = MilCompressContext; ProcessingUserHookData.ProcessedImageCount = 0; ProcessingUserHookData.ProcessingOperation = ProcessingHookOperation.ENCODE; MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_START, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); // NOTE: Now the main() is free to perform other tasks while the compression is executing. // --------------------------------------------------------------------------------------- // Print a message and wait for a key press after a minimum number of frames. Console.WriteLine("Press <Enter> to stop.\n"); Console.ReadKey(); // Stop the processing. MIL.MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, MIL.M_STOP + MIL.M_WAIT, MIL.M_DEFAULT, ProcessingFunctionDelegate, GCHandle.ToIntPtr(hUserData)); // Free the processing user data handle. hUserData.Free(); // Stop the encoding process MIL.MseqProcess(MilCompressContext, MIL.M_STOP, MIL.M_WAIT); // Make sure the hook handler function delegate is not prematurely garbage collected since // only MIL has a reference to it. GC.KeepAlive(FrameEncodingEndFunctionDelegate); // Free the encoding user data handle. EncodingFrameEndUserHookDataHandle.Free(); // Print statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref ProcessFrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref ProcessFrameRate); Console.WriteLine("{0} frames encoded at {1:0.00} frames/sec ({2:0.0} ms/frame).", ProcessFrameCount, ProcessFrameRate, 1000.0 / ProcessFrameRate); Console.WriteLine(); MIL.MseqInquire(MilCompressContext, MIL.M_SEQ_OUTPUT(0) + MIL.M_SEQ_DEST(0), MIL.M_STREAM_FILE_NAME_SIZE, ref SeqProcessFilePathSize); SeqProcessFilePath = new StringBuilder((int)SeqProcessFilePathSize); MIL.MseqInquire(MilCompressContext, MIL.M_SEQ_OUTPUT(0) + MIL.M_SEQ_DEST(0), MIL.M_STREAM_FILE_NAME, SeqProcessFilePath); Console.WriteLine("The video sequence file was written to:"); Console.WriteLine("{0}.", SeqProcessFilePath.ToString()); Console.WriteLine(); Console.WriteLine("It can be played back using any compatible video player."); // Free the grab buffers and sequence context. while (MilGrabBufferListSize > 0) { MIL.MbufFree(MilGrabBufferList[--MilGrabBufferListSize]); MilGrabBufferList[MilGrabBufferListSize] = MIL.M_NULL; } MIL.MseqFree(MilCompressContext); // Wait for a key to start the replay. Console.WriteLine("Press <Enter> to replay encoded sequence."); Console.ReadKey(); MIL.MseqAlloc(MilSystem, MIL.M_DEFAULT, MIL.M_SEQ_DECOMPRESS, MIL.M_DEFAULT, MIL.M_DEFAULT, ref MilDecompressContext); // Specify the destination of the compressed file and the target container type. // The last argument specifies to generate an MP4 file. MIL.MseqDefine(MilDecompressContext, MIL.M_SEQ_INPUT(0), MIL.M_FILE, (MilSystemLocation != MIL.M_REMOTE ? SEQUENCE_FILE : REMOTE_SEQUENCE_FILE), MIL.M_FILE_FORMAT_MP4); double outputFrameRate = 0.0; MIL.MseqInquire(MilDecompressContext, MIL.M_SEQ_INPUT(0), MIL.M_STREAM_FRAME_RATE, ref outputFrameRate); Console.WriteLine(); Console.WriteLine("Replaying file at {0:0.00} frames/second.", outputFrameRate); // Initialize the optional decoding end function data structure. DecodingFrameEndUserHookData.DecodedImageCount = 0; DecodingFrameEndUserHookData.MilImageDisp = MilImageDisp; // get a handle to the HookDataStruct object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle DecodingFrameEndUserHookDataHandle = GCHandle.Alloc(DecodingFrameEndUserHookData); // Register the decoding end function to the sequence context. MIL_SEQ_HOOK_FUNCTION_PTR FrameDecodingEndFunctionDelegate = new MIL_SEQ_HOOK_FUNCTION_PTR(FrameDecodingEndFunction); MIL.MseqHookFunction(MilDecompressContext, MIL.M_FRAME_END, FrameDecodingEndFunctionDelegate, GCHandle.ToIntPtr(DecodingFrameEndUserHookDataHandle)); // Start the decoding process, waits for buffer to be fed for encoding. MIL.MseqProcess(MilDecompressContext, MIL.M_START, MIL.M_ASYNCHRONOUS); // Print a message and wait for a key press after a minimum number of frames. Console.WriteLine("Press <Enter> to stop.\n"); Console.ReadKey(); // Stop the play back. MIL.MseqProcess(MilDecompressContext, MIL.M_STOP, MIL.M_NULL); // Make sure the hook handler function delegate is not prematurely garbage collected since // only MIL has a reference to it. GC.KeepAlive(FrameDecodingEndFunctionDelegate); // Free the decoding user data handle. DecodingFrameEndUserHookDataHandle.Free(); MIL.MseqFree(MilDecompressContext); // Wait for a key to end. Console.WriteLine("Press <Enter> to end."); Console.ReadKey(); // Release defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); return(0); }