Computes the center of gravity (COG) of a character-like binary image using its outer contour.
Usage
cog_contour(img, origin = c("bottomleft", "topleft"))
Arguments
- img
An image input, either a file path to an image file (e.g., PNG, JPEG), or a
cimg
object from the imager package. The image should be in binary form, with foreground (glyph) values not equal to 1 and background values equal to 1.- origin
A character string indicating the location of the image origin. Use
"bottomleft"
(default) if the y-axis increases upward (Cartesian), or"topleft"
if the y-axis increases downward (as in image arrays).
Value
A list containing:
statistics
A data frame with the following components:
center_x
,center_y
: The (x, y) coordinates of the COG in pixel coordinates of the input image.center_x_trim
,center_y_trim
: The COG coordinates relative to the trimmed glyph region, excluding image margins.center_x_std
,center_y_std
: The standardized COG coordinates ranging from 0 to 1, based on the trimmed region's width and height.margin_left
,margin_right
,margin_top
,margin_bottom
: Margins between the glyph and the image boundary.width_original
,height_original
: Dimensions of the original image.width_trim
,height_trim
: Width and height of the trimmed glyph region, excluding margins.area
: The number of pixels inside the convex hull (i.e., the total mass used to compute the COG).
points
A data frame of (x, y) coordinates representing the contour points of the convex polygon.
Details
In the contour-based method, the center of gravity (COG) is defined as the geometrical centroid of the convex hull (the smallest convex polygon) that encloses the stroke region of the character. The convex hull is estimated by tracing the outer contour of the glyph and computing the minimal convex polygon that wraps all stroke pixels, i.e., the foreground pixels whose intensity values are not equal to 1 (pure white). The centroid is then calculated as the arithmetic mean of the (x, y) coordinates of all pixels located within the interior of the convex polygon.
Mathematically, the contour-based center of gravity \((G_x, G_y)\) is defined as the weighted mean of pixel coordinates within the polygon region, where each pixel contributes a value of 1 (unit mass) and background pixels are excluded. Specifically, let \(p(x, y)\) be an indicator function such that \(p(x, y) = 1\) if the pixel \((x, y)\) lies inside the convex polygon and \(p(x, y) = 0\) otherwise. Then the horizontal and vertical components of the COG are computed as:
$$ G_x = (\sum_{x=1}^{w} \sum_{y=1}^{h} p(x, y) \cdot x) / (\sum_{x=1}^{w} \sum_{y=1}^{h} p(x, y)) $$ $$ G_y = (\sum_{x=1}^{w} \sum_{y=1}^{h} p(x, y) \cdot y) / (\sum_{x=1}^{w} \sum_{y=1}^{h} p(x, y)) $$
where \(w\) and \(h\) denote the width and height of the image, respectively.
This method was originally proposed by Kotani and colleagues (2004, 2011) and has been used in character analysis and font design to reflect the perceived shape of glyphs more robustly than simple stroke averaging.
References
Kotani, A. (2011). Contour-based evaluation method of center of gravity on characters and its application to font development. Memoirs of Shonan Institute of Technology, 45(1), 23–33. https://shonan-it.repo.nii.ac.jp/?action=repository_view_main_item_detail&item_id=368
Kotani, A., Asai, Y., Nakamura, Y., Otuka, M., Mituyama, Y., & Onoye, T. (2004). Contour-based evaluation method of center of gravity on “LCFONT.” IPSJ SIG Technical Report, 115, 63–70. https://ipsj.ixsq.nii.ac.jp/records/36793
Examples
data(img_A) # load example image from the package
result <- cog_contour(img_A, origin = "bottomleft")
result$statistics # summary data frame
#> center_x center_y center_x_trim center_y_trim center_x_std center_y_std
#> 1 250.1548 194.8667 189.1548 165.8667 0.4990892 0.3761149
#> margin_left margin_right margin_top margin_bottom width_original
#> 1 61 61 31 29 500
#> height_original width_trim height_trim area
#> 1 500 378 440 93779
result$points # contour polygon vertices (x, y, angle)
#> x y angle
#> 1 389 471 0.0000000
#> 2 391 471 0.0000000
#> 3 439 463 0.1651487
#> 4 439 462 1.5707963
#> 5 429 436 1.9379702
#> 6 305 117 1.9415363
#> 7 284 63 1.9416876
#> 8 275 40 1.9437840
#> 9 273 35 1.9513027
#> 10 272 33 2.0344439
#> 11 271 32 2.3561945
#> 12 223 32 3.1415927
#> 13 222 34 4.2487414
#> 14 219 42 4.3536183
#> 15 196 104 4.3571581
#> 16 69 447 4.3577783
#> 17 62 466 4.3593986
result$origin # image origin specification
#> [1] "bottomleft"