04-25-2024 07:23 PM
OK, maybe I'm done now. I've got a .vim inside a .vim; but it seems to work OK.
04-25-2024 11:05 PM
@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?
04-26-2024 03:28 AM
@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):
04-26-2024 04:31 AM
04-26-2024 04:34 AM - edited 04-26-2024 04:40 AM
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):
Well, in this particular case we can "go down" to U8 right inside of vim:
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:
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):
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.
04-26-2024 09:49 AM
@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):
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.
04-27-2024 01:45 AM
@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:
I'm not sure I can go that far down the rabbit hole.
04-28-2024 04:15 PM
@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:
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.
04-28-2024 04:31 PM
@paul_a_cardinale wrote:
So my new problem is:
- 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.)
- 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.
04-29-2024 03:36 AM - edited 04-29-2024 03:42 AM
Wouldn't the U8 overflow?
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.