LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

IMAQ image rescale to 50% by averaging 2x2 ?

I want to resize an image to 50% so it has half the original X and Y dimensions. I want each output pixel to be the average of an input 2x2 pixel block. If I use IMAQ Resample, as I understand it, it simply downsamples, by copying a single pixel out of the 2x2 region with no averaging. I think I could do it if I use IMAQ Extract 2 four different times, with X step and Y step size = 2 and with the Optional Rectangle upper-left corner set to (0,0), (0,1), (1,0), (1,1) respectively, and then divide each pixel value by 4, and add the four images together for the final 2x2 averaged-pixel image.

 

I need real-time (30 fps) performance and I suspect that operation will be inefficient unless implemented at a low level. Is there a better way to do this?

 

The original color camera image is 2048 x 2048, and I want 1024 x 1024.

0 Kudos
Message 1 of 7
(4,733 Views)

Your pure IMAQ-based suggestion may work fast enough but you may get away with a pure LabVIEW array manipulation approach.

 

I've tried to implement your feature in LabVIEW using 2D_U8 arrays (see attached sub-VI) and the operation itself takes approx 10-12 ms for a 2kx2k array on an older desktop machine. The conversion from IMAQ Image to/from Array will add some overhead but I haven't tried how much.

 

Is this an option for you?

 

Message 2 of 7
(4,684 Views)

Just be careful with rounding and overflow.  If you shift by -2 (divide by 4) first, then you lose some information (four values of 255 will average to 252 for example).  If you add then divide, then you need to worry about overflow.

 

I think the best approach for 2x2 binning, which is also pure IMAQ is to convolve the image with a kernel that has 4 ones in the lower-right, and then extract every second pixel:

 

2x2Binning.png

 

This handles the precision/rounding and overflow correctly. On my machine this takes 4ms for a 2048x2048 image (vs 7ms for extracting 4 images and averaging, and 18ms for LocalDSPs method including image-array and back again), so it is fastest despite computing the convolution at all pixels, not just 1/4 of them.  I did just notice that you say you have color images, so you will need to process each plane separately.

 

Note: I had thought that IMAQ Resample with Bilinear interpolation might work, and it is close but not exactly the same result.

Message 3 of 7
(4,665 Views)

Good day! Can someone suggest how to modify the code given above by GregS for averaging areas with an arbitrarily given size, i.e. not only 2х2, but also for 4х4, 8х8 or 16х16 (and so on). I tried to play around with the kernel array of IMAQ Convolute and with the constant for parameters Y Step Size and X Step Size of IMAQ Extract 2 to make it work for 4x4 size, but I did not find any solution. The knowledge of mathematics of this transformation is needed here, which I do not have enough, I think. Can someone help me with that?

 

First of all, three additional sizes are of greatest interest for me: 4х4, 8х8 and 16х16 (or even any arbitrary size equal to the power of 2, if someone can make this). But if it is possible to realize truly any arbitrary size (for example, 2x2, 3х3, 5х5, 6х6, 7х7, 8х8, 9x9 and so on), then it would be even better. 🙂

 

It will be also excellent if someone can make the code from LocalDSP working for any Input 2D Array Size (not only 2048) and any averaging (binning) size (as I mentioned above not only 2x2, but also 4x4, 8x8 and 16x16... or even all possible sizes 3x3, 4x4, 5x5, 6x6, 7x7, 8x8, 9x9 and so on).

0 Kudos
Message 4 of 7
(4,420 Views)

I have attached the VI (for LV versions 2015 and 8.5) that I build using the code from GregS and LocalDSP (and screenshots). By the way, the part given by LocalDSP is not working properly at all, because its results are wrong (I don't investigate at this time why). The version 8.5 is autogenerated by LV (saved from v2015), so there are some inaccurate front panel elements. Main version is 2015.

 

Screenshot 1.png

 

Screenshot 2.png

0 Kudos
Message 5 of 7
(4,408 Views)

Firstly, if you want powers of 2, you can just reapply the 2x2 binning to the results, although the answers may not be so accurate if you have integer values, but should be fine if your images are SGL.

 

Modifying the code for 4x4 binning is not too hard:

4x4Binning.png

This can be generalised to NxN binning, but you need to be sure that the Border of the Image is large enough for the convolution operation:

NxNBinning.png

 

A different approach for NxN binning works by extracting N images and averaging them (so it doubles the memory used):

NxN Binning.png

You may want to be careful when the image size is not a multiple of N.

Message 6 of 7
(4,390 Views)

I am very grateful for the help, dear Greg! 🙂

Your experience with Labview and knowledge of some mathematics behind the screen of its VIs is really amazing. )

0 Kudos
Message 7 of 7
(4,386 Views)