Migrating from 0.30 to 0.31¶
0.31 is mostly additions — open polylines, boundary distances, coverage matching, header metadata from paths. The breaking changes are a removed spelling, one default that now reports "unknown" instead of a guessed value, and inputs that used to be silently mis-measured and are now read as written or refused. This page lists what to check coming from 0.30; the changelog has the full list.
Removed¶
extract_contours(mode="tree"): it ran exactly asmode="all"while documented as a hierarchy, which nothing builds. Usemode="all";"tree"is refused like any unknown value.
Results that change¶
froc_auc is null where fp_range leaves the curve. A FROC curve stops
at the highest FP/image any threshold reaches. froc_auc used to fill the
curve flat past that point (while froc_summary_table reported null there),
which for thresholded-mask detections gave an AUC close to the curve's
maximum sensitivity. Every FROC/LROC curve reader now takes one
extrapolate= policy, "none" by default. Pass extrapolate="flat" for the
previous value (the LUNA16 np.interp convention), and report
froc_operating_range(table) alongside to show how far each curve reaches.
LROC values are unchanged.
is_closed=False is read. The field was written True and ignored, so a
contour with is_closed=False was measured as the ring its closing edge would
make. It is now an open polyline: boundary functions (perimeter, distances,
nearest point, Hausdorff, transforms) measure it as a line, and region
functions (area, centroid, iou, contains_point, rasterize, …)
refuse it, naming the row. Contours with is_closed true, null or absent
are unaffected. If you wrote False meaning a region, write True — or
close the line along the image frame with .contour.close_along_border.
CORRESPONDENCE_SCHEMA has a third field, duplicate: List(Boolean).
Code that compares the struct's dtype to a hand-written two-field struct, or
unnests it into a fixed set of columns, needs the new field.
Newly refused¶
These used to produce a silently wrong result:
PreMatchedAdapterrequiresclass_colwhen the detections orimage_metacarry aclass_idcolumn (the class key was dropped and every join matched nothing), and raises on a namediou_col,weight_col,det_idx_col,n_gts_col,gt_label_colorgroup_colthat is missing (it fell back to a default). Withoutiou_coltheioucolumn is null andat_iou_threshold/mean_average_precisionraise.ContourMatcher(score_col=...)with a heatmap prediction is refused; it was accepted and ignored.score_colnow scores contour predictions.- A
file://URL naming a host (file://server/data/a.png) is refused by every path reader. It named no local file, and underallowed_rootsthe check and the read resolved it differently, so it could read outside the allowed roots. Writefile:///absolute/path. A percent-encodedfile://URL is now decoded (%20reads as a space). close_along_borderrefuses a NaN or negativemax_snapand a non-finite frame size;point_from_coords/contour_from_coordsrefuse a NaN or infinite coordinate (every geometry reader already did).
Behaviour worth knowing¶
- A sourceless
Pipeline()continues any domain. Its first op now anchors it, socontours.pipe(Pipeline().simplify(2.0))works ascontours.simplify(2.0)does. - A one-row geometry operand broadcasts, as a per-row parameter does: a bbox or point built from literals no longer fails with "row 1 out of bounds".
.cv.width()/height()/channels()/image_dtype()take path columns, reading a local file only as far as its header;.cv.read_bytes()first is no longer needed for metadata.