NUKE keyframes animation curve - animation

I'm parsing the NUKE software keyframe animation format. It's description is here: https://learn.foundry.com/nuke/developers/70/ndkdevguide/advanced/curveformat.html
It uses these numbers to define the curve. ("x" x-value) y-value ("s" l-slope) ("t" r-slope) ("u" l-angle) ("v" r-angle)
x,y,slope are fine, but I'm confused by the "angle". I'm assuming l and r refer to left and right side of the anchor point. The l-angle and r-angle seem more like a function of the length of the handle to me. It also seems like the maximum value is 3
Below are some examples with image (note, the grid in the images doesn't show units "correctly", but the slope values mean what you'd think they mean, they say how much increase in y per x value)
x40 399.5495605 s21.10000038 u3 v0.9411216378
Here's another example, note l-angle is still 3 (the maximum, but I had to decrease the slope)
x40 399.5495605 s5.900000095 u3 v0.9411216378
Another one:
x40 399.5495605 s6 u0.2508043051 v0.9411216378
And an example where l-slope and r-slope is different, neither u,v are provided, so per docs default to 1 (whatever that means)
x1 355 x40 399.5495605 s6 t-6.953211784
Anyone have ideas about what the "angle" values mean in this context? I'm trying to convert this format into the more normal bezier curve definition.
(I also posted this question in a NUKE forum: https://community.foundry.com/discuss/topic/160372/curve-serialisation-format)
EDIT: (about the grids not showing "correct units")

Related

Plumb bob camera distortion in Three.js

I'm trying to replicate a real-world camera within Three.js, where I have the camera's distortion specified as parameters for a "plumb bob" model. In particular I have P, K, R and D as specified here:
If I understand everything correctly, I want to set up Three to do the translation from "X" on the right, to the "input image" in the top left. One approach I'm considering is making a Three.js Camera of my own, setting the projectionMatrix to ... something involving K and D. Does this make sense? What exactly would I set it to, considering K and D are specified as 1 dimensional arrays, of length 9 and 5 respectively. I'm a bit lost how to combine all the numbers :(
I notice in this answer that there are complicated things necessary to render straight lines as curved, they way they would be with certain camera distortions (like a fish eye lens). I do not need that for my purposes if that is more complicated. Simply rendering each vertex is the correct spot is sufficient.
This document shows the step by step derivation of the camera matrix (Matlab reference).
See: http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/parameters.html
So, yes. You can calculate the matrix using this procedure and use that to map the real-world 3D point to 2D output image.

How to reduce 10k data points and show them on smaller display? Arduino

I‘m working on a visual data logger for my DMM, it writes every measurement to RS232 inteface. There I connect a Teensy 3.6 and collect the data points.
For each point I have the timestamp and the measured value. I will collect 10.000 readings.
I want to display the measured data on a display (800x480) in two ways. First as a rolling graph, that scrolls from right to left and shows the last minute or so. This is working fine.
Second, I want to display all collected measurements in total (max. 10k points). So I have to shrink or compress the data, but I want to preserve the shape of the curve.
To give you an idea how it should look like, please watch the video from Dave on EEV at YT (https://youtu.be/SObqPuUozNo) and skip to 41:20. There you see how another DMM is shrinking the incomming data and displays it. At about 1:01:05 10k measurements are shown on the display area of only 400px wide.
Question is, how is this done?
I’ve heard about Douglas-Pucker algorithm, but have no idea if this is the right way and how to use it on the Arduino/ Teensy platform.
Any help is very welcome, thank you....
I cannot just display all data points, because I‘m using an FT81x as display controller, and this can take only up to 2000 drawing commands per frame. And it takes more time.
Anyway, I solved the problem using the simple way.
I create bins and calculate the min and max values in this bin. Then simply draw a line between these points. Works fine!
BTW, I‘m the TO :-)
For cases where you got many more samples than pixels in x axis instead of LineTo like graph use vertical lines graph instead...
So depending on the number of samples per rendered time frame and x resolution you should compute ymin and ymax for eaxch x and render vertical line ...
something like:
xs=800;
for (x0=x,i=sample_left,y0=y1=sample[i],i<sample_right;i++)
{
x = (i-sample_left)*xs/(sample_right-sample_left);
y = sample[i]; // here add y scaling and offset
if (x0!=x) { line(x0,y0,x0,y1); x0=x; y0=y; y1=y; }
if (y0>y) y0=y;
if (y1<y) y1=y;
}
where sample[] are your stored values , sample_left,sample_right is the range to render and xs is graph x resolution. To speed up you can pre-compute the y0,y1 for each x and render that (recompute only on range or samples change) ... So as you can see you will use just xs line commands which shoul dbe fast enough. The x linear interpolation can be done without multiplication nor division if you rewrite it to integer DDA style ...
These QAs might interest you:
plotting real time Data on (qwt )Oscillocope
i don't really understand FFT and sample rates
[note]
After a second look The deleted answer is with the same approach as this (got deleted by review probably before the edit which transformed it from not an answer (comment) to the correct answer) so I voted for undelete even if it is considerably lower quality than mine but was posted sooner.

Accurate (and fast) angle matching

For a hobby project I'm attempting to align photo's and create 3D pictures. I basically have 2 camera's on a rig, that I use to make pictures. Automatically I attempt to align the images in such a way that you get a 3D SBS image.
They are high resolution images, which means a lot of pixels to process. Because I'm not really patient with computers, I want things to go fast.
Originally I've worked with code based on image stitching and feature extraction. In practice I found these algorithms to be too inaccurate and too slow. The main reason is that you have different levels of depth here, so you cannot do a 1-on-1 match of features. Most of the code already works fine, including vertical alignment.
For this question, you can assume that different ISO exposion levels / color correction and vertical alignment of the images are both taken care of.
What is still missing is a good algorithm for correcting the angle of the pictures. I noticed that left-right pictures usually vary a small number of degrees (think +/- 1.2 degrees difference) in angle, which is enough to get a slight headache. As a human you can easily spot this by looking at sharp differences in color and lining them up.
The irony here is that you spot it immediately as a human if it's correct or not, but somehow I'm not able to learn this to a machine. :-)
I've experimented with edge detectors, Hough transform and a large variety of home-brew algorithms, but so far found all of them to be both too slow and too inaccurate for my purposes. I've also attempted to iteratively aligning vertically while changing the angles slightly, so far without any luck.
Please note: Accuracy is perhaps more important than speed here.
I've added an example image here. It's actually both a left and right eye, alpha-blended. If you look closely, you can see the lamb at the top having two ellipses, and you can see how the chairs don't exactly line up at the top. It might seem negliable, but on a full screen resolution while using a beamer, you will easily see the difference. This also shows the level of accuracy that is required; it's quite a lot.
The shift in 'x' direction will give the 3D effect. Basically, if the shift is 0, it's on the screen, if it's <0 it's behind the screen and if it's >0 it's in front of the screen. This also makes matching harder, since you're not looking for a 'stitch'.
Basically the two camera's 'look' in the same direction (perpendicular as in the second picture here: http://www.triplespark.net/render/stereo/create.html ).
The difference originates from the camera being on a slightly different angle. This means the rotation is uniform throughout the picture.
I have once used the following amateur approach.
Assume that the second image has a rotation + vertical shift mismatch. This means that we need to apply some transform for the second image which can be expressed in matrix form as
x' = a*x + b*y + c
y' = d*x + e*y + f
that is, every pixel that has coordinates (x,y) on the second image, should be moved to a position (x',y') to compensate for this rotation and vertical shift.
We have a strict requirement that a=e, b=-d and d*d+e*e=1 so that it is indeed rotation+shift, no zoom or slanting etc. Also this notation allows for horizontal shift too, but this is easy to fix after angle+vertical shift correction.
Now select several common features on both images (I did selection by hand, as just 5-10 seemed enough, you can try to apply some automatic feature detection mechanism). Assume i-th feature has coordinates (x1[i], y1[i]) on first image and (x2[i], y2[i]) on the second. We expect that after out transformation the features have as equal as possible y-coordinates, that is we want (ideally)
y1[i]=y2'[i]=d*x2[i]+e*y2[i]+f
Having enough (>=3) features, we can determine d, e and f from this requirement. In fact, if you have more than 3 features, you will most probably not be able to find common d, e and f for them, but you can apply least-square method to find d, e and f that make y2' as close to y1 as possible. You can also account for the requirement that d*d+e*e=1 while finding d, e and f, though as far as i remember, I got acceptable results even not accounting for this.
After you have determined d, e and f, you have the requirement a=e and b=-d. This leaves only c unknown, which is horizontal shift. If you know what the horizontal shift should be, you can find c from there. I used the background (clouds on a landscape, for example) to get c.
When you know all the parameters, you can do one pass on the image and correct it. You might also want to apply some anti-aliasing, but that's a different question.
Note also that you can in a similar way introduce quadratic correction to the formulas to account for additional distortions the camera usually has.
However, that's just a simple algorithm I came up with when I faced the same problem some time ago. I did not do much research, so I'll be glad to know if there is a better or well-established approach or even a ready software.

Measure real object from image

I am going to prepare my assignment. It's a bit freaky as our Teacher, though :D. Okay, the job is simple. There will be a white cloth vertically. A person will be in front of that. Distance of the man from the cloth is 3 feet. The shadow of the person will be caught through a mid res (say 1600 X 1200) camera. The image (img01.jpg) of this camera is my input. I have to measure the man's body from the image, I mean parts of body. I need 80 to 90 percent accuracy. Desired output is some length (centimeter):
A = ?
B = ?
C = ?
D = ?
E = ?
Just as the picture:
I don't know what type of algorithm is needed here and I don't want to ask it to my freaky Sir. Great hearts here are requested to help me. Do not ask me for my code as I don't have yet. I don't need codes rather I need algorithms to do the job.
Thanks in advance.
Find the number of pixels between the points and multiply by the number of cm's per pixel based on how far the subject is from the camera.
A possible algorithm would be, given a vertical offset y, to find the distance (in pixels) between the first colored (or in your case, black) pixel and the last one, on the same line y. Then, you can use your unit conversion as you deem convenient, once you fix the scale between pixels and your real world measure. This answer would work assuming, as in your example, that the distance is measured horizontally and not diagonally on the figure.

Exploded view algorithm for CAD

I'm making a program to view 3D CAD models and would like to build in automated exploded views. All the assemblies that will be viewed are axi-symmetric. Some may not be, but the majority are. I'd like to figure out an algorithm for automatically moving parts in an assembly into an exploded view position. Here is an example of what I want to achieve through an algorithm (minus the labels of course):
The only value I have to work with is the center of the bounding box of each part. If more information than that is needed, I can calculate more information, but it seems like it should be sufficient. The rough approach I have in mind is to calculate a vector from the origin of the assembly to the center of each part along the axi-symmetric axis, then calculate a radial vector to the center of the part with respect to the center axis. From there, I'd need to figure out some calculation that would be able to scale the position of each part along some combination of those two vectors. That's the part where I'm not quite sure what direction to go with this. The image I've included shows the exact functionality I'd like, but I want to be able to scale the position by any float value to expand or contract the exploded view, with 1.0 being the original assembled model. Any ideas?
Your question is quite broad and thus my explanation became somehow lengthy. I'll propose two variants of an explosion algorithm for both axial and radial treatment.
To illustrate them with an example I'll use the following numbers (bounding boxes along the axis only, only five parts):
P1: [ 0,10] (battery)
P2: [10,14] (motor)
P3: [14,16] (cog)
P4: [16,24] (bit holder)
P5: [18,26] (gear casing)
While parts P1 to P4 exactly touch each other, P4 and P5 actually overlap.
The first one is an algorithm which basically scales the distances by a factor, such as you proposed. It will suffer if size of pieces is much different in an assembly but also for overlapping parts (e.g. in your example along the axis the extension of circle cog is much smaller than bit holder).
Let the scaling factor be f, then the center of each bounding box is scaled by f, but extension is not. Parts then would be
P1: 5 + [-5,5] => P1': 5*f + [-5,5]
P2: 12 + [-2,2] => P2': 12*f + [-2,2]
P3: 15 + [-1,1] => P3': 15*f + [-1,1]
P4: 20 + [-4,4] => P4': 20*f + [-4,4]
P5: 22 + [-4,4] => P5': 22*f + [-4,4]
The distance between the parts P1' to P4 is then given by
P2' - P1' : (12*f-2) - (5*f+5) = 7*(f-1)
P3' - P2' : (15*f-1) - (12*f+2) = 3*(f-1)
P4' - P3' : (20*f-4) - (15*f+1) = 5*(f-5)
As expected the difference is zero for f=0 but for any exploded view the distance strongly depends on the sizes of the separate parts. I don't think that this will look too good if variation of sizes is bigger.
Additionally for overlapping parts
P5' - P4' : (22*f-4) - (20*f+4) = 2*f-8
they still overlap for reasonable f.
Another possibility would be to define not a scaling factor for the axis but a constant part-distance d. Then bounding boxes would be aligned like the following:
P1': [ 0,10]
P2': [10,14]+d
P3': [14,16]+2*d
P4': [16,24]+3*d
P5': [18,26]+4*d+6
Note that in the last line we added 24-8=6, i.e. the overlap in order to differentiate the two parts.
While this algorithm handles the above mentioned cases in a (in my opinion) better way we have to add special care to parts which cover multiple other parts and should not be included in the grouping (e.g. handle top in your case).
One possibility would be to group the parts into groups in a first step and then apply the algorithm to the bounding box of these groups. Afterwards it can be applied to parts in each group again, omitting the parts which cover more than one subgroup. In your case it would be (note nested grouping is possible):
[
([battery,(switch,circuit switch),motor],handle top),
motor cog,
tri-cog,
red-cog,
circle-cog,
bit-holder,
(gear casing,spring,lock knob)
]
You might see that I have introduced two different kind of groups: parts/groups in square braces are handled by the algorithm, i.e. a spacing is added between each part/subgroup inside such a group, while the groups inside round braces are not exploded.
Up to now we did not handled the radial explosion because it nicely decouples from the axis treatment. But again the same both approaches can be used for radial explosion also. But again in my opinion the second algorithm yields more pleasant results. E.g. the groups can be done as follows for radial treatment:
[
(battery,switch,<many parts>,gear casing),
(switch,spring),
(handle top, lock knob)
]
In this case we would add an additional component r to all radial centers in the second group and 2*r to all in the third group.
Note that the simple scaling algorithm runs without special user guidance (once the scaling factor is given) while the second one uses additional information (the grouping).
I hope this rather long explanation gives you some ideas how to proceed further. If my explanations are unclear at some point or if you have further questions please feel free to comment.

Resources