LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Interpolate Pixel

OK, maybe I'm done now.  I've got a .vim inside a .vim; but it seems to work OK.

Download All
Message 71 of 95
(241 Views)

@paul_a_cardinale wrote:

OK, maybe I'm done now.  I've got a .vim inside a .vim; but it seems to work OK.


Nice usage of malleable VIs, thank you for sharing! Now I'm just curious — how complicated would be to "extrapolate" this to Bicubic, Spline and in the ideal case to Lanczos interpolations?

0 Kudos
Message 72 of 95
(228 Views)

@paul_a_cardinale wrote:

OK, maybe I'm done now.  I've got a .vim inside a .vim; but it seems to work OK.


I'd also make the VI return the interpolated value. If it's not used, it's removed by dead code elimination. AFAIK, in the .vim, returning both the index and value comes at no cost. 

 

Why convert the fractional index to integer in the interpolation VI? It calculates a nice fractional index (like LV's function), that could be useful. If user wants it to be an integer, converting the fraction costs the same as doing it in the .vim.

 

But if you do want to convert it, why not convert it before adding (for a tiny bit of speed, but mostly because of clarity):

wiebeCARYA_1-1714120038758.png

0 Kudos
Message 73 of 95
(218 Views)

Thanks Paul for this beautiful expression about getting older.

greetings from the Netherlands
Message 74 of 95
(205 Views)

wiebe@CARYA wrote:

But if you do want to convert it, why not convert it before adding (for a tiny bit of speed, but mostly because of clarity):

wiebeCARYA_1-1714120038758.png


Well, in this particular case we can "go down" to U8 right inside of vim:

Screenshot 2024-04-26 11.24.22.png

This also will work (hopefully without rounding errors, at least my quick test passed). Two additional changes — compound arithmetic and (surprisingly) adding array elements instead of scalars:

Screenshot 2024-04-26 11.25.04.png

In theory working with arrays should be slower, because of allocation, but with these changes above I see around 3% better performance (on the Mac and other LV version could be different, of course):

Screenshot 2024-04-26 11.25.41.png

Technically for array sum NI calls a function (I guess), this could be slightly more efficient rather than single adds in compound arithmetic also with additional overhead from allocation and call itself.

 

0 Kudos
Message 75 of 95
(202 Views)

@Andrey_Dmitriev wrote:

wiebe@CARYA wrote:

But if you do want to convert it, why not convert it before adding (for a tiny bit of speed, but mostly because of clarity):

wiebeCARYA_1-1714120038758.png


Well, in this particular case we can "go down" to U8 right inside of vim:


For me an index is almost always an I32.

 

Making it a U8 will usually cause a coercion when using it as an index. 

0 Kudos
Message 76 of 95
(250 Views)

@paul_a_cardinale wrote:


Mostly I'll use it in a tool that applies a certain type of distortion.  Each pixel on the output maps to non-integer pixel coordinates in the original.  Currently it just picks nearest neighbor; and in most images that works very well, but sometimes odd aliasing is visible.  I'm sure that ignoring gamma and merely interpolating RGB values would work well with most images, but I wonder if artifacts would be visible where there are steep gradients.

 


I have discovered that, unfortunately, the aliasing that I have observed is caused not by nearest-neighbor-interpolation, but rather by the manner that I'm applying the distortion.  The way I'm doing it is, for every pixel in the output image, apply the inverse distortion to that pixel's coordinates, yielding fractional coordinates into the original, then interpolating.  The problem is that I'm only calculating from the center point of the output pixel, not the entire area of the pixel.  The consequence of that is that data from some pixels in the original doesn't get mapped to the output; it just gets lost.

For example, suppose that in the output image, pixel [n,20] gets mapped from [n,8.5] in the original, so its value comes from [n,8] and [n,9].

Then pixel [n,21] maps from [n,11.5]; so the value comes from original pixels [n,11] and [n,12].  But the value from original pixel [n,10] never gets used.

So my new problem is:

  1. Apply the distortion: For each pixel in the output image, transform the coordinates of the 4 corners of that pixel to coordinates in the original (inverse distortion).  (This part is easy.)
  2. Interpolate a pixel: From that set of 4 fractional coordinates (which define a quadrilateral in the original pixmap), calculate the color based on all of the full pixels and fractional pixels encompassed by that quadrilateral.  (Seems hard.)

I'm not sure I can go that far down the rabbit hole.

0 Kudos
Message 77 of 95
(228 Views)

@paul_a_cardinale wrote:

@Andrey_Dmitriev wrote:

One thing I don't understand. Why are you struggling and fighting with slow LabVIEW code, on  the limits of optimization, and not switching to a DLL-based solution?  


I do most of my imaging work on a Mac.


This weekend I've completed an experiment — how to call a Library on macOS. I just installed Sonoma 14.4.1 and "The Last of the Mohicans" LabVIEW 2023 Q3 into a Virtual Machine and was able to get things done (with both gcc and Xcode). It's really not so complicated and in some points more easy than on Windows.
Anyway, the benchmark demonstrated over a 100x performance boost — where the LabVIEW needs 8 seconds, the library — 70 milliseconds only:

 

Screenshot 2024-04-28 22.27.34.png

But such test under the Virtual Machine, where I have only 3 CPUs (like my three-cylinder car) and 6 GB of Ram assigned, could be totally different on a real Mac. You can try if you want — the source code is attached, and my Dev Notes about this experiment (if you need to recompile or modify C code) are here —  macOS LabVIEW Experiment — Call Library Function. I'm too lazy to add "gamma == 1" particular case, but this is trivial.

Message 78 of 95
(177 Views)

@paul_a_cardinale wrote:

So my new problem is:

  1. Apply the distortion: For each pixel in the output image, transform the coordinates of the 4 corners of that pixel to coordinates in the original (inverse distortion).  (This part is easy.)
  2. Interpolate a pixel: From that set of 4 fractional coordinates (which define a quadrilateral in the original pixmap), calculate the color based on all of the full pixels and fractional pixels encompassed by that quadrilateral.  (Seems hard.)

 


May be OpenCV Remap will help you in this case (as an idea). I've used this in the past for classical Lens Distortion correction (based on dot pattern grid), it works.

0 Kudos
Message 79 of 95
(170 Views)

Wouldn't the U8 overflow?

wiebeCARYA_0-1714379697323.png

Adding 4 U8 will only fit an U8 if the input U8's are 6 bit...

 

If the value really is an U8, you could make a real LUT, using the U8 as an index in the table. Interpolating is expensive... Even a LUT with an U16 index will be fast, but an I32 will be impractical.

0 Kudos
Message 80 of 95
(147 Views)