NeverTooSmall Couch Colours

Author

Jonathan Jayes

Published

November 19, 2024

Intro

I really enjoy watching the YouTube channel NeverTooSmall, which showcases cleverly designed small spaces from around the world.

I was watching an episode with my girlfriend recently when she remarked, “Doesn’t it feel like every second couch is a boring grey one on this channel? Why can’t they choose some more fun colors?!”

There are probably a couple of practical reasons people might go for a grey couch. For one, in a small space, a bold color can quickly overpower the room. And secondly, grey doesn’t show wear and discoloration as easily as white, which is often a popular choice for its stylish look.

But Kathy’s comment sent me down a rabbit hole. I wanted to find out how many of the couches on NeverTooSmall were actually grey.

My close friend and flatmate duing my Master’s degree, Nick, once confidently said regarding his interest in audio processing that, “Computer vision is a solved field”—and that was five years ago! So I thought, how hard could it be to use a small, open-source, CPU-based computer vision model to analyze the videos from NeverTooSmall, identify the frames with a couch, extract its color, and visualize the results in a nice waffle chart?

It turns out, it’s not that hard. In this post, I’ll share the answer to my question and, if you’re interested, explain the technical steps I took to get there.

Code
library(tidyverse)
library(jsonlite)
library(gt)

setwd(here::here("posts", "2024-11-19-grey-couches"))

df <- fromJSON("data/couch_info_with_colour_classifications.json")

df <- as_tibble(df)

n_videos <- nrow(df)

n_couches <- nrow(df %>% filter(couch_detected))

n_grey_couches <- nrow(df %>% filter(couch_detected, couch_colour == "grey"))


color_mapping <- c(
    "beige" = "#F5F5DC", # Soft beige
    "light blue" = "#A9D8E6", # Lightened sky blue
    "green" = "#A3DCA3", # Soft pastel green
    "grey" = "#C0C0C0", # Light grey
    "blue" = "#87CEEB", # Light blue
    "black" = "#4E4E4E", # Dark grey to represent pastel black
    "brown" = "#C8A165", # Light brown
    "white" = "#FFFFFF", # White
    "red" = "#FF9999", # Lightened true red
    "yellow" = "#FFFFB3", # Soft pastel yellow
    "teal" = "#99CED3", # Soft teal
    "orange" = "#FFCC99", # Lightened orange
    "pink" = "#FFB6C1", # Soft pink
    "purple" = "#CBA1E6" # Light purple
)


# Expand the data to repeat each color based on the count
expanded_df <- df %>%
    count(couch_colour) %>%
    filter(!is.na(couch_colour)) %>%
    arrange(desc(n)) %>%
    uncount(n) %>%
    mutate(tile_id = row_number())

# Calculate the number of columns and rows for the grid
n_cols <- ceiling(sqrt(nrow(expanded_df)))

# Create a grid with the colors
grid <- expand.grid(x = 1:n_cols, y = 1:n_cols) %>%
    slice(1:nrow(expanded_df)) %>%
    bind_cols(expanded_df)

# Create legend order using number of couches
legend_order <- expanded_df %>%
    group_by(couch_colour) %>%
    summarise(n = n()) %>%
    arrange(desc(n)) %>%
    pull(couch_colour)

# Plot the grid with colors
grid %>%
    ggplot(aes(x = x, y = y, fill = factor(couch_colour, levels = legend_order))) +
    geom_tile(color = "black") +
    scale_fill_manual(values = color_mapping) +
    theme_void() +
    coord_fixed() +
    labs(
        # title = "The colours of the couches in NeverTooSmall videos",
        fill = "Couch Colour"
    ) +
    guides(fill = guide_legend(reverse = TRUE))

Spoiler Alert: Out of the 189 videos on the channel, I identified 148 couches, and 61 of them were grey! That’s nearly three times the next most common color, beige, and four times the third most common color, white.

NeverTooSmall Couches
Grey 61
No couch 41
Beige 23
White 15
Green 12
Blue 11
Black 8
Brown 7
Red 4
Orange 2
Light Blue 1
Pink 1
Purple 1
Teal 1
Yellow 1

How Did We Do It?

I made all my code available for this project in the GitHub repo linked here.

Here’s how I broke down the project:

  1. Ingest data from the NeverTooSmall YouTube playlist.
  2. Identify frames in the videos that contain a couch, selecting the frame with the largest ratio of couch-to-frame area.
  3. Isolate the image of the couch from this frame.
  4. Classify the couch’s color.
  5. Visualize the results.

In the process, I ran into some challenges—especially with color classification—so I tried two approaches to get accurate results. I’ll walk you through each step in detail below.

I think it is worth noting here that while the task of telling what colour a couch is may seem trivial, the fact that it seems so is truly a testament to the fantastic computer vision libraries available today that make it so easy to do.


1. Ingesting the Data

This part was relatively straightforward. Using the yt_dlp library, I pulled video information from the official NeverTooSmall playlist and stored the thumbnails in a folder in my repo.

2. Identifying Frames with a Couch

Luckily, there are a plethora of open-source computer vision models available on platforms like Hugging Face. For this project, I chose a model that performs well on just a CPU and is trained to identify about 80 objects, including couches: the You Only Look Once (YOLO) v8 model. YOLO was originally created in 2016 by Joseph Redmon and coauthors, who aimed to make object detection fast and efficient for real-time applications.1

I wrote a loop to analyze every 100th frame of each NeverTooSmall video, checking if the frame contained a couch and, if so, calculating the ratio of the couch’s bounding box to the frame. At the end of each loop, I selected the frame with the largest ratio, giving me the clearest image of the couch. While there are probably more advanced ways to do this, this method was simple and effective.

Here is an example of frame selection from the Sydney Loft House Small Homes by Brad Swartz above

3. Isolating the Couch Image from the Frame

Next, I used a different version of the YOLO model to segment the frame and extract only the part containing the couch, removing everything else in the image. This step allowed me to focus solely on the couch for color classification.

Here is an example of couch segmentation from the Sydney Loft House Small Homes by Brad Swartz above

4. Classifying the Couch’s Color

For color classification, I initially used a standard clustering algorithm, k-means, to determine the most common 5 colours in the segmented couch image. However, this approach had its limitations. For example, in one instance, the couch was wooden with a white bench cushion and large green scatter cushions. Since the scatter cushions took up more space, my k-means algorithm gave most weight to the color green.2 If asked, though, I’d classify this couch as white based on the cushion.

Another challenge came from the variations in lighting conditions across different videos, as the shots are filmed at various times of day and in different locations. This lighting variance made it hard to extract a general color, as each image offered a very specific shade instead. I created a colour strip for each couch including five colours, weighted by their frequency in the image. As you can see in a gif of these strips in the margin, the colours vary significantly, and are quite dull in some cases.

The 5 colour strips extracted from the segmented image of each couch

To address these issues, I tried grouping colors by their HSV values to create a more generalized classification. While this produced a visually appealing waffle chart, it didn’t fully answer Kathy’s question about the dominant couch color.

The visually appealing waffle chart of couch colors

Sidebar: A bit about color perception
It’s easy for a human to answer, “What color is this?” because our brains are adept at contextualizing color based on lighting, surrounding colors, and other factors. For a computer, though, the task is more challenging. Computers see a “pure” color without context, so they struggle with nuances that are obvious to us. This challenge made me appreciate the difficulty of color perception in computer vision.

To improve accuracy, I took a different approach, using the OpenAI API, which now accepts images. I simply asked the GPT-4o model to classify the couch color based on the segmented image. OpenAI’s API now allows you to specify a data model in your request to ensure you get a specific type of response. Using Pydantic data models in the API request helped me standardize outputs and reduced errors significantly. I can really recommend having a look at the structured outputs option if you are working with the OpenAI API.

Here is the simple data model and prompt I used to get the color classification from the API:

Code
class CouchColourClassification(BaseModel):
    couch_colour: str = Field(description="The classified color of the couch")

PROMPT = """
You will see a still from a video. What color is the couch in the image? Use a single word to describe the color, e.g. 'white', 'black', 'grey', 'beige', 'blue', 'green', 'red', 'brown', 'purple', 'yellow', 'orange', 'pink'. If the couch has multiple colors, choose the most prominent one. 
"""

5. Visualizing the Results

I’m a fan of the waffle chart for representing shares—it’s easier to interpret than a pie chart and, in my opinion, looks great! The visual result of our color classification highlights the distribution of couch colors across the channel’s videos.

The waffle chart of couch colors

Additionally, I used Quarto’s tabsets to group videos by couch color, so you can explore them below.

NEVER TOO SMALL Sydney Small Apartment for Downsizers - 38sqm/410sqft
NEVER TOO SMALL: Architect’s 90’s Inspired Apartment, Paris 57sqm/614sqft
NEVER TOO SMALL: Slide and Fold Micro Apartment, Brazil 29sqm/312sqft
NEVER TOO SMALL: Spanish Couple’s Multifunctional Apartment, Seville 55sqm/592sqft
NEVER TOO SMALL London Heritage Loft Apartment Conversion 54sqm/581sqft
NEVER TOO SMALL Hong Kong Small Treehouse Loft Apartment - 33sqm/355sqft
NEVER TOO SMALL Japanese 5S Micro Apartment - 24sqm/260sqft
NEVER TOO SMALL 40sqm/430sqft Small Apartment - Karoot Apartment
NEVER TOO SMALL: Paris Architect/Book Lover’s Cozy Tiny Apartment - 25sqm/270sqft
NEVER TOO SMALL: Modern Compact Japanese Family Home, Osaka - 57sqm/613sqft
NEVER TOO SMALL: Family of 5’s Simple Home, Japan 45sqm/483sqft
NEVER TOO SMALL: Architect’s Treehouse Inspired Loft Apartment, Madrid 45sqm/484sqft
NEVER TOO SMALL: Tokyo Light-Filled Industrial Oasis, 59sqm/635sqft
NEVER TOO SMALL Melbourne Micro apartment - 22sqm/236sqft
NEVER TOO SMALL 1800’s Milanese Micro Loft Apartment - 14sqm/150sqft
Designing Happier Living - SMALL FOOTPRINT - Ep 1
NEVER TOO SMALL: Bold, Two Toned Small Apartment, Singapore - 47sqm/505sqft
NEVER TOO SMALL: From Dark to Light Heritage Attic Transformation, Lisbon 60sqm/645sqft
NEVER TOO SMALL: Contemporary Attic Conversion for Family of Three, Amsterdam 60sqm/645sqft
NEVER TOO SMALL Australian Apartment Style Tiny Home -27sqm/291sqft
NEVER TOO SMALL Metal Clad Sydney Micro Studio Apartment - 30sqm/322sqft
NEVER TOO SMALL New Zealand Backyard Flexible Micro Loft - 36sqm/387sqft
NEVER TOO SMALL Experimental Small Sydney Apartment - 24sqm/258sqft
NEVER TOO SMALL Italian Micro Loft Apartment - 37sqm/398sqft
NEVER TOO SMALL 40sqm/430sqft Tiny Cabin - The Pod
NEVER TOO SMALL Kyiv Compact Designer Apartment Ukraine - 32sqm/344sqft
NEVER TOO SMALL: Architect’s Stylish Small Apartment Renovation Italy - 50sqm/538sqft
NEVER TOO SMALL: Cinema Inspired Small Apartment, Madrid - 33sqm/355sqft
NEVER TOO SMALL: Architect’s Modernist Apartment Restoration, Melbourne 58sqm/624sqft
NEVER TOO SMALL: Architect’s 19th Century Apartment Restoration, Barcelona - 60sqm/645sqft
NEVER TOO SMALL: Paris Architect’s 70s Luxe Apartment, 53sqm/570sqft
NEVER TOO SMALL Paris Architect’s Micro Apartment - 31sqm/344sqft
NEVER TOO SMALL - 29m2/318sqf - Boho Japanese Micro London Apartment
NEVER TOO SMALL 1970’s Melbourne Tiny Apartment - 35sqm/370sqft
NEVER TOO SMALL Tasmanian bed-Sit Micro Apartment - 26.5sqm/285sqft
NEVER TOO SMALL Central Paris Revolution Era Small Apartment - 42sqm/450sqft
NEVER TOO SMALL: Mid-Century Retro Studio Apartment Sydney 26sqm/280sqft
NEVER TOO SMALL: Seoul Small City Sanctuary Apartment 45sqm/484sqf
NEVER TOO SMALL: Furniture Dealer’s Mid-Century Attic Apartment, Barcelona - 34sqm/366sqft
NEVER TOO SMALL: Interior Architect’s DIY Studio Apartment, Antwerp - 51sqm/548sqft
NTS Renters: Washington DC DIYers Eclectic Studio Apartment: 45sqm/490sqft
NEVER TOO SMALL: Japanese Architect’s Industrial Style Studio, Tokyo 48sqm/516sqf
NEVER TOO SMALL Modular Milanese Micro Apartment - 34sqm/365sqft
NEVER TOO SMALL Melbourne Sustainable Small Apartment - 51sqm/548sqft
NEVER TOO SMALL Sydney Minimalist Small Apartment - 46sqm/495sqft
NEVER TOO SMALL Scandi Style Paris Small Apartment - 50sqm/538sqft
NEVER TOO SMALL: Architect’s Live/Work Home Design Singapore 60sqm/645sqft
NEVER TOO SMALL: Berlin Designer Open Plan Micro Apartment - 36sqm/388sqft
NEVER TOO SMALL: Flexible Minimalist Micro Apartment, Sydney - 27sqm/291sqft
NEVER TOO SMALL: DIY Plant-filled Waterfront Loft, Amsterdam - 45sqm/484sqft
NEVER TOO SMALL: 1970’s Timber Accented Small Apartment Renovation, Melbourne - 42sqm/452sqft
NEVER TOO SMALL: Self Taught Interior Designer’s Apartment, Hong Kong - 48sqm/516sqft
NEVER TOO SMALL: Bespoke Airy Paris Small Apartment, 47sqm/505sqft
NEVER TOO SMALL: Bright, Minimalist Mezzanine Apartment, Taiwan 70sqm/753sqft
NEVER TOO SMALL: Garage to Beach Studio Transformation, Australia 40sqm/431sqft
NEVER TOO SMALL - Japanese Artist’s Unique Open Air Family Home, Tokyo 57sqm/613sqft
NEVER TOO SMALL: Flexible Family Apartment, Singapore 58sqm/624sqft
NEVER TOO SMALL Sydney Art Studio + Small Apartment - 49sqm/419sqft
NEVER TOO SMALL Waterside Italian Two Bedroom Tiny Apartment - 35sqm/376sqft
NEVER TOO SMALL Hong Kong City Escape Small Apartment -52sqm/559sqft
NEVER TOO SMALL Darlinghurst Heritage Small Apartment - 27sqm/ 290sqft
NEVER TOO SMALL London Townhouse Conversion Small Apartment -40sqm/430sqft
NEVER TOO SMALL Modular Antwerp Micro Apartment - 25sqm/269sqft
NEVER TOO SMALL, re-imagining small spaces - channel trailer
NEVER TOO SMALL Tasmanian Heritage Small Home - 44sqm/473sqft
NEVER TOO SMALL Tiny Mediterranean Villa With Pool - 40sqm/430sqft
NEVER TOO SMALL Vibrant Small Athens Apartment 50sqm/538sqf
NEVER TOO SMALL: Singapore Graphic Designer’s Maximalist Apartment - 59sqm/635sqft
NEVER TOO SMALL: Scandi Style Small Apartment - 50sqm/538sqft
NEVER TOO SMALL: Architects’ Tiny Loft Amsterdam 49sqm/527sqft
NEVER TOO SMALL: Diamond Shaped Apartment With Hidden Storage - Hong Kong 50sqm/538sqft
NEVER TOO SMALL: Simple and Stylish Singapore Apartment, 55sqm/592sqft
NEVER TOO SMALL: Flexible Japanese Inspired Apartment, Thailand 33sqm/355sqft
NEVER TOO SMALL: Japanese Inspired Tranquil Apartment, Taiwan 33sqm/355sqft
NEVER TOO SMALL: Ceramicist’s Vintage Furniture Apartment, Warsaw 33sqm/355sqft
NEVER TOO SMALL: Amsterdam Couple’s Luxe DIY Apartment, 48sqm/516 sqft Amsterdam
NEVER TOO SMALL: Japanese Inspired Sydney Terrace House, 47sqm/506sqft
NEVER TOO SMALL: Art Collector’s Luxe Melbourne Apartment, 55sqm/592sqft
NEVER TOO SMALL: Storage Packed Micro Apartment, Hong Kong 24sqm/258sqft
NEVER TOO SMALL: 3 in 1 Artist’s Home, Studio and Gallery, Lisbon 50sqm/538sqft
NEVER TOO SMALL: Clever Spaces in an Illustrator’s Vibrant Apartment, Singapore 47sqm/506sqft
NEVER TOO SMALL: Vibrant Retro Inspired Small Apartment - Madrid 47sqm/506sqft
NEVER TOO SMALL Amsterdam Pod Small Loft Apartment - 45sqm/484sqft
NEVER TOO SMALL Flexible Small Seaside Apartment - 49sqm/527sqft
NEVER TOO SMALL Melbourne Hotel Small Apartment Conversion - 50sqm/538sqft
NEVER TOO SMALL 24sqm/258sqft Micro Apartment - Boneca
NEVER TOO SMALL Small Family Hong Kong Apartment - 40sqm/430sqft
NEVER TOO SMALL Melbourne Toolbox Micro Apartment - 24sqm/258sqft
NEVER TOO SMALL Sci-Fi Apartment Hong Kong - 59sqm/635sqft
NEVER TOO SMALL Hong Kong Walk-Up Tiny Apartment - 25sqm/269sqft
NEVER TOO SMALL 2 x Sydney Loft House Small Homes - 35sqm/375sqft
NEVER TOO SMALL Small Hybrid Loft Pod Apartment - 40sqm/430sqft
NEVER TOO SMALL Art Deco Compartmented Sydney Micro apartment - 22sqm/236sqft
NEVER TOO SMALL London Houseboat Home - 40sqm/430sqft
NEVER TOO SMALL Melbourne Community First Small Apartment - 50sqm/538sqft
NEVER TOO SMALL Barbican Brutalist Small Apartment - 41sqm/441sqft
NEVER TOO SMALL Melbourne Southeast Small Apartment - 50sqm/538sqft
NEVER TOO SMALL Heritage Art Deco Sydney Apartment - 50sqm/538sqft
NEVER TOO SMALL Flexible Milanese Micro Apartment - 30sqm/340sqft
NEVER TOO SMALL Sydney Small Basement Apartment - 49sqm/527sqft
NEVER TOO SMALL Italian Transforming Tiny Studio Apartment - 44sqm/473sqft
NEVER TOO SMALL Buenos Aires Multi-purpose Small Apartment - 42sqm/452sqft
NEVER TOO SMALL Melbourne Flexible Small Apartment - 55sqm/592sqft
NEVER TOO SMALL 40sqm/431sqft Small Apartment Design - Lycabettus Hill Studio
NEVER TOO SMALL Argentinian Small Mezzanine Apartment - 44sqm/474sqft
How We Live Small - SMALL FOOTPRINT Introduction & Trailer
Reimagining Small Living - SMALL FOOTPRINT - Ep 2
Building Urban Villages - SMALL FOOTPRINT - Ep 3
Rethinking Affordability - SMALL FOOTPRINT - Ep 4
Greening our Cities - SMALL FOOTPRINT - Ep 5
Building Happier Cities - SMALL FOOTPRINT - Ep 6
NEVER TOO SMALL - Retro Chic Athens Small Apartment 48sqm/516sqft
NEVER TOO SMALL - Our NTS Space Studio
NEVER TOO SMALL New York Designer Studio Apartment 33sqm/350sqft
NEVER TOO SMALL Architects Paris Small Family Apartment - 54sqm/581sqft
NEVER TOO SMALL Shaker Style Compact Apartment Auckland - 27sqm/291sqft
NEVER TOO SMALL: Architect’s Blue Mountains Cabin, Sydney 28sqm/310sqft
NEVER TOO SMALL: Artist’s Tiny Beach Shack Australia - 30sqm/323sqf
NEVER TOO SMALL: Adaptable Small Apartment for Family of Five Paris - 50sqm/538sqft
NEVER TOO SMALL: Architect’s Colourful 50’s Small Apartment Italy 39sqm/429sqft
NTS Renters: Japanese YouTuber’s DIY Rental, Tokyo 58sqm/624sqft
NEVER TOO SMALL: Easy, Breezy, Adaptable Small Apartment - Poland 32sqm/344sqft
NEVER TOO SMALL: Architect’s DIY Beachside Apartment: Sydney 51sqm/549sqf
NEVER TOO SMALL: Film Director’s Tiny Urban Oasis, Manila - 35sqm/376sqft
NEVER TOO SMALL: Musicians’ Pet Friendly Apartment, Buenos Aires - 48sqm/516sqft
NEVER TOO SMALL: Designer Couple’s Simple Luxe Apartment, Amsterdam 33sqm/355sqft
NEVER TOO SMALL: Architect Couple’s Small Heritage Apartment, France 57sqm/613sqft
NEVER TOO SMALL: Transforming Multifunctional Brazilian Apartment , 56sqm/603sqft
NEVER TOO SMALL: Family of 5’s Multifunctional Micro Apartment, Manila 28 sqm/301sqft
NEVER TOO SMALL: Tetris Shaped French Modernist Apartment, Paris 43m2/463sqft
NEVER TOO SMALL: Colourful, Open Plan Apartment, Seville 58qm/624sqft
NEVER TOO SMALL: Colourful Art Deco Micro Apartment, Sydney 27sqm/290sqft
NEVER TOO SMALL: Elegant, Heritage Apartment Renovation, Berlin 46sqm/495sqft
NEVER TOO SMALL: Architects’ Flexible Three Balcony 1860’s Apartment, Madrid 55sqm/592sqft
NEVER TOO SMALL: DIY YouTuber’s Handcrafted Apartment, Portugal 31sqm/333sqft
NEVER TOO SMALL: Movie Director’s Micro Loft Apartment, Philippines 24sqm/258sqft
NEVER TOO SMALL: Wes Anderson Inspired Attic Apartment, Madrid 42sqm/452sqft
NEVER TOO SMALL: Couple’s Japanese Inspired Loft, Singapore 41sqm/441sqft
NEVER TOO SMALL: Micro Apartment With Multifunctional Mirrored Pod, Melbourne 27sqm/291sqft
NEVER TOO SMALL: Interior Designer’s Custom Built Plywood Apartment, Paris 32sqm/344sqft
NTS: Melbourne Architect’s Smart Space-Saving Hacks in Small Apartment

Conclusion

In conclusion, Kathy was right: grey dominates the couch color spectrum on NeverTooSmall.

I hope you enjoyed following along on this journey to answer a casual question with computer vision. If you’d like to try it yourself, feel free to check out the GitHub repo here and let me know what you find!

Footnotes

  1. Joseph Redmon’s CV is worth a peak if you’re needing some inspiration for your own.↩︎

  2. The offending image
    ↩︎