micro-manager / mmCoreAndDevices

Micro-Manager's device control layer, written in C++
41 stars 109 forks source link

Cannot verify interface compatibility of device adapter #123

Closed yuegew closed 2 years ago

yuegew commented 2 years ago

i write a device adapter for the Daheng camera. And when i test it, i find this error "Cannot verify interface compatibility of device adapter""Line 2: run-time error : Failed to load device "DCam" from adapter module "Dahengcameratest" [ Failed to load device adapter "Dahengcameratest" from "C:\Program Files\Micro-Manager-2.0\mmgr_dal_Dahengcameratest.dll" [ Cannot verify interface compatibility of device adapter [ Cannot find function GetModuleVersion() in module "C:\Program Files\Micro-Manager-2.0\mmgr_dal_Dahengcameratest.dll" [ ÕҲ»µ½ָ¶¨µijÌÐò¡£" Do you know what it mains? Thankyou very much.

marktsuchida commented 2 years ago

The most likely explanation is that your device adapter is not correctly linking to MMDevice-SharedRuntime.

yuegew commented 2 years ago

Thank you very much. I think i fixed this issue by adding the MODULE_API function. However, i encounter another problem. I open and run through the configuration of the device, but when i run through the step of opening the GUI, the micromanager crashed. The log is here.

2022-01-15T23:15:29.985238 tid88716 [IFO,Core] Did load device Dahengcamera from Dahengcameratest; label = Dahengcamera
2022-01-15T23:17:49.858043 tid88716 [IFO,Core] Will initialize device Dahengcamera
2022-01-15T23:17:51.892503 tid88716 [IFO,dev:Dahengcamera] camera open done
2022-01-15T23:17:51.916500 tid88716 [IFO,dev:Dahengcamera] Using ExposureTime (double) for Exposure
2022-01-15T23:17:51.922503 tid88716 [IFO,dev:Dahengcamera] exposurevalue5000.000000
2022-01-15T23:17:51.922503 tid88716 [IFO,dev:Dahengcamera] Using ExposureTime (double) for Exposure
2022-01-15T23:17:51.922503 tid88716 [IFO,dev:Dahengcamera] Synchronizing properties
2022-01-15T23:17:51.924502 tid88716 [IFO,dev:Dahengcamera] exposure is5000.000000
2022-01-15T23:17:51.925501 tid88716 [IFO,dev:Dahengcamera] Setting up image buffer
2022-01-15T23:17:51.925501 tid88716 [IFO,dev:Dahengcamera] ResizeImageBuffer: bitDepth: 8 color mode: 0
2022-01-15T23:17:51.925501 tid88716 [IFO,dev:Dahengcamera] ResizeImageBuffer: byteDepth 4 w 1280 h 1024 bufferSizeBytes 5242880
2022-01-15T23:17:51.925501 tid88716 [IFO,dev:Dahengcamera] finnish initialized
2022-01-15T23:17:51.925501 tid88716 [IFO,Core] Did initialize device Dahengcamera
2022-01-15T23:17:51.928502 tid88716 [IFO,dev:Dahengcamera] exposure is5000.000000
2022-01-15T23:17:55.012599 tid88716 [IFO,dev:Dahengcamera] exposure is5000.000000

The expossure time and the height and width of the device is right. I wonder wheter the 3rd party drive is link to the device ,but the expossure time and the height and width of the device is right. Then i try using script to load the device and it returns this.

`// Error: // Uncaught Exception: Method Invocation mmc.loadDevice : at Line: 2 : in file: <unknown file> : mmc .loadDevice ( "Camera" , "Dahengcameratest" , "D1214Cam" ) 

Target exception: java.lang.Exception: Failed to load device "D1214Cam" from adapter module "Dahengcameratest" [ Device adapter "Dahengcameratest" failed to instantiate device "D1214Cam" ]

bsh % java.lang.Exception: Failed to load device "D1214Cam" from adapter module "Dahengcameratest" [ Device adapter "Dahengcameratest" failed to instantiate device "D1214Cam" ]
    at mmcorej.MMCoreJJNI.CMMCore_loadDevice(Native Method)
    at mmcorej.CMMCore.loadDevice(CMMCore.java:312)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at bsh.Reflect.invokeMethod(Reflect.java:131)
    at bsh.Reflect.invokeObjectMethod(Reflect.java:77)
    at bsh.Name.invokeMethod(Name.java:852)
    at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:69)
    at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:96)
    at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:41)
    at bsh.Interpreter.run(Interpreter.java:471)
    at java.lang.Thread.run(Thread.java:748)`

Do you know what it means?

marktsuchida commented 2 years ago

From your first log, it looks like your device is correctly instantiated and its Initialize() function was successfully called. After Initialize(), other functions of your device may be called by Micro-Manager to interact with the device, and it is not possible to tell from the log which of them caused the crash.

I would recommend building your device adapter in Debug configuration and attaching the Visual Studio debugger before configuring the device. This should allow you to debug the crash.

As for your second log, I cannot interpret the error without knowing the exact script you ran.

yuegew commented 2 years ago

Thank you so much! I will try this very soon.

yuegew commented 2 years ago

Thank you very much. I think I solove the issue of the micromanager crashed. Unfortunately, when I snap an image , there is an "Missing pixel type in Thread" problem. And when i use live image the interface didn't open. The corelog is here

2022-01-18T16:32:01.151666 tid30248 [IFO,dev:Dahengcamera] SnapImageCallback:  img_.bitDepth 4
2022-01-18T16:32:19.908495 tid16740 [IFO,dev:Dahengcamera] exposure is100.000000
2022-01-18T16:32:20.517482 tid16740 [IFO,dev:Dahengcamera] SnapImage: acquisition started; waiting with timeout of 200 ms
2022-01-18T16:32:20.517482 tid16740 [IFO,dev:Dahengcamera] SnapImage stopped the acquisition because no image had been returned after 200 ms
2022-01-18T16:32:32.481580 tid30248 [IFO,dev:Dahengcamera] aquireImage:  try to copy DIB RGB image, BufferInfo 3932160 mm img buffer size 5242880
2022-01-18T16:33:54.610005 tid16740 [IFO,App] Failed to snap image
                                    [       ] java.lang.IllegalArgumentException: Missing pixel type in Thread[AWT-EventQueue-0,6,main]
                                    [       ]   at org.micromanager.data.internal.DefaultImage.<init>(DefaultImage.java:147)
                                    [       ]   at org.micromanager.data.internal.DefaultImage.<init>(DefaultImage.java:82)
                                    [       ]   at org.micromanager.acquisition.internal.DefaultAcquisitionManager.snap(DefaultAcquisitionManager.java:265)
                                    [       ]   at org.micromanager.internal.SnapLiveManager.snap(SnapLiveManager.java:849)
                                    [       ]   at org.micromanager.quickaccess.internal.controls.SnapButton$2.actionPerformed(SnapButton.java:103)
                                    [       ]   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
                                    [       ]   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
                                    [       ]   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
                                    [       ]   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
                                    [       ]   at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
                                    [       ]   at java.awt.Component.processMouseEvent(Component.java:6533)
                                    [       ]   at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
                                    [       ]   at java.awt.Component.processEvent(Component.java:6298)
                                    [       ]   at java.awt.Container.processEvent(Container.java:2237)
                                    [       ]   at java.awt.Component.dispatchEventImpl(Component.java:4889)
                                    [       ]   at java.awt.Container.dispatchEventImpl(Container.java:2295)
                                    [       ]   at java.awt.Component.dispatchEvent(Component.java:4711)
                                    [       ]   at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4889)
                                    [       ]   at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4526)
                                    [       ]   at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4467)
                                    [       ]   at java.awt.Container.dispatchEventImpl(Container.java:2281)
                                    [       ]   at java.awt.Window.dispatchEventImpl(Window.java:2746)
                                    [       ]   at java.awt.Component.dispatchEvent(Component.java:4711)
                                    [       ]   at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
                                    [       ]   at java.awt.EventQueue.access$500(EventQueue.java:97)
                                    [       ]   at java.awt.EventQueue$3.run(EventQueue.java:709)
                                    [       ]   at java.awt.EventQueue$3.run(EventQueue.java:703)
                                    [       ]   at java.security.AccessController.doPrivileged(Native Method)
                                    [       ]   at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
                                    [       ]   at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
                                    [       ]   at java.awt.EventQueue$4.run(EventQueue.java:731)
                                    [       ]   at java.awt.EventQueue$4.run(EventQueue.java:729)
                                    [       ]   at java.security.AccessController.doPrivileged(Native Method)
                                    [       ]   at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
                                    [       ]   at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
                                    [       ]   at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
                                    [       ]   at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
                                    [       ]   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
                                    [       ]   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
                                    [       ]   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
                                    [       ]   at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

I'm wondering what is related to it and want to get some supports from you, thank you very much.

marktsuchida commented 2 years ago

If it has something to do with pixel type, make sure that your camera's GetImageBytesPerPixel() returns 1 (8-bit gray), 2 (16-bit gray), or 4 (RGB). Correspondingly, GetNumberOfComponents() must return 1, 1, or 4, respectively. In contrast, GetBitDepth() is supposed to return the actual bit depth, independent of the pixel format (e.g., a 16-bit pixel might contain 14-bit data).

yuegew commented 2 years ago

Thank you very much! I think now I can open the device and grab the picture. But now I encounter another problem. The device only have 24 bits RGB, but the micromanager shows that it is 32 bits RGB, and the color of the picture seems to be raw data of bayer rg8, but I think i do convert the pixel format. I wonder how I can solve the problem. And the following is how I(not MM) convert and show the picture, it works well.

img.create(objImageDataPointer->GetHeight(), objImageDataPointer->GetWidth(), CV_8UC3);
pRGB24Buffer = objImageDataPointer->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);
memcpy(img.data, pRGB24Buffer, (objImageDataPointer->GetHeight()) * (objImageDataPointer->GetWidth()) * 3);
cv::flip(img, img, 0);
cv::imshow("www", img);
cv::waitKey(1);
marktsuchida commented 2 years ago

For historical reasons, the required format for RGB images is BGRA32. The extra 'A' component is not used, and should be set to zero. It is best to test your code by pointing the camera to blue or red objects (e.g. an LCD screen showing those colors) to confirm that you have the components in the correct order.

So I think you need to convert your image to RGB (debayer), and then to BGRA32. There are functions in MMDevice/Debayer.h that you can use for debayering (instead of OpenCV). These functions will generate the BGRA32 format directly, if I remember correctly.

yuegew commented 2 years ago

Thank you very much ,i follow your step and it turn out that this return a very good result , i can now run the camera in 32 bit RGB Howerver, i have to use scaneimage ,it only support device that GetImageBytesPerPixel() returns 1 (8-bit gray), 2 (16-bit gray). I wonder how i can show colored image with this, maybe 16bit RGB or 8bit RGB?

marktsuchida commented 2 years ago

Great to hear it worked!

MMDevice/MMCore does not support RGB with fewer than 8 bits per component. You could convert your images to 16-bit grayscale, at least to get a preview. You will have to ask the ScanImage people about their RGB image support.

marktsuchida commented 2 years ago

Considering this solved; please open a new issue if necessary.