问题
I am trying to compute a panoramic projection for dental imaging purpose.
I have a rectangle surface "curved" in one direction by a piecewise function. If we look at it from the top, it looks like a regular piecewise function.
The "piecewise linear function" is just defined by a set of 3D points. All the points are in the same plane. The plane where all the 3D points sit is orthogonal to the curved surface
(see the green line in the top-left window)
I am looking for the proper way to "flatten" it. (non linear transform)
The flat surface should have the same "length" as the curved one. (it is not a classic orthogonal projection)
Ultimately, I will use the "flat surface" as a canvas to display the information of interest.
(Bottom window)
Best,
回答1:
I see it like this:
I would:
- take 3 consequent points
P0,P1,P2
from your curve compute
U0,V0,U1,V1
U0 = P1-P0 U1 = P2-P1 V0 = cross(U0,(0,0,1)); V0=half_height/|V0| V1 = cross(U1,(0,0,1)); V1=half_height/|V1|
so
A,B
is justP0 +/- V0
andC,D
isP1 +/- V1
. In the cross product Use any vector non parallel withU0,U1
I chose(0,0,1)
but in case it si parallel chose any other...make the
ABCD
a recangleSo compute
A'B'C'D'
for exampleA'.x = B'.x = index_of(P0) * sizex C'.x = D'.x = index_of(P0) * sizex + sizex A'.y = D'.y = sizey B'.y = C'.y = 0
Where
sizex,sizey
is the size of rectangle segment. You can also use|U0|,|V0|
but in that case the startx
will be integrated curve length.compute transformation between
ABCD
andA'B'C'D'
so for each pixel P inside
ABCD
compute(x,y)
insideA'B'C'D'. The
x` is easy:x = A'.x + dot(P-P0,U0)/|P-P0|
y
is tricky and need some tweaking to suite your needs (so the result is smooth to your liking). For starters try simple approach (will lead to seams between segments)y = (A'.y+B'.y)/2 + dot(P-P),V0)/|P-P0|
Now just copy the pixel at position
P
into your target image at position(x,y)
To make this more smooth you can make
V
interpolated betweenV0,V1
dependent on thedot(P-P0,U0)/(|P-P0|*|U0|)
so it will change seamlessly.t = dot(P-P0,U0)/(|P-P0|*|U0|) V = V0 + (V1-V0)*t y = (A'.y+B'.y)/2 + dot(P-P),V)/|P-P0|
If you need help with determining if point is inside then pixel
P
is inside ifdot(P-P0,U0)/(|P-P0|*U0) = <0.0,1.0>
loop #1 for all segments of the curve
step by single sample point of curve (not by 3 ...)
来源:https://stackoverflow.com/questions/44407591/flatten-curved-surface