我是 Matrox (MIL) 和 C++ 编程新手。我一直想将相机的使用发挥到极致(120 Hz 帧速率)。我目前正在通过 Microsoft Visual Studio 使用 MIL 对相机进行编程。我的程序当前的工作方式是使用 MdigProcess 使用单独的函数获取和保存每个图像。然而,这会将相机的速度减慢至大约 10Hz,因为每次准备好图像时都会调用该函数将图像保存在缓冲区中。如果我不保存图像,那么相机就可以正常工作。但我不会有任何数据:/
我正在考虑先将图像(目前为 100 张图像)放入缓冲区中一次,然后保存它们。有办法做到这一点吗?这是我的尝试:
#include <mil.h>
#include <stdlib.h>
/* Number of images in the buffering grab queue.
Generally, increasing this number gives a better real-time grab.
*/
#define BUFFERING_SIZE_MAX 5
/* User's processing function prototype. */
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void*
HookDataPtr);
/* User's processing function hook data structure. */
typedef struct
{
MIL_ID MilDigitizer;
MIL_ID MilImageDisp;
MIL_INT ProcessedImageCount;
} HookDataStruct;
/* Main function. */
/* ---------------*/
int MosMain(void)
{
MIL_ID MilApplication;
MIL_ID MilSystem;
MIL_ID MilDigitizer;
MIL_ID MilDisplay; /* Display identifier. */
MIL_ID MilImageDisp; /* Display Image buffer identifier. */
MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX] = { 0 };
MIL_INT MilGrabBufferListSize;
MIL_INT ProcessFrameCount = 0, ProcessFrameMissed = 0, ProcessFrameCorrupted = 0;
MIL_DOUBLE ProcessFrameRate = 0;
MIL_DOUBLE FrameRate; // Initializes the FrameRate variable as double
HookDataStruct UserHookData;
MappAlloc(M_NULL, M_DEFAULT, &MilApplication); /* This initializes the MIL library. M_NULL means no cluster manager will be used. M_DEFAULT means reported error message will be displayed. */
MsysAlloc(M_SYSTEM_RAPIXOCL, M_DEFAULT, M_DEFAULT, &MilSystem); /* This allocates a MIL system*/
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDisplay); /* M_WINDOWED means it will display at a separate window*/
MdigAlloc(MilSystem, M_DEV0, MIL_TEXT("C:\\Users\\fluids-student\\Documents\\JAI 5000 PMCL.dcf"), M_DEFAULT, &MilDigitizer);
/* Allocate a monochrome display buffer. */
MbufAlloc2d(MilSystem, 2560, 2048, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &MilImageDisp);
MbufClear(MilImageDisp, M_BLACK);
/* Display the image buffer. */
MdispSelect(MilDisplay, MilImageDisp);
/* This inquires the frame rate */
MdigInquire(MilDigitizer, M_SELECTED_FRAME_RATE, &FrameRate);
MosPrintf(MIL_TEXT("The frame rate is @ %0.2f fps.\n"), FrameRate);
/* Print a message. */
MosPrintf(MIL_TEXT("\nMULTIPLE BUFFERED PROCESSING.\n"));
MosPrintf(MIL_TEXT("-----------------------------\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to start acquisition.\n\n"));
/* Grab continuously on the display and wait for a key press. */
MdigGrabContinuous(MilDigitizer, MilImageDisp);
MosGetch();
/* Halt continuous grab. */
MdigHalt(MilDigitizer);
/* Allocate the grab buffers and clear them. */
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for (MilGrabBufferListSize = 0; MilGrabBufferListSize < BUFFERING_SIZE_MAX;
MilGrabBufferListSize++)
{
MbufAlloc2d(MilSystem,
MdigInquire(MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL),
8L + M_UNSIGNED,
M_IMAGE + M_GRAB + M_PROC,
&MilGrabBufferList[MilGrabBufferListSize]);
if (MilGrabBufferList[MilGrabBufferListSize])
MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF);
else
break;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
/* Initialize the user's processing function data structure. */
UserHookData.MilDigitizer = MilDigitizer;
UserHookData.MilImageDisp = MilImageDisp;
UserHookData.ProcessedImageCount = 0;
/* Start the processing. The processing function is called with every frame grabbed. */
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_SEQUENCE + M_COUNT(100), M_DEFAULT, ProcessingFunction, &UserHookData);
/* Here the main() is free to perform other tasks while the processing is executing. */
/* --------------------------------------------------------------------------------- */
/* Stop the processing. */
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_STOP, M_DEFAULT, ProcessingFunction, &UserHookData);
/* Print statistics. */
MdigInquire(MilDigitizer, M_PROCESS_FRAME_COUNT, &ProcessFrameCount);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_RATE, &ProcessFrameRate);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_MISSED, &ProcessFrameMissed);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_CORRUPTED, &ProcessFrameCorrupted);
MosPrintf(MIL_TEXT("\n\n%d frames grabbed at %.1f frames/sec (%.1f ms/frame).\n"),
(int)ProcessFrameCount, ProcessFrameRate, 1000.0 / ProcessFrameRate);
MosPrintf(MIL_TEXT("%ld frames missed.\n"), ProcessFrameMissed);
MosPrintf(MIL_TEXT("%ld frames corrupted.\n"), ProcessFrameCorrupted);
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosPrintf(MIL_TEXT("BufferListSize = %d\n"), MilGrabBufferListSize);
MosGetch();
/* Free the grab buffers. */
while (MilGrabBufferListSize > 0)
MbufFree(MilGrabBufferList[--MilGrabBufferListSize]);
/* Free display buffer. */
MbufFree(MilImageDisp);
/* Release defaults. */
MdigFree(MilDigitizer);
MdispFree(MilDisplay);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
/* User's processing function called every time a grab buffer is ready. */
/* -------------------------------------------------------------------- */
/* Local defines. */
#define STRING_LENGTH_MAX 20
#define STRING_POS_X 20
#define STRING_POS_Y 20
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr)
{
HookDataStruct* UserHookDataPtr = (HookDataStruct*)HookDataPtr;
MIL_ID ModifiedBufferId;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX] = { MIL_TEXT('\0'), };
MIL_TEXT_CHAR junkoutput[STRING_LENGTH_MAX] = { MIL_TEXT('\0'), };
/* Retrieve the MIL_ID of the grabbed buffer. */
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER + M_BUFFER_ID, &ModifiedBufferId);
/* Increment the frame counter. */
UserHookDataPtr->ProcessedImageCount++;
/* Print and draw the frame count (remove to reduce CPU usage). */
MosPrintf(MIL_TEXT("Acquiring frame #%d.\r"), (int)UserHookDataPtr->ProcessedImageCount);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%d"),
(int)UserHookDataPtr->ProcessedImageCount);
/* Execute the processing and update the display. */
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp); // Remove comment to see the image acquisition. Will slow down the frame rate/ acquisition time
/* Create file name base on the index of the frame that is being processed */
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("Image%03li.png"), UserHookDataPtr->ProcessedImageCount); // 0-adds zeroes to the naming, 3- three places, l-long integer, i-signed decimal integer
/* Save image to disk */
MbufSave(Text, UserHookDataPtr->MilImageDisp);
return 0;
}
感谢您提供的所有帮助!
Mil 安装应该附带一个示例文件夹。
军事控制中心应用程序中应该有一个链接。
MdigProcess.cpp 就是一个很好的例子。
图像缓冲区列表被设置为由捕获回调函数以环形或循环方式使用。 每次获取新图像时都会调用回调,您可以查询环形缓冲区中的哪张图像是最新捕获的图像。
请注意,这里存在线程和计时问题。 回调位于单独的线程中,如果帧速率很高,则帧之间没有太多时间进行处理。 在 50 fps 下,处理一帧只需 20 毫秒。