Estimating the heights of New Yorkers from their scuff marks

Lobsters Hottest News

Summary

The author uses a photo of scuff marks on a subway station wall to estimate the height distribution of commuters, applying image processing and a heuristic body-to-scuff ratio, and discusses potential improvements using Bayesian methods.

<p><a href="https://lobste.rs/s/rtegvw/estimating_heights_new_yorkers_from">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 07/13/26, 11:57 PM

# Estimating the heights of New Yorkers from their scuff marks | Jesse Li Source: [https://blog.jse.li/posts/smith9street/](https://blog.jse.li/posts/smith9street/) [twitter](https://twitter.com/__jesse_li)[rss](https://blog.jse.li/index.xml)![](https://blog.jse.li/smith9street/IMG_4804.jpg)The wall at Smith–Ninth Streets in Brooklyn is made of concrete\. Its rough surface holds onto memories longer than the smooth tile that adorns most other stations in the city\. A commuter waiting for the train leans with one foot against the wall, and their shoe leaves a mark\. It joins marks left by past travelers\. In aggregate, they form a darkened band about 18 inches above the floor\. ``` from matplotlib.image import imread import matplotlib.pyplot as plt import numpy as np import cv2 image = imread('IMG_4804.jpg') IMAGE_WIDTH = image.shape[1] Y1, Y2, X1, X2 = 1800, 2350, 1300, 3300 GROUND_Y = 2454 KEYPAD_X = 3380 KEYPAD_HEIGHT_PX = 670 KEYPAD_HEIGHT_IN = 32 PIXELS_PER_INCH = KEYPAD_HEIGHT_PX / KEYPAD_HEIGHT_IN landmarks = image.copy() cv2.rectangle(landmarks, (X1, Y1), (X2, Y2), (255, 0, 0), 20) cv2.line(landmarks, (0, GROUND_Y), (IMAGE_WIDTH, GROUND_Y), (0, 255, 0), 20) cv2.line(landmarks, (KEYPAD_X, GROUND_Y), (KEYPAD_X, GROUND_Y - KEYPAD_HEIGHT_PX), (0, 0, 255), 10) plt.imshow(landmarks) ``` ![](https://blog.jse.li/smith9street/landmarks.jpg)The yellow keypad beside the maintenance door is 32 inches high \(I[measured it](https://blog.jse.li/smith9street/IMG_4802.jpg)\) which gives us a yardstick by which to convert pixel coordinates into physical positions\. Isolating the region with the scuffs, we can compute the[relative luminance](https://en.wikipedia.org/wiki/Relative_luminance)of each pixel\. ``` region = image[Y1:Y2, X1:X2] luminance = np.dot(region, [0.2126, 0.7152, 0.0722]) plt.imshow(luminance, cmap='Greys_r') ``` ![](https://blog.jse.li/smith9street/luminance.jpg)If we take the average of each row, we can plot the darkness of the wall against height from the floor\. Darker rows have seen more scuffs\. ``` inches = (GROUND_Y - np.arange(Y1, Y2)) / PIXELS_PER_INCH avg_luminances = np.mean(luminance, axis=1) / 255 avg_darknesses = 1 - avg_luminances plt.figure(figsize=(10, 6)) plt.plot(inches, avg_darknesses) plt.title('Darkness of the wall at Smith–Ninth Streets') plt.xlabel('Height from ground (inches)') plt.ylabel('Mean darkness (1 minus relative luminance)') plt.grid(True, linestyle='--', alpha=0.6) ticks = np.arange(np.floor(inches.min()), np.ceil(inches.max())) plt.xticks(ticks[ticks % 2 == 0]) plt.show() ``` ![](https://blog.jse.li/smith9street/plot.png)From just a photo, we obtained a distribution of where commuters’ shoes strike the wall\. Can we derive how tall they are from this data? Experimentally, I put my sneakers on and leaned against my bedroom wall, pretending to wait for the F train\. The scuff I made landed about 27% up the height of my body\. Or, I’m 3\.7 times taller than my scuff mark\. Assuming this ratio holds for everyone \(it doesn’t\) we can scale the chart to estimate the heights of the population\. ![](https://blog.jse.li/smith9street/humans.png)The mean lands on a reasonable spot of five\-foot\-something, but the variance is too wide\. The distribution implies people who are impossibly tall\. Besides height, the other variable here is the angle at which people bend their legs: if someone the same height as me kicked their foot up higher, then I’d incorrectly conclude that they’re taller\. Our model must account for this\. Future work: if we knew the distribution of angles, then we could do some Bayesian math to correct our estimated height distribution\. Send me an email if you want to work together on this\! I’d also love to see other cool wear patterns you spot in the wild\. ![](https://blog.jse.li/smith9street/IMG_4832.jpg)

Similar Articles

The footprints of every building in NYC – updated weekly

Hacker News Top

The New York City Office of Technology and Innovation publishes a weekly updated dataset of building footprints for all 1.08 million buildings in NYC, providing a detailed and current geospatial foundation for city data.

Walkable to Whom? Capturing Subjective Variability in Walkability Perception Using Multimodal Deep Learning

arXiv cs.LG

This paper introduces a dataset of 29,870 walkability ratings from 1,196 respondents and proposes a user-conditioned multimodal deep learning framework that fuses visual features with individual rater attributes to capture subjective variability in walkability perception. The model improves rank agreement by 65% over an image-only baseline, showing that who evaluates an environment matters.