LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Save Sequence Images with a given timing

Solved!
Go to solution

Hi Emanuele,

 

I take issue with a couple of points in your response, which are not LabVIEW related.

 

I understand you're new to LabVIEW.  Please don't get upset when I gently criticize you...notice that I also paid you several compliments, and I meant them.  You are smart.  You're doing a good job.  When you want to try something new, first write down the process, in words.  After you do that, you can work on coding it up in LabVIEW.  Then, if you're not sure which functions to use to code it, we can help you.  Does that make sense?  I felt you were capable of figuring out that process (of saving every n-th image) by yourself, even if you didn't know how to code it up.  I want to see you write down the process for what you want to do, then we can figure out how to implement that process in LabVIEW.

 

So now let's talk about the time it takes to do things.  You mention that it takes a lot of time for you to straighten out your wires.  I have mentioned twice that straightening out the wires will make the block diagram easier to read.  Are you unwilling to invest that time?  It appears that you are.  Yet you want me to invest my time, and quickly, to help you as soon as I can.  That doesn't seem right. 

 

On to your problem.  I'm going to try a different approach:  I'm going to write out my problem-solving process (with pictures) so you can see it, which will perhaps provide you with an approach to use in the future.  I'll probably break it up into a few posts to make it easier to read.  Here we go.

 

Step 1:   The error message.

 

Here's something pretty cool that you can do in LabVIEW to find out more about an error message.  Place an "error out" cluster on the front panel.  Type in the error code.  Then right-click and select "explain error".  See image below.

explain error.png

 

When I did that for your error code, I got the following explanation:

IMAQ error code.png

 

Will continue in the next post...

Message 11 of 69
(2,083 Views)

Continuing on.  OK.  So what do we know?  We know which function originated the error -- IMAQ Bayer Color Decode -- and we know what the error means (Not an Image).

 

When we look at the function that originated the error, we see that it has two image inputs:  Source Image and Destination Image.  So it seems clear that there is a problem with one of those inputs.  Sooo...

 

Step 2.  Open the help file for the function which is causing the error.

 

We pull up the help file for the function by right-clicking on the function and selecting "Help", as shown below.

open function help.png

 

The help file for that function pops up.

 

Step 3.  Read the help file for the function.  Since we know that the problem is most likely with one of the image inputs, let's pay special attention to the descriptions of those inputs:

 

Bayer decode help file.png

 

Here we note that the Destination Image MUST be an RGB 32-bit image.  Is it? 

 

Next post...

 

0 Kudos
Message 12 of 69
(2,082 Views)

Looking at the source for our Destination image, we find the following:

 

destination image source.png

 

See the red dot going into the "IMAQ Create" function?  That's a coercion dot.  What it means is that the input to the function is not exactly the same as the datatype expected at that input.  So, we see "RGB", but we haven't specified that it's a RGB 32-bit image.  So:

 

Step 4.  Look at the help file for "IMAQ Create" and see what that input is supposed to look like.

 

IMAQ Create help.png

 

Aha!  It's different!  Let's try specifying that input as RGB U32:

 

destination image source new.png

Now we can be pretty sure that the destination image source has the correct format.  After making those changes, run your VI again.  If we get the same error, what does that tell us?

 

It tells us that maybe we need to follow the same process for the source image to make sure that it also has the correct format.

 

I hope that seeing the troubleshooting process will help a little bit.  I don't have your hardware so I'm not able to run your VI and reproduce your problem...I can only suggest a process that you can try to follow yourself.  You can also use execution highlighting -- that little lightbulb in the top left-hand corner of your block diagram, near the "run" arrow -- to watch your code execute.  That can be really handy.

 

One final thing:  in your bottom loop, you need to use a shift register for your counter, the way I showed you in the counter VI I posted.  The shift register is the blue triangle (one is an input and one is an output).  Your counter will not work unless you use a shift register.  Right-click on the tunnel (the one with the "0" wired to it) and select "replace with shift register".

 

Ok, hang in there and keep at it.  Oh, and 2 hours is not a lot of time to spend troubleshooting something.  Some problems can take days to track down, even for experienced programmers.  Smiley Happy

Message 13 of 69
(2,081 Views)

Dear Diane,

 

thank you, you're very kind to show me those interesting LabView features, I appreciate it a lot!

 

After trying different things, I found that the problem was related to the fact that in the False part of the case structure I inserted a rubbish bin to delete the image, and this caused the problem that stopped my acqusition: now it seems to be working.

I have modified the program again because I want to give the images names with successive integer numbers, and in the program I wrote before the index from which I was building the name was continuoisly updating in the loop cycle, and so I didn't get successive numbers in the saved image names. In addition, these numbers were not even multiple of 5, probably because the while loop index was going faster than the dequeing process... I don' t know, but it was not what I wanted.

Now I've decided to put the case structure in the producer loop, so that I only enqueue the images I want to save, while I display all of them. Does this seem a better solution to you?

However,if I set acquiring rate 20 fps and saving rate 5 fps and I record 10 seconds measured with my watch, when I stop the program I don't have 50 images (or about 50, as I'm not so precise in stopping the acquisition), but I have about 25-30 images... May it be due to the fact that, when I stop the program, it also stops the saving process and doesn't save the remaining enqueued images?

Please let me know if you can give me some hints on how to fix this hopefully last issue.

Tha new VI is attached.

 

Thank you again very much.

 

Emanuele

0 Kudos
Message 14 of 69
(2,070 Views)

Hi Emanuele,

 

I am very proud of you for finding the problem and getting your program working again.  Congratulations!

 

Putting the case structure in the producer loop is more-or-less exactly the same as putting it in the consumer loop -- you're still using the same logic to determine when to save.  So either will work just fine.  The way you have it now is working, so it probably makes sense to leave it that way.  Right?

 

I can think of a few reasons why you might not be saving the number of images you expect:

 

1.  You are quite right, it's very possible that your lower loop is terminating when you still have data in your queue, and of course that data won't be written to file.

2.  Your timed loop may be taking longer than you think to execute, so you are capturing fewer images than you think you are.  As you'll recall, I've mentioned in previous posts that you could run into exactly this problem.

3.  If your frame rate is 20Hz and your save rate is 5Hz, you expect to save 4 images / second, not 5 (20/5=4).  Therefore, after a 10 second run, you would expect 40 images saved, not 50.

 

Ok.  So you're not as far off as you think you are, but you're still off.  So how do we determine where the problem is?  Right now we don't know whether the problem is possibility #1 -- your lower loop is terminating when your queue still contains data -- or possibility #2 -- your timed loop isn't executing at the rate you expect.

 

Let's start with the queue, and see whether there are any queue functions which might give us some additional information.

 

Here's the queue palette...and hmmm, I wonder what "Get Queue Status" does.  That seems like it might be helpful.

 

queue palette.png

 

Look at the help file for "Get Queue Status".  I think you'll find that to be a very handy function.

 

After you read the help for that function, ask yourself the following questions:

 

1.  What kind of information does that function give me?

2.  How might I use that information to answer the question, "Is my consumer loop stopping even though there's still data in the queue?"

3.  If that is what's happening, how can I use that information to prevent my loop from stopping until all the data is processed?

 

Ok, I'm going to let you take it from here.  Smiley Happy

 

 

 

Message 15 of 69
(2,068 Views)

Dear Diane,

 

I used the queue status function and it always returns the values 0 as number of elements in the queue, does this mean that the queue is continuously emptied?

In any case, I recorded a series of images in which I inserted my hand in the frame at the end of the acquisition, and the image of my hand is just in the last saved images. So I'm almost certain that the problem is the timing: how can I make sure that I acquire images at exactly the requested timing?

 

The save rate should be independent on the display rate, so of I decide to save at 5Hz, then I should have to save 5 images per second, 4 is the counter value, meaning the number of images that the program has to discard between two successive image saving.

 

I have also tried to use a while loop with the function Wait ms inestead of the timed loop, but it doesn't work properly anyway...

0 Kudos
Message 16 of 69
(2,059 Views)

or maybe the problem is just how many images the program has to skip, probably it's there...

because for the moment it looks like it skips an image more than it should... so that might cause a mismatch... maybe I have to subtract 1 to the value of the saturation index for the counter...

0 Kudos
Message 17 of 69
(2,054 Views)

Hi Emanuele,

 

Yes, if the number of items in the queue is always zero (I trust that you put "Get Queue Status" in your consumer loop), then that means the consumer loop is keeping up with the producer loop.  In other words, you're not losing data when your consumer loop is terminating.

 

Let's take a look at your code again -- just the producer part -- and write out in words what it's doing, in order to understand what might be going on here.  I am looking at "Image Grabber Saver 2", which I believe is the most recent one you posted.

 

1.  You initialize a session using "IMAQ Init"

2.  You configure a list using "IMAQ Configure List".  You set the acquisition mode to "continuous" and the number of buffers to "1".  So your list contains only 1 buffer.

3.  You obtain an image type for use by "IMAQ Create".

4.  You configure your single buffer using "IMAQ Configure Buffer".

5.  You start the image acquisition using "IMAQ Start".

6.  Inside your loop, you use "Copy Acquired Buffer" to copy an acquired buffer from system memory space.  You increment the number of the buffer to grab, but you only have one buffer, so I'm not sure how this function is working, precisely.

7.  You use "IMAQ Bayer Color Decode" to produce an RGB image.

 

So it seems like there could be a few problems here, again.  First of all, you only have one buffer.  I don't know if that buffer gets overwritten with each acquisition, or what, but if it does, that could explain why your saved images aren't what you expect.  If the buffer does not get overwritten with each aquisition, then all of your images should be mighty similar to each other...since you will have only captured one image and you're just accessing that image again and again.  I don't know precisely what's happening in this case, and I don't have any hardware so I'm not able to help you find out.  You'll have to do that yourself.

 

How do you have your camera configured in MAX?  Is it configured to capture 20 frames / second?  What kind of camera are you using?

 

I think you're going to have to alter your approach somewhat.  Did you look at the "IMAQ Sequence" function?  Would you consider grabbing all of your images and post-processing them instead of trying to grab and process them one at a time?

 

Have you searched the forum, specifically the Machine Vision forum, for information?

Message 18 of 69
(2,051 Views)

You might look at this discussion.

 

Searching the forum can be very useful.

0 Kudos
Message 19 of 69
(2,048 Views)

Dear Diane,

 

I read the topic you posted the link of, and I have got that, as you also said in one of your previous messages, it's very hard to acquire images at a given precise frame rate using software timing control.

My camera is a Basler camera, it's not very recent but it works fine for my purposes. It's possible to set the frame rate by means of a software, Camer Configuration Tool, provided by Basler.

I can set up my camera using this software. Provided that I'm able to set the camera frame rate by means of it (this is of course something about which you can't help me as you don't have the hardware), how can I then make sure that that is the frame rate at which also the producer loop works? Because I also need to take into account some processing time both for the bayer deconding and for discerning whether the image has to be saved or discarded.... probably I have to set a timing in the prodeucer loop as well, but now I'm not confident anymore on the software timing. This is because I've also tried to make several acquisitions for 10 seconds, changing the frame rate and saving rate. And sometimes for the same parameters the programs returns a different number of saved images.

I'm really stuck and I couldn't fine any other help from the forum, this seems a very tricky issue... can you give me some advice on how to go on?

Thank you again

 

Emanuele

0 Kudos
Message 20 of 69
(2,040 Views)