Your definition for the "binary perimeter" is not a good approximation
of the smooth perimeter.
# Sample data
n <- 100
im <- matrix(0, 3*n, 3*n+1)
x <- ( col(im) - 1.5*n ) / n
y <- ( row(im) - 1.5*n ) / n
im[ x^2 + y^2 <= 1 ] <- 1
image(im)
# Shift the image in one direction
s1 <- function(z) cbind(rep(0,nrow(z)), z[,-ncol(z)] )
s2 <- function(z) cbind(z[,-1], rep(0,nrow(z)) )
s3 <- function(z) rbind(rep(0,ncol(z)), z[-nrow(z),] )
s4 <- function(z) rbind(z[-1,], rep(0,ncol(z)) )
# Area, perimeter and circularity
area <- function(z) sum(z)
perimeter <- function(z) sum( z != 0 & s1(z)*s2(z)*s3(z)*s4(z) == 0)
circularity <- function(z) 4*pi*area(z) / perimeter(z)^2
circularity(im)
# [1] 1.241127
area(im)
# [1] 31417
n^2*pi
# [1] 31415.93
perimeter(im)
# [1] 564
2*pi*n
# [1] 628.3185
One worrying feature is that this perimeter is not rotation-invariant:
when you rotate a square of side 1 (with sides parallel to the axes)
by 45 degrees, its area remains the same, but its perimeter is divided by sqrt(2)...
square1 <- -1 <= x & x <= 1 & -1 <= y & y <= 1
c( perimeter(square1), area(square1) )
# [1] 800 40401
square2 <- abs(x) + abs(y) <= sqrt(2)
c( perimeter(square2), area(square2) )
# [1] 564 40045
Here is a slightly better approximation of the perimeter.
For each point on the perimeter,
look at which points in its 8-neighbourhood are also in the perimeter;
if they form a vertical or horizontal segment,
the contribution of the pair to the perimeter is 1,
if they are in diagonal, the contribution is sqrt(2).
edge <- function(z) z & !(s1(z)&s2(z)&s3(z)&s4(z))
perimeter <- function(z) {
e <- edge(z)
(
# horizontal and vertical segments
sum( e & s1(e) ) + sum( e & s2(e) ) + sum( e & s3(e) ) + sum( e & s4(e) ) +
# diagonal segments
sqrt(2)*( sum(e & s1(s3(e))) + sum(e & s1(s4(e))) + sum(e & s2(s3(e))) + sum(e & s2(s4(e))) )
) / 2 # Each segment was counted twice, once for each end
}
perimeter(im)
# [1] 661.7544
c( perimeter(square1), area(square1) )
# [1] 805.6569 40401.0000
c( perimeter(square2), area(square2) )
# [1] 797.6164 40045.0000
circularity(im)
# [1] 0.9015315
circularity(square1)
# [1] 0.7821711
circularity(square2)
# [1] 0.7909881