Halcon - Extract straight edge from XLD - line

I have a XLD edge, like the one in red in the sample picture below.
I need to extract start/endpoint of straight lines that reppresent it. Hough lines sort of work for this, but the results are not really replicable. minor changes in the contour produce unexpected results.
How can the contours be extracted as straight lines? (blue) with start and finish coordinates?
lines shorter than a specified length should not be counted as separate line.

Contour needs to be converted to a polygon using the following function:
gen_polygons_xld (Object, Polygons, 'ramer', 25.0)
The only adjustable parameter is the alpha (25.0) which decides the approximation threshold.

Related

Halcon: Obtain how much is a mm in pixels after calibration

I've successfully calibrated my camera and I can get the dimensions of a XLD in world coordinates with ContourToWorldPlaneXld and then HeightWidthRatioXld. This returns me the measures of a contour extracted from a shape.
Now I need to convert a value inserted by the user in mm (example in mm: 0.1) and get how many pixels the measure is, for example, to draw a line.
I need the pixel value as per request. I tried looking around in the Halcon documentation but I didn't find what I was looking for.
Also I read this answer but it' not exactly what I'm looking for.
I'm using Halcon Progress 21.11.
Edit: A possible solution could be obtaining the dimensions before converting them to world plane and then do something like pixel/world but I would prefer a better method if it exists.

Inserting Upward Triangle In Mathtext String Matplotlib

I am using the function plt.text in Matplotlib to produce text within my plot. In addition, I am using Mathtext to bold a portion of the text string, as seen in this piece of code:
plt.text(0.01,0.32,fill(r"$\bf{Peaks:}$"+appended_text,57), ha='left',va="top", multialignment="left", fontsize=10.5, wrap=True)
Within my plot, I am currently denoting specific points with an filled upward triangle ("^" via plt.plot in Matplotlib), and would like to use this filled upward triangle symbol within the Mathtext bolded string above.
My initial approach was to try: r"$\bf{Peaks\ [^]:}$", however this simply moved the closed portion of the bracket as an exponential symbol.
Is there a way to replicate this filled triangle within Mathtext?
How would I use

Smoothly painting a path of straight line segments in Qt5

I have a series of straight line segments of varying thickness connected end-to-end to create meandering path. Does anyone know a way to paint this as a smooth meandering line, sort of like vectorizing it? I am using QPainter. I haven't had any success finding an appropriate function in QPainterPath.
The data looks something like this:
[(QPointF, width), (QPointF, width), (QPointF, width), ... ]
Thanks!
EDIT: Added example image
I wanted to leave it open to creative responses, but I am just looking to move from linear interpolation (QPainter::drawLine()) to spline interpolation.
If I understand your question correctly...
Don't draw a line, draw a filled polygon that encloses your line data with the right thickness. Drawback: That requires calculations on your data beforehand.

How do I fit a function to a candle plot TH2 in ROOT?

I've collected test data for a system and would like to fit a line to the linear portion of the system.
Here's my current plot, which is very barebones:
This was generated by drawing a TH2D with the CANDLE option, which gives nice error bars. However, neither of the two obvious TH2 fit options, both of which take slices and fit to slices, seems to be able to fit a line to this candle plot. The only clear solution I see is to make an array of TH1Ds corresponding to my X axis, filling them, then extracting their means and standard deviations and using those in a TGraphErrors plot, which makes fitting easy.
Is there a way to fit a line directly in the candle plot? If not, is there a more elegant solution than the one that I outlined above?

Interpolating data onto a line of points

I have some irregularly spaced data and need to analyze it. I can successfully interpolate this data onto a regular grid using mlab.griddata (or rather, the natgrid implementation of it). This allows me to use pcolormesh and contour to generate plots, extract levels, etc. Using plot.contour, I then extract a certain level using get_paths from the contour CS.collections().
Now, what I'd like to do is then, with my original irregularly spaced data, interpolate some quantities onto this specific contour line (i.e., NOT onto a regular grid). The similarly named griddata function from Scipy allows for this behavior, and it almost works. However, I find that as I increase the number of original points, I can get odd erratic behavior in the interpolation. I'm wondering if there's a way around this, i.e., another way to interpolate irregularly spaced (or regularly spaced data for that matter, since I can use my regularly spaced data from mlab.griddata) onto a specific line.
Let me show some numerical examples of what I'm talking about. Take a look at this figure:
The top left shows my data as points, and the line shows an extracted level of level=0 from some data D that I have at those points (x,y) [note, I have data 'D', 'Energy', and 'Pressure', all defined in this (x,y) space]. Once I have this curve, I can plot the interpolated quantities of D, Energy, and Pressure onto my specific line. First, note the plot of D (middle, right). It should be zero at all points, but it's not quite zero at all points. The likely cause of this is that the line that corresponds to the 0 level is generated from a uniform set of points that came from mlab.griddata, whereas the plot of 'D' is generated from my ORIGINAL data interpolated onto that level curve. You can also see some unphysical wiggles in 'Energy' and 'Pressure'.
Okay, seems easy enough, right? Maybe I should just get more original data points along my level=0 curve. Getting some more of these points, I then generate the following plots:
First look at the top left. You can see that I've sampled the hell out of the (x,y) space in the vicinity of my level=0 curve. Furthermore, you can see that my new "D" plot (middle, right) now correctly interpolates to zero in the region that it originally didn't. But now I get some wiggles at the start of the curve, as well as getting some other wiggles in the 'Energy' and 'Pressure' in this space! It is far from obvious to me that this should occur, since my original data points are still there and I've only supplemented additional points. Furthermore, some regions where my interpolation is going bad aren't even near the points that I added in the second run -- they are exclusively neighbored by my original points.
So this brings me to my original question. I'm worried that the interpolation that produces the 'Energy', 'D', and 'Pressure' curves is not working correctly (this is scigrid's griddata). Mlab's griddata only interpolates to a regular grid, whereas I want to interpolate to this specific line shown in the top left plot. What's another way for me to do this?
Thanks for your time!
After posting this, I decided to try scipy.interpolate.SmoothBivariateSpline, which produced the following result:
You can now see that my line is smoothed, so it seems like this will work. I'll mark this as the answer unless someone posts something soon that hints that there may be an even better solution.
Edit: As requested, below is some of the code used to generate these plots. I don't have a minimally working example, and the above plots were generated in a larger framework of code, but I'll write the important parts schematically below with comments.
# x,y,z are lists of data where the first point is x[0],y[0],z[0], and so on
minx=min(x)
maxx=max(x)
miny=min(y)
maxy=max(y)
# convert to numpy arrays
x=np.array(x)
y=np.array(y)
z=np.array(z)
# here we are creating a fine grid to interpolate the data onto
xi=np.linspace(minx,maxx,100)
yi=np.linspace(miny,maxy,100)
# here we interpolate our data from the original x,y,z unstructured grid to the new
# fine, regular grid in xi,yi, returning the values zi
zi=griddata(x,y,z,xi,yi)
# now let's do some plotting
plt.figure()
# returns the CS contour object, from which we'll be able to get the path for the
# level=0 curve
CS=plt.contour(x,y,z,levels=[0])
# can plot the original data if we want
plt.scatter(x,y,alpha=0.5,marker='x')
# now let's get the level=0 curve
for c in CS.collections:
data=c.get_paths()[0].vertices
# lineX,lineY are simply the x,y coordinates for our level=0 curve, expressed as arrays
lineX=data[:,0]
lineY=data[:,1]
# so it's easy to plot this too
plt.plot(lineX,lineY)
# now what to do if we want to interpolate some other data we have, say z2
# (also at our original x,y positions), onto
# this level=0 curve?
# well, first I tried using scipy.interpolate.griddata == scigrid like so
origdata=np.transpose(np.vstack((x,y))) # just organizing this data like the
# scigrid routine expects
lineZ2=scigrid(origdata,z2,data,method='linear')
# plotting the above curve (as plt.plot(lineZ2)) gave me really bad results, so
# trying a spline approach
Z2spline=SmoothBivariateSpline(x,y,z2)
# the above creates a spline object on our original data. notice we haven't EVALUATED
# it anywhere yet (we'll want to evaluate it on our level curve)
Z2Line=[]
# here we evaluate the spline along all our points on the level curve, and store the
# result as a new list
for i in range(0,len(lineX)):
Z2Line.append(Z2spline(lineX[i],lineY[i])[0][0]) # the [0][0] is just to get the
# value, which is enclosed in
# some array structure for some
# reason otherwise
# you can then easily plot this
plt.plot(Z2Line)
Hope this helps someone!