Click here to show toolbars of the Web Online Help System: show toolbars |
//**********************************************************************************/ // // File name: SuperResolutionCode.cpp // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: This example aligns a sequence of images containing bar codes // and combines them with a super-resolution process to form // an enhanced image, which is then used to decode the bar codes. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved #include <mil.h> //*********************************************************************************** // Example description. //*********************************************************************************** void PrintHeader() { MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n") MIL_TEXT("SuperResolutionCode\n\n") MIL_TEXT("[SYNOPSIS]\n") MIL_TEXT("This example aligns a sequence of images containing bar codes\n") MIL_TEXT("and combines them with a super-resolution process to form\n") MIL_TEXT("an enhanced image, which is then used to decode the bar codes.\n\n") MIL_TEXT("[MODULES USED]\n") MIL_TEXT("Modules used: application, system, display, buffer,\n") MIL_TEXT("graphics, sequence, registration, code reader.\n\n") MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } //*********************************************************************************** // Structures declarations. //*********************************************************************************** // Hold the description of the sequence to be processed. struct SSequenceDescription { MIL_CONST_TEXT_PTR Filename; MIL_INT StartImage; MIL_INT NumberOfImages; MIL_INT ChildOffsetX; MIL_INT ChildOffsetY; MIL_INT ChildSizeX; MIL_INT ChildSizeY; MIL_DOUBLE PsfRadius; MIL_INT PsfType; MIL_DOUBLE Smoothness; }; // Processing object. class CSuperResolution { public: CSuperResolution(MIL_ID MilSystem); ~CSuperResolution(); void InitializeWithFirstImage(MIL_ID MilFirstImage, MIL_INT NumberOfImages, MIL_INT ChildOffsetX, MIL_INT ChildOffsetY, MIL_INT ChildSizeX, MIL_INT ChildSizeY); bool AddImage(MIL_ID MilImage); void SuperResolution(MIL_DOUBLE PsfRadius, MIL_INT PsfType, MIL_DOUBLE Smoothness); protected: void InitializeDisplay(MIL_ID MilFirstImage, MIL_INT ChildSizeX, MIL_INT ChildSizeY); void DrawCurrentResult(); MIL_ID m_MilSystem; // Registration context and result. MIL_ID m_MilRegContext; MIL_ID m_MilRegResult; // Images of the sequence. MIL_ID* m_MilSequenceImageTable; MIL_ID* m_MilPartialSequenceImageTable; MIL_INT m_NumberOfImagesInTable; MIL_INT m_NumberOfAllocatedTableElements; // Various images for display. MIL_ID m_MilDisplay; MIL_ID m_MilOverlayImage; MIL_ID m_MilFullDisplayImage; MIL_ID m_MilTrackingImage; MIL_ID m_MilZoomedWithSuperResolutionImage; MIL_ID m_MilTrackingOverlayImage; MIL_INT m_FirstImageChildOffsetX; MIL_INT m_FirstImageChildOffsetY; }; //*********************************************************************************** // Constants definitions. //*********************************************************************************** // Note that the sequence is imaged with a pretty good focus, therefore // the Point Spread Function (PSF) is simply the size of one CCD pixel // (square of "radius" = 0.5 pixel). // // All the images have low noise, the super-resolution smoothness can be // reduced less than its default behavior of 50. #define EXAMPLE_SEQUENCE_PATH M_IMAGE_PATH MIL_TEXT("SuperResolutionCode/") #define SEQUENCE_FILE EXAMPLE_SEQUENCE_PATH MIL_TEXT("code_far.avi") // The sequence data struct for super-resolution. static const SSequenceDescription Sequences = { SEQUENCE_FILE, // Filename 0, // StartImage 8, // NumberOfImages, can be from 2 to 8. 80, // ChildOffsetX 10, // ChildOffsetY 200, // ChildSizeX 110, // ChildSizeY 0.5, // PsfRadius M_SQUARE, // PsfType 30.0 // Smoothness }; // Mosaic scale factor for super-resolution. static const MIL_DOUBLE MOSAIC_SCALE = 2.0; // Utility function. template <class T> inline T Max(T InValue1, T InValue2) { if (InValue1 > InValue2) return InValue1; else return InValue2; } //*********************************************************************************** // Main. //*********************************************************************************** int MosMain(void) { // Allocate MIL objects. MIL_ID MilApplication = MappAlloc(M_NULL, M_DEFAULT, M_NULL); MIL_ID MilSystem = MsysAlloc(M_DEFAULT, M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, &MilSystem); // Main application code here. PrintHeader(); { // Open sequence. MbufImportSequence(Sequences.Filename, M_DEFAULT, M_NULL, M_NULL, M_NULL, M_NULL, M_NULL, M_OPEN); MIL_INT NumberOfImagesInSequence = MbufDiskInquire(Sequences.Filename, M_NUMBER_OF_IMAGES, M_NULL); MIL_DOUBLE FrameRate; MbufDiskInquire(Sequences.Filename, M_FRAME_RATE, &FrameRate); // Restore first image. MIL_ID MilSequenceImage; MbufImportSequence(Sequences.Filename, M_DEFAULT, M_RESTORE, MilSystem, &MilSequenceImage, Sequences.StartImage, 1, M_READ); MIL_INT FrameIndex = 1; // Allocate processing object. CSuperResolution SuperResolution(MilSystem); SuperResolution.InitializeWithFirstImage(MilSequenceImage, Sequences.NumberOfImages, Sequences.ChildOffsetX, Sequences.ChildOffsetY, Sequences.ChildSizeX, Sequences.ChildSizeY); MosPrintf(MIL_TEXT("A sequence of images is captured at different focus distance using,\n") MIL_TEXT("for example, a liquid lens optic.\n\n") MIL_TEXT("A rectangular region defines the ROI used to perform the image alignment.\n\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); MosPrintf(MIL_TEXT("Aligning...\n")); MIL_DOUBLE PreviousTime; MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &PreviousTime); bool Success = true; while (Success && FrameIndex < Sequences.NumberOfImages) { // Read and process next image in sequence. MbufImportSequence(Sequences.Filename, M_DEFAULT, M_LOAD, M_NULL, &MilSequenceImage, M_DEFAULT, 1, M_READ); Success = SuperResolution.AddImage(MilSequenceImage); FrameIndex++; // Wait to have a proper frame rate. MIL_DOUBLE EndTime; MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &EndTime); MIL_DOUBLE WaitTime = (1.0/FrameRate) - (EndTime - PreviousTime); if (WaitTime > 0) MappTimer(M_DEFAULT, M_TIMER_WAIT, &WaitTime); MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &PreviousTime); } MosPrintf(MIL_TEXT("\n%d images have been aligned with the first one.\n\n"), Sequences.NumberOfImages-1); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); // Perform image enhancement with super-resolution. SuperResolution.SuperResolution(Sequences.PsfRadius, Sequences.PsfType, Sequences.Smoothness); MosPrintf(MIL_TEXT("\nPress <Enter> to end.\n")); MosGetch(); // Free image and close sequence. MbufFree(MilSequenceImage); MbufImportSequence(Sequences.Filename, M_DEFAULT, M_NULL, M_NULL, M_NULL, M_NULL, M_NULL, M_CLOSE); } // Free MIL objects. MsysFree(MilSystem); MappFree(MilApplication); return 0; } //*********************************************************************************** // Constructor of the processing object. // Most initialization will be done later in InitializeWithFirstImage. //*********************************************************************************** CSuperResolution::CSuperResolution(MIL_ID MilSystem) : m_MilSystem (MilSystem), m_MilRegContext (M_NULL), m_MilRegResult (M_NULL), m_MilSequenceImageTable (NULL), m_MilPartialSequenceImageTable (NULL), m_NumberOfImagesInTable (0), m_NumberOfAllocatedTableElements (0), m_MilDisplay (M_NULL), m_MilOverlayImage (M_NULL), m_MilFullDisplayImage (M_NULL), m_MilTrackingImage (M_NULL), m_MilZoomedWithSuperResolutionImage (M_NULL), m_MilTrackingOverlayImage (M_NULL), m_FirstImageChildOffsetX (0), m_FirstImageChildOffsetY (0) { } //*********************************************************************************** // Destructor of the processing object. // Free all objects. //*********************************************************************************** CSuperResolution::~CSuperResolution() { // Free all allocated MIL objects. while (m_NumberOfImagesInTable) { m_NumberOfImagesInTable--; MbufFree(m_MilSequenceImageTable[m_NumberOfImagesInTable]); } delete [] m_MilPartialSequenceImageTable; delete [] m_MilSequenceImageTable; if (m_MilRegResult != M_NULL) MregFree(m_MilRegResult); if (m_MilRegContext != M_NULL) MregFree(m_MilRegContext); MbufFree(m_MilTrackingOverlayImage); MbufFree(m_MilZoomedWithSuperResolutionImage); MbufFree(m_MilTrackingImage); MbufFree(m_MilFullDisplayImage); MdispFree(m_MilDisplay); } //*********************************************************************************** // Initialize the processing object. // // The processing object will be ready to align a series of images with the // child specified when calling this function. //*********************************************************************************** void CSuperResolution::InitializeWithFirstImage(MIL_ID MilFirstImage, MIL_INT NumberOfImages, MIL_INT ChildOffsetX, MIL_INT ChildOffsetY, MIL_INT ChildSizeX, MIL_INT ChildSizeY) { // Allocate registration context and result. MregAlloc(m_MilSystem, M_STITCHING, M_DEFAULT, &m_MilRegContext); MregAllocResult(m_MilSystem, M_DEFAULT, &m_MilRegResult); MregControl(m_MilRegContext, M_CONTEXT, M_NUMBER_OF_ELEMENTS, NumberOfImages); m_FirstImageChildOffsetX = ChildOffsetX; m_FirstImageChildOffsetY = ChildOffsetY; // Allocate an array to store the images of the sequence. m_MilSequenceImageTable = new MIL_ID[NumberOfImages]; m_MilPartialSequenceImageTable = new MIL_ID[NumberOfImages]; m_NumberOfAllocatedTableElements = NumberOfImages; m_NumberOfImagesInTable = 0; // Initialize the display. InitializeDisplay(MilFirstImage, ChildSizeX, ChildSizeY); MbufCopy(MilFirstImage, m_MilFullDisplayImage); MgraRectAngle(M_DEFAULT, m_MilOverlayImage, ChildOffsetX, ChildOffsetY, ChildSizeX-1, ChildSizeY-1, 0, M_CORNER_AND_DIMENSION); // Keep a copy of the specified child of the first image. // All the other images of the sequence will be aligned with this child. MbufAlloc2d(m_MilSystem, ChildSizeX, ChildSizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC, &(m_MilSequenceImageTable[0])); m_NumberOfImagesInTable++; MbufCopyClip(MilFirstImage, m_MilSequenceImageTable[0], -ChildOffsetX, -ChildOffsetY); // Dummy calculate, just to initialize the result. MregCalculate(m_MilRegContext, m_MilSequenceImageTable, m_MilRegResult, m_NumberOfImagesInTable, M_DEFAULT); // Specify the initial rough location of the next image // with respect to the child of the first image. MregSetLocation(m_MilRegContext, m_NumberOfImagesInTable, 0, M_POSITION_XY, static_cast<MIL_DOUBLE>(-ChildOffsetX), static_cast<MIL_DOUBLE>(-ChildOffsetY), M_DEFAULT, M_DEFAULT, M_DEFAULT); } //*********************************************************************************** // Add one image to the sequence of images to align. // // The image will be copied in the internal array of images to be processed. // Registration is used such that the child specified in InitializeWithFirstImage // is aligned in the new image. //*********************************************************************************** bool CSuperResolution::AddImage(MIL_ID MilImage) { if (m_NumberOfImagesInTable >= m_NumberOfAllocatedTableElements) return false; // Display the image. MbufCopy(MilImage, m_MilFullDisplayImage); // Set the mosaic offsets. MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_STATIC_INDEX, m_NumberOfImagesInTable-1); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_OFFSET_X, 0); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_OFFSET_Y, 0); // Keep a copy of the sequence image. m_MilSequenceImageTable[m_NumberOfImagesInTable] = MbufAlloc2d( MbufInquire(MilImage, M_OWNER_SYSTEM, M_NULL), MbufInquire(MilImage, M_SIZE_X , M_NULL), MbufInquire(MilImage, M_SIZE_Y , M_NULL), MbufInquire(MilImage, M_TYPE , M_NULL), M_IMAGE+M_PROC, M_NULL); MbufCopy(MilImage, m_MilSequenceImageTable[m_NumberOfImagesInTable]); m_NumberOfImagesInTable++; // Create an array of images that contains M_NULL in all elements // except for image 0 and current image. m_MilPartialSequenceImageTable[0] = m_MilSequenceImageTable[0]; for (MIL_INT i = 1; i < m_NumberOfImagesInTable-1; i++) m_MilPartialSequenceImageTable[i] = M_NULL; m_MilPartialSequenceImageTable[m_NumberOfImagesInTable-1] = m_MilSequenceImageTable[m_NumberOfImagesInTable-1]; // First alignment: use translation only. MregControl(m_MilRegContext, M_CONTEXT, M_TRANSFORMATION_TYPE, M_TRANSLATION); MregCalculate(m_MilRegContext, m_MilPartialSequenceImageTable, m_MilRegResult, m_NumberOfImagesInTable, M_DEFAULT); MIL_INT Status; MregGetResult(m_MilRegResult, M_GENERAL, M_RESULT+M_TYPE_MIL_INT, &Status); if (Status != M_SUCCESS) return false; // Second alignment will use the result of the first alignment as initial rough location. MregSetLocation(m_MilRegContext, M_ALL, M_UNCHANGED, // All the images to be aligned will be aligned with the same targets M_COPY_REG_RESULT, // using the initial location specified by the result m_MilRegResult, // of the alignment just performed. M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT); // Second alignment: translation and rotation. MregControl(m_MilRegContext, M_CONTEXT, M_TRANSFORMATION_TYPE, M_TRANSLATION_ROTATION_SCALE); MregCalculate(m_MilRegContext, m_MilPartialSequenceImageTable, m_MilRegResult, m_NumberOfImagesInTable, M_DEFAULT); MregGetResult(m_MilRegResult, M_GENERAL, M_RESULT+M_TYPE_MIL_INT, &Status); if (Status != M_SUCCESS) return false; // The alignment of this image is done. Do not re-do the alignment of this image // when we will receive other images in the sequence. // Simply copy the results of the alignment to the registration // context. Since this image will not be part of m_MilPartialSequenceImageTable // in future calls to MregCalculate, its alignment will not be recalculated. MregSetLocation(m_MilRegContext, M_ALL, M_UNCHANGED, M_COPY_REG_RESULT, m_MilRegResult, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT); if (m_NumberOfImagesInTable < m_NumberOfAllocatedTableElements) { // The initial rough location of the next image of the sequence is copied // from the alignment result of the just aligned image. MregSetLocation(m_MilRegContext, m_NumberOfImagesInTable, 0, // The next image will be aligned with image 0. M_COPY_REG_RESULT, // using the initial location specified by the result. m_MilRegResult, // of the alignment just performed. static_cast<MIL_DOUBLE>(m_NumberOfImagesInTable-1), 0, // of the just aligned image with image 0. M_DEFAULT, M_DEFAULT); } // Draw the result. DrawCurrentResult(); return true; } //***************************************************************************** // Perform super-resolution on the sequence of images and display the results. // Also show the result of averaging all the images, for comparison purpose. //***************************************************************************** // Maximum length of the string to read. #define STRING_LENGTH_MAX 64L // Width and height given to the text to write. #define TEXT_WIDTH 140 #define TEXT_HEIGHT 20 // The Y offset to draw the code from the result y position of the code. #define DRAW_CODE_Y_OFFSET 30 void CSuperResolution::SuperResolution(MIL_DOUBLE PsfRadius, MIL_INT PsfType, MIL_DOUBLE Smoothness) { // Clear the overlay. MbufClear(m_MilTrackingOverlayImage, (MIL_DOUBLE)(MdispInquire(m_MilDisplay, M_TRANSPARENT_COLOR, M_NULL))); // Setup the registration result to do super-resolution with all images. MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_STATIC_INDEX, 0); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_SCALE , MOSAIC_SCALE); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_OFFSET_X, 0); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_OFFSET_Y, 0); MregControl(m_MilRegResult, M_GENERAL, M_SR_PSF_RADIUS, PsfRadius); MregControl(m_MilRegResult, M_GENERAL, M_SR_PSF_TYPE , PsfType); MregControl(m_MilRegResult, M_GENERAL, M_SR_SMOOTHNESS, Smoothness); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_COMPOSITION, M_SUPER_RESOLUTION); // Composes the mosaic into the super-resolution result image. MregTransformImage(m_MilRegResult, m_MilSequenceImageTable, m_MilZoomedWithSuperResolutionImage, m_NumberOfImagesInTable, M_BILINEAR, M_DEFAULT); MgraText(M_DEFAULT, m_MilOverlayImage, MbufInquire(m_MilZoomedWithSuperResolutionImage, M_ANCESTOR_OFFSET_X, M_NULL) +MbufInquire(m_MilZoomedWithSuperResolutionImage, M_SIZE_X, M_NULL)-TEXT_WIDTH, MbufInquire(m_MilZoomedWithSuperResolutionImage, M_SIZE_Y, M_NULL), MIL_TEXT("Super-resolution")); MosPrintf(MIL_TEXT("The aligned images are combined in a higher resolution image using\n") MIL_TEXT("a super-resolution process.\n\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); // Allocate code objects. MIL_ID Barcode = McodeAlloc(m_MilSystem, M_DEFAULT, M_DEFAULT, M_NULL); MIL_ID BarModel = McodeModel(Barcode, M_ADD, M_CODE128, M_NULL, M_DEFAULT, M_NULL); MIL_ID CodeResults = McodeAllocResult(m_MilSystem, M_DEFAULT, M_NULL); // Read the code128 code in the super-resolution image. McodeRead(Barcode, m_MilZoomedWithSuperResolutionImage, CodeResults); // Get decoding status. MIL_INT BarcodeStatus; McodeGetResult(CodeResults, M_STATUS+M_TYPE_MIL_INT, &BarcodeStatus); MIL_TEXT_CHAR BarcodeString[STRING_LENGTH_MAX]; MIL_DOUBLE PositionX, PositionY; // Check if decoding was successful. if (BarcodeStatus == M_STATUS_READ_OK) { // Get decoded string and position. McodeGetResult(CodeResults, M_STRING, BarcodeString); McodeGetResult(CodeResults, M_POSITION_X, &PositionX); McodeGetResult(CodeResults, M_POSITION_Y, &PositionY); McodeDraw(M_DEFAULT, CodeResults, m_MilTrackingOverlayImage, M_DRAW_POSITION, M_ALL, M_DEFAULT); MgraText(M_DEFAULT, m_MilTrackingOverlayImage, PositionX, PositionY+DRAW_CODE_Y_OFFSET, BarcodeString); } MIL_INT NumOfModels = McodeInquire(Barcode, M_NUMBER_OF_CODE_MODELS, M_NULL); McodeModel(Barcode, M_DELETE, M_NULL, M_NULL, M_DEFAULT, &BarModel); NumOfModels = McodeInquire(Barcode, M_NUMBER_OF_CODE_MODELS, M_NULL); McodeModel(Barcode, M_ADD, M_4_STATE, M_NULL, M_DEFAULT, M_NULL); McodeControl(Barcode, M_ENCODING, M_ENC_AUSTRALIA_MAIL_RAW); // Read the 4-state code in the super-resolution image. McodeRead(Barcode, m_MilZoomedWithSuperResolutionImage, CodeResults); // Get decoding status. McodeGetResult(CodeResults, M_STATUS+M_TYPE_MIL_INT, &BarcodeStatus); // Check if decoding was successful. if (BarcodeStatus == M_STATUS_READ_OK) { // Get decoded string and position. McodeGetResult(CodeResults, M_STRING, BarcodeString); McodeGetResult(CodeResults, M_POSITION_X, &PositionX); McodeGetResult(CodeResults, M_POSITION_Y, &PositionY); McodeDraw(M_DEFAULT, CodeResults, m_MilTrackingOverlayImage, M_DRAW_POSITION, M_ALL, M_DEFAULT); MgraText(M_DEFAULT, m_MilTrackingOverlayImage, PositionX, PositionY+DRAW_CODE_Y_OFFSET, BarcodeString); } MosPrintf(MIL_TEXT("The codes are read from the resulting super-resolution image.\n")); // Free code objects. McodeFree(CodeResults); McodeFree(Barcode); } //***************************************************************************** // Initialize a display that will show // - The sequence image. // - A result of the tracking of the child of the first image in all // the sequence image. // - The result of super-resolution and of averaging of all images of the // sequence. //***************************************************************************** void CSuperResolution::InitializeDisplay(MIL_ID MilFirstImage, MIL_INT ChildSizeX, MIL_INT ChildSizeY) { // Allocate display. m_MilDisplay = MdispAlloc(m_MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, M_NULL); MdispControl(m_MilDisplay, M_OVERLAY, M_ENABLE); MIL_INT SequenceImageSizeX = MbufInquire(MilFirstImage, M_SIZE_X, M_NULL); MIL_INT SequenceImageSizeY = MbufInquire(MilFirstImage, M_SIZE_Y, M_NULL); // Find the size of the zoomed child. MIL_INT ZoomedChildSizeX = static_cast<MIL_INT>(ChildSizeX * MOSAIC_SCALE); MIL_INT ZoomedChildSizeY = static_cast<MIL_INT>(ChildSizeY * MOSAIC_SCALE); // Allocate full display image. MIL_INT FullDisplayImageSizeX = SequenceImageSizeX + Max(ZoomedChildSizeX, SequenceImageSizeX); MIL_INT FullDisplayImageSizeY = Max(SequenceImageSizeY, ZoomedChildSizeY); m_MilFullDisplayImage = MbufAlloc2d(m_MilSystem, FullDisplayImageSizeX, FullDisplayImageSizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, M_NULL); MbufClear(m_MilFullDisplayImage, M_COLOR_BLACK); MdispSelect(m_MilDisplay, m_MilFullDisplayImage); MdispInquire(m_MilDisplay, M_OVERLAY_ID, &m_MilOverlayImage); MgraControl(M_DEFAULT, M_BACKGROUND_MODE, M_TRANSPARENT); MgraColor(M_DEFAULT, M_COLOR_GREEN); MgraText(M_DEFAULT, m_MilOverlayImage, SequenceImageSizeX-TEXT_WIDTH, SequenceImageSizeY-TEXT_HEIGHT, MIL_TEXT("Source image")); // Allocate children in the full display image to show current image aligned // with first image and to show zoomed version of the sequence. m_MilTrackingImage = MbufChild2d(m_MilFullDisplayImage, SequenceImageSizeX, 0, SequenceImageSizeX, SequenceImageSizeY, M_NULL); m_MilTrackingOverlayImage = MbufChild2d(m_MilOverlayImage, SequenceImageSizeX, 0, SequenceImageSizeX, SequenceImageSizeY, M_NULL); m_MilZoomedWithSuperResolutionImage = MbufChild2d(m_MilFullDisplayImage, SequenceImageSizeX, 0, ZoomedChildSizeX, ZoomedChildSizeY, M_NULL); } //***************************************************************************** // Display the result of the alignment of the child of the first image of the // sequence with the current image of the sequence. //***************************************************************************** void CSuperResolution::DrawCurrentResult() { // Draw the current image as aligned with image 0. MIL_INT i; for (i = 0; i < m_NumberOfImagesInTable-1; i++) // Create an array of images that contains. m_MilPartialSequenceImageTable[i] = M_NULL; // M_NULL in all elements. // except for the current image. m_MilPartialSequenceImageTable[m_NumberOfImagesInTable-1] = m_MilSequenceImageTable[m_NumberOfImagesInTable-1]; MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_COMPOSITION, M_LAST_IMAGE); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_OFFSET_X, m_FirstImageChildOffsetX); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_OFFSET_Y, m_FirstImageChildOffsetY); MregControl(m_MilRegResult, M_GENERAL, M_MOSAIC_STATIC_INDEX, 0); MregTransformImage(m_MilRegResult, m_MilPartialSequenceImageTable, m_MilTrackingImage, m_NumberOfImagesInTable, M_BILINEAR+M_OVERSCAN_CLEAR, M_DEFAULT); if(m_NumberOfImagesInTable==2) { MregDraw(M_DEFAULT, m_MilRegResult, m_MilTrackingOverlayImage, M_DRAW_BOX, 0, M_DEFAULT); MgraText(M_DEFAULT, m_MilTrackingOverlayImage, MbufInquire(m_MilTrackingOverlayImage, M_SIZE_X, M_NULL)-TEXT_WIDTH, MbufInquire(m_MilTrackingOverlayImage, M_SIZE_Y, M_NULL)-TEXT_HEIGHT, MIL_TEXT("Realigned image")); } }