Package: boxobj
boxoboxois a simple library that makes working with computer vision, OCR, and other tools that interact with regions
of an image or document, simpler and more predictable.BoxThe core class in this library isBox. It handles many of the common approaches that different
libraries use to reference the region containing the returned results including:coordinates:[x1, y1, x2, y2]a dict containing thepositiondefined bytop,left,width,heightrelativecoordinatesorpositiondefined as a percentage of the size of the source:[0.2, 0.5, 0.3, 0.8]In addition, it supports conversion frombottom indexedboxes like those used in older file types and libraries
such as PDFs.Box internally represents its coordinates in pixels that are measured from the top-left, but it can return results
using other approaches as needed.fromboxoimportBoxtlwh={'top':10,'left':10,'width':30,'height':30}coords=[10,10,40,40]coords_ratio=[0.1,0.1,0.4,0.4]obj={'coordinates':[10,10,40,40],'label':'green','name':'my box'}box=Box.from_position(tlwh)box=Box.from_coords(coords)box=Box.from_position_percentage(coords_ratio,width=100,height=100)box=Box.from_position_percentage(coords_ratio,top_origin=False,size=(100,100))box=Box.from_dict(obj)The Box object supports a range of pythonic interactions including sort, addition, subtraction, multiplication,
division and area calculations.fromboxoimportBoxbox_a=Box([10,10,40,40])box_b=Box([15,10,30,50])boxes=[box_b,box_a]# sort the boxes verticallyboxes.sort()# sort the boxes horizontallyboxes.sort(key=lambdax:x.left)# shift the position of a boxbox_a_shifted_down=box_a+[0,10]# [10, 20, 40, 50]box_a_shifted_left=box_a-[5,0]# [5, 10, 35, 40]# scale up the size of a boxbox_a_bigger=box_a*2# [20, 20, 80, 80]box_a_smaller=box_a/3# [3.333333, 3.333333, 13.333333, 13.333333]box_a_smaller=round(box_a_smaller)# [3.3, 3.3, 13.3, 13.3]box_a_smaller_floor=box_a//3# [3, 3, 13, 13]# Combine two boxes (union)box_c=box_a+box_b# [10, 10, 40, 50]# Get the intersection of two boxesbox_i=box_a&box_b# [15, 10, 30, 40]# Get the area of a boxbox_a_area=abs(box_a)# 900box_b_area=box_a.area# 600Note that to avoid the excessive precision that frequently makes its way into Boxes as they are moved and scaled, the
repr of a Box object limits the output to six digits after the decimal.Of course, these operands can be combined to perform common operations such as the commonintersection over unioncalculation used to evaluate agreement between two models.iou=abs(box_a&box_b)/abs(box_a+box_b)# 0.375AttributesTheBoxobject also supports assigning attributes such as alabelortextto the object to associate it with
a set of values.fromboxoimportBoxcv_box=Box([10,10,30,50],{"label":"cat","confidence":0.84})cv_box_2=Box({"coordinates":[10,10,30,50],"label":"cat","confidence":0.84})ocr_box=Box([3,4,67,10],text="Boxo is great for working with boxes")As you can see, there are a variety of options for creating aBoxobject from whatever source system produced it.
Here thecv_boxvalue is created by passing the coordinates first, then a dict containing the associated attributes.cv_box_2is the same value, but here the coordinates and attributes are contained in a single dict object. Finally,
theocr_boxis created by passing coordinates and using keyword arguments to assign attributes. This flexibility is
intentional to make it easier to handle the varying approaches different tools use to represent data.Internally theboxoclasses keep the attributes and coordinate values separate to make them easier to work with.
This shows up in how the objects are represented when printed or displayed in the output. The following is the
representation of the objects above.Box([10, 10, 30, 50], {'label': 'cat', 'confidence': 0.84})
Box([10, 10, 30, 50], {'label': 'cat', 'confidence': 0.84})
Box([3, 4, 67, 10], {'text': 'Boxo is great for working with boxes'})data and serializationpage
pages
page indices