Member
Joined:
Posts: 1

Good evening,
I tried to communicate with the Vialux module V9501 (controller board V4395 ) following what written in this post https://www.wavefrontshaping.net/post/id/20 and using the code available on https://github.com/wavefrontshaping/ALP4lib.

If I run the code, on line

DMD.SeqAlloc(nbImg = 2, bitDepth = bitDepth)

I get this error:

DMD.SeqAlloc(nbImg = 2, bitDepth = bitDepth)
File "---- \DMD\ALP4.py", line 445, in SeqAlloc
self._checkError(self._ALPLib.AlpSeqAlloc(self.ALP_ID, ct.c_long(bitDepth), ct.c_long(nbImg), ct.byref( SequenceId)),'Cannot allocate image sequence.')
File "---\DMD\ALP4.py", line 368, in _checkError
raise Exception(errorMsg)
Exception: Cannot allocate image sequence.
The requested memory is not available (full?).

Can you help me to fix this problem?
Thanks
Lorenzo

Administrator
Joined:
Posts: 73

Hi Lorenzo,

First, it is important to understand that ALP4lib is simply a wrap of the .dll (C/C++ API) provided by Vialux. So errors can come from the Python part, the one I wrote, or the .dll, the black box from Vialux.

The requested memory is not available (full?).

This one actually come from the .dll. I checked into the API desciption pdf, it simply says that "the memory requested is not available".

This could happen if you allocate to much memory without freeing some. If it happens the first time you allocate memory, this seems wrong.

My best bet would be to unplug/plug back the device and try again.

What is your bit depth? What is the rest of the code? Did you manage to make the DMD work anmother way (with Vialux codes)?

Sebastien

Member
Joined:
Posts: 4

Dear sebastien.popoff:
I am using the python control module for Vialux DMDs (V-6501) based on ALP4.3 provided in your github. I want control both a DMD and a Basler CMOS camera with python. I try to load a picture into DMD and then grab an image using camera as fast as I can and I repeat this process for a several loops. Here is the code I write:

import numpy as np
from ALP4 import *
import time
import cv2
from pypylon import pylon
'''
Initialize the camera device
'''
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
camera.Open()
'''
Initialize the DMD device
'''
DMD = ALP4(version = '4.3')
DMD.Initialize()
bitDepth = 1

img1=np.zeros(shape=(1080,1920))
img2=np.ones(shape=(1080,1920))
imgs=np.stack((img1,img2),axis=0)

'''
load image to DMD and grab with camera for loops
'''
grabResult_array=np.zeros(shape=(pic_num,Height,Width),dtype='uint8')
start=time.perf_counter()
for i in range(pic_num):
DMD.SeqAlloc(nbImg = 1, bitDepth = bitDepth)
DMD.SetTiming(illuminationTime=15000,pictureTime = 10000)
DMD.SeqPut(imgData = imgs[i%2].ravel())
DMD.Run(loop = True)
grabResult= camera.GrabOne(100)
grabResult_array[i]=grabResult.Array
grabResult.Release()
DMD.Halt()
DMD.FreeSeq()
end= time.perf_counter()
print(end-start)
camera.Close()
DMD.Free()
print('fps:',pic_num/(end-start))

It seems something gets wrong because I only get 27 FPS for 100 loops. Would you please give some advice for my code. I don’t know if it is right when I want to load a image into DMD and grab using camera for loops as fast as I can.
I would appreciate it if you could give some advice.

Administrator
Joined:
Posts: 73

Hi luwenjian,

I am not sure what you are trying to do, but it does not seem to be an efficient way to display sequences of image:
Instead of loading once your entire sequence, which is only two images, you load a sequence of one image at every single iteration of your loop.

The typical way is to load the entire sequence, and then run it.

DMD.SeqAlloc(nbImg = 2, bitDepth = bitDepth)
DMD.SeqPut(imgData = imgs.ravel())
DMD.Run(loop = True)

Your sequence of two images will then run continuously. In order to get your images synchronously, you need to trigger your camera with your DMD (use the cable that come with the DMD, look at the documentation). The trigger signal can be customized using the arguments of SeqTiming (namely illuminationTime, pictureTime, synchDelay, synchPulseWidth, and triggerInDelay).

That would be the most efficient way to use your system. Keep in mind that the DMD frame rate can be very fast, so if you use for instance a 10 kHz refresh rate, most likely your camera will not follow the pace. Adjust pictureTime accordingly.

Sebastien

Member
Joined:
Posts: 4

sebastien.popoff wrote:

Hi luwenjian,

I am not sure what you are trying to do, but it does not seem to be an efficient way to display sequences of image:
Instead of loading once your entire sequence, which is only two images, you load a sequence of one image at every single iteration of your loop.

The typical way is to load the entire sequence, and then run it.

DMD.SeqAlloc(nbImg = 2, bitDepth = bitDepth)
DMD.SeqPut(imgData = imgs.ravel())
DMD.Run(loop = True)

Your sequence of two images will then run continuously. In order to get your images synchronously, you need to trigger your camera with your DMD (use the cable that come with the DMD, look at the documentation). The trigger signal can be customized using the arguments of SeqTiming (namely illuminationTime, pictureTime, synchDelay, synchPulseWidth, and triggerInDelay).

That would be the most efficient way to use your system. Keep in mind that the DMD frame rate can be very fast, so if you use for instance a 10 kHz refresh rate, most likely your camera will not follow the pace. Adjust pictureTime accordingly.

Sebastien

Member
Joined:
Posts: 4

Thanks for you advice. I will try the trigger signal you mentioned. And also I wonder whether it is the right way to write code like I showed above when I want to display a single image in DMD for a single iteration loop.

Administrator
Joined:
Posts: 73

And also I wonder whether it is the right way to write code like I showed above when I want to display a single image in DMD for a single iteration loop.
No it is not, read my answer. You need to load your sequence once before displaying them continuously.

Member
Joined:
Posts: 4

Thanks for your advice. I used the trigger signal from DMD to trigger the camera and I can achieve synchronization of DMD and camera.

As you said I should load all the image sequence to DMD once. I noticed that the function DMD.Seqput() takes parameters of list, 1D array or 1D ndarray:

imgData : list, 1D array or 1D ndarray
Data stream corresponding to a sequence of nSizeX by nSizeX images.
Values has to be between 0 and 255.

If I want to load more then one images into DMD, Should I concatenate all images and ravel them to 1D array? Besides what is in the list if I use list data as DMD.Seqput() input.

Administrator
Joined:
Posts: 73

Please read the information on the Github page.
The minimal example I provided actually loads a two image sequence

# Binary amplitude image (0 or 1)
bitDepth = 1    
imgBlack = np.zeros([DMD.nSizeY,DMD.nSizeX])
imgWhite = np.ones([DMD.nSizeY,DMD.nSizeX])*(2**8-1)
imgSeq  = np.concatenate([imgBlack.ravel(),imgWhite.ravel()])

# Allocate the onboard memory for the image sequence
DMD.SeqAlloc(nbImg = 2, bitDepth = bitDepth)
# Send the image sequence as a 1D list/array/numpy array
DMD.SeqPut(imgData = imgSeq)
Member
Joined:
Posts: 1

Hi Sebastian,

I'm having exactly the same problem. May I ask how to synchronize the camera with the DMD? How do you use and modify the parameters like SynchDelay, TriggerInDelay? I went through the manual but still a little bit confuse. I'm considering using the DMD_Master mode and when the DMD is reaching the middle point of the IlluminateTime, I want the DMD to trigger out a signal to the camera so that the camera could catch an image. How does this relates to the parameters you mentioned above?

Really thanks.