LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Increasing sub-VI size

Solved!
Go to solution

Hey there!

 

For my program I need a lot of image conversion and stuff like that. That requires me to get acces to all kinds of pixels and stuff like that.

The problem is this: because of this my program has become almost unreadable. Take this part for an example:

 

Labview small problem.png

As you can see here (ignore the text) the function get's a lot of input. But the lines have become almost untraceable. Sometimes when I want to check if something is right it can take way too long. What would be useful is if I could increase the size of that Replace Array-Subset function, I could place the incrementors and decrementors further apart and thus make it more clear to see. Is there anyway for me to increase the size?

0 Kudos
Message 1 of 16
(2,913 Views)

Most of those incrementors are coming out to the same value.  Just use a single incrementor and wire the result to all that need it.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 2 of 16
(2,886 Views)

That would be a solution to this situation yes, but I was hoping there is a possibility to increase the size of the function, instead of streamlining the program

0 Kudos
Message 3 of 16
(2,883 Views)

Looking at this code even closer.  You are changing the values of an array that is ALL ZERO.  And then you index out a element that you didn't change.  You will always have a 0 coming out of the Index Array.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 16
(2,880 Views)
Solution
Accepted by topic author Choisai

@Choisai wrote:

That would be a solution to this situation yes, but I was hoping there is a possibility to increase the size of the function, instead of streamlining the program


You can't resize the function in the manner you are talking about.  You should always be looking at streamlining your programs.

 

And work on cleaning up your wires and functions.  That will help you way more than being able to resize a function.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 5 of 16
(2,877 Views)

See, a little bit of cleaning up makes a huge difference in trying to read a LabVIEW program.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 6 of 16
(2,871 Views)

Well I was indeed hoping that the array would be all zero. I will explain this via a simple example of what my algorithm does. It actually a really, really simple algorithm, but it can be quite tricky to get into it.

I will give a detailed explanation and a very compact 'too long, didn't read' explanation (too long, didn't read is abbreviated as 'tl;dr').

 

 

This programs processes the pixel values of an image and calculates them to be a value between 0 and 1. This found value is then rounded to either a 0 or a 1. This rounding induces an error that must be diffused to surrounding pixels so the error can be corrected. The way I do this is by taking the array and processing the pixels one by one, from left to right, top to bottom. Because of this diffusion of errors, this algorithm is called the error diffusion algorithm.

 

An example:

Take a random image array that is for some reason incredibly small:

 

4 2 3 4

5 6 7 8

9 1 2 3

 

Now I am going to process that image.

The outcome must be binary, so it will be either a zero or a 1. Remember that the rounding to these values is the thing that induces the error.

 

So let's say that first value is calculated. The first value is the 4, and after will come the 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3. The first pixel get's a value of 0.6. That will be rounded to a 1. This has then an error of 0.4. This error must then be passed unto the surrounding unprocessed pixels (you can see in my program which ones).

 

I correct this error by diffusing it to pixels with the values 2, 6 and 5.

Now I didn't know how to do this. I still don't know how to pass this on to surrounding pixels. So what I did is I create an entire new array from which I can retrieve the error that was diffused to that pixel: that array is what I call the error array!

 

This array is filled with the errors of the calculations. So whenever I process an pixel, I calculate the value and then look at its coordinates. It has coordinate (x,y)? Then I retrieve from the error array the value that is stored at those same calculations.

This requires me to have an array that is exactly the same size as the image-array. So instead of initializing a new error, I take the image array and multiply it with zero. Then I start filling it up with the errors.

 

So let's go back to the example.

The first pixel, 4 got an error of 0.4. This error is then diffused to the 2, 6 and 5. Now because not all pixels are equally important and the error shouldn't be so dominantly present the 0.4 will become 0.1 for the pixel next to it and the others will become 0.2 and 0.3.

 

So we just calculated what the first pixel is supposed to be. Now we process the second pixel: the one with value 2.

We calculate that this pixel should have a value of 0.45. But now we look at can look at its coordinates within the image-array and use these coordinates to retrieve the error that was stored in the error array.

 

So to get an array that is exactly the same size as my image array I multiply it with zero. It now looks like this:

 

0 0 0 0

0 0 0 0

0 0 0 0

This is the error array from which I retrieve my errors!

 

Now after calculating the first pixel I get an error of 0.4 These are then 'corrected' themselves so they aren't as dominant. This gives us the following array:

0      0.1    0    0

0.2   0.3    0    0

0       0      0     0

 

This is our error array in its current state!

 

Now the second pixel was calculated to be 0.45. It is located at coordinates (x,y). We look at our error array and see that at these coordinates there is an error of 0.1. This error is added to it and it becomes 0.45+0.1=0.55. This is in turn rounded to 0.1 and it get's an error of 0.45. This value is then again corrected for dominance and diffused to our surrounding pixels (including the one down to left of it). So let's say the error gets corrected to 0.15, another 0.15 and 0.25 and 0.35 for the respective surrounding pixels. We then get for our error array:

 

0                  0.1                  0.25                 0

0.2+0.15    0.3+0.15        0,35                 0

0                  0                     0                       0

 

Our processed image array now looks like this:

 

1 1 3 4

5 6 7 8

9 1 2 3

 

The two bold numbers are the two pixels we already processed. Eventually the processed image array would look something like this:

 

1 1 0 1

0 0 0 1

0 1 1 1

 

In chart form the algorithm looks like this:

Error algorithm.png

t(m,n) = target value at pixel coordinates m,n. s(m,n) shaped value at m,n.

 

And these pixels are being processed in this order:

Dorrer and Zuegel processing.png

 

So to make clear, we have three arrays:

the incoming image array

The processed image array

The error array.

 

tl;dr?

This is the image processing in a nutshell

Incoming image array:

a b c d

e f  g h

i  j   k L

 

Calculate 'a' and add the error that was stored at location a in the error array. The pixel is calculated to be 0.35 and the error array currently looks like this:

 

a b c d           0 0 0 0

e f  g h * 0 = 0 0 0 0

i  j   k L          0 0 0 0

 

At location A in the error array a 0 was stored. Zero was added to the calculated value of 0.35. The 0.35 is rounded to be a ZERO. This rounding to zero induces an error of value n. This value is being corrected for how dominant it should be. For the sake of simplicity let's still call it n. This error 'n' is diffused to the surrounding pixels in the error array. The error array now looks like this:

 

0      0+n 0 0

0+n 0+n 0 0 

0      0     0 0

 

Calculate pixel B. Pixel B turns out to be 0.65. At location in the error array an error of n was stored. Pixel B therefore get's a value of B+n. This value is rounded to be 1. This induces an error of value m. This is then diffused to the surrounding unprocessed pixels. The error array then look like this:

 

0            0+n       0+m 0

0+n+m 0+n+m 0+m 0 

0            0            0      0

 

For pixel C we then have retrieve from the error array a value of m. And this goes on and on for all the pixels.

 

 

 

I chose to create a new error array instead of adding a 3rd dimension with errors to my image array because that would be too difficult. 

 

Now you said something that worried me: you said that this:

 

You will always have a 0 coming out of the Index Array

 

That shouldn't be the case: it should give me zero for the very first pixel, but after that the array should start to fill up with error inducements from processing pixels, as I have explained in this comment.

 

So feel free to elaborate on your comment. Thank you for your help and for the fact that you have already answered my question perfectly.

 

PS: My program is incomplete: the diffusion to surrounding pixels goes wrong at the edges, because there are then no pixels next to it or beneath it. I will add this later using case structures.

 

PPS: I have discussed my program in other Labview threads. At these points my program was incomplete and wasn't in its current state, so I was adressing other issues. To explain the context I made a couple of YouTube videos. You can watch them here if you want:

 

Realizing lexicographical processing:

https://www.youtube.com/watch?v=iZY6h3YM3gA

https://www.youtube.com/watch?v=h7pHnB3WPWE

 

Concerning the diffusion:

https://www.youtube.com/watch?v=pjoiBGN0OV0

https://www.youtube.com/watch?v=ZAQjy1pK6uo

https://www.youtube.com/watch?v=vRKxMoFssVw

https://www.youtube.com/watch?v=QJKyyN7JUDA

 

0 Kudos
Message 7 of 16
(2,854 Views)

@Choisai wrote:
[snip]

The problem is this: because of this my program has become almost unreadable.

[/snip]


Dear Choisai,

to increase the chances, that your problem will attract more people, I suggest that you create a "self-sustainable" VI with some default values for its controls. Self-sustaining (or self-sufficient) would mean that it can be run on its own without using external libraries or add-ons.

 

Could you please move the the IMAQ subVIs outside the while-loop? The data are coming from "IMAQ ImageToArray.vi", aren't they? Those can be created outside the while-loop and supplied to the self-sufficient sub-VI with the while-loop or within the while-loop (it's your decision). The other IMAQ subVIs are there for some pretty display -- not neccessary for sharing.

 

missing subVis.png

 

I would very much like to run your program to track the values and to think of possibilities for optimisation, but I'm not able for the reasons above.

 

For nicer layout, you can move the comments to the labels of the subVIs (or primitives) -- just make label for a primitive function visible and overwrite it with your comment.

 

GL! Cheers,

Message 8 of 16
(2,823 Views)

Hi there! It is strange for the IMAQ VI's to be unreadable as your screenshot suggests. I have the complete Vision module, so that might explain that.

 

But concerning the image array: I don't know if I can do that.

 

As explained above, I need to take the array of the image (which must be updated constantly) and process it. If I put the array of the image outside of my loop, doesn't that mean that the array will only be updated when I stop the program?

0 Kudos
Message 9 of 16
(2,802 Views)

Dear Choisai,

 

IMHO, you should rethink, which variables are neccesary to enter the while-loop, which variables are updated between the loops (using shift registers) and which variables are going to be send further as an output from the loop after the loop stopped (if any).

 

Now, I do not see that the output from "IMAQ ImageTo Array" is updated between the loops. You generate the 2D0array of I32 values every time with the same input parameters and you generate it within each loop newly -- a totally unnecessary waste of recources.

 

I would generate the array (output of the IMAQ ImageToArray) outside the loop, convert it to DBL (from I32), connect it to a shift register (from outside the while-loop). Then connect (probably?) the "DMD value" to the complementary shift register on the other side of the loop. I hope that make sense and I could help to you.

 

Cheers,

0 Kudos
Message 10 of 16
(2,776 Views)