Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

3.12 K-means Segmentation

Open In Colab

Overview

This lesson utilizes a video snippet capturing 8 months of underwater footage from the Southern Hydrate Ridge, obtained by the Ocean Observatories Initiative (OOI)RCA’s digital still camera. Hydrate Ridge is populated by large communities of giant sulfide-oxidizing bacteria (Beggiatoa) and of the symbiotic vesicomyid clam Calyptogena pacifica and Calyptogena kilmeri, which are associated with surficial hydrate deposits and high fluid flow. The presence of the RCA digital still camera allows us to study the variations of the coverage of this biogenic sediment at a very fine scale. For those interested in learning more, please refer to Antje Boetius and Erwin Suess, “Hydrate Ridge: a natural laboratory for the study of microbial life fueled by methane from near-surface gas hydrates,”. The primary objective is to analyze the changes in biogenic (living organisms) to inert (non-living) sediment ratios over time, offering insights into the seafloor ecosystem dynamics. The workflow involves downloading a video and extracting frames. Image processing techniques, such as CLAHE and HSV conversion, are used to preprocess frames, and KMeans clustering is applied for segmentation, identifying clusters representing different sediment types (biogenic and inert). The notebook quantifies the percentage cover of each cluster over time, producing data that is visualized using stacked bar charts. These charts illustrate the temporal changes in sediment ratios, and linear regression is applied to further quantify these trends. The output includes segmented images, cluster information (colors and percentage cover), stacked bar charts, and linear regression results, providing a comprehensive view of sediment dynamics in the study area.

Learning Objectives:

By the end of this section, you will:

  • Download and process video data within a Google Colab environment.

  • Apply image processing techniques, including CLAHE and HSV conversion for preprocessing the frames.

  • Apply image processing techniques, including CLAHE and HSV conversion for preprocessing the frames.

  • Segment images using KMeans clustering, identifying regions with distinct visual properties.

  • Make decisions about the meaning and science context behind clusters.

  • Quantify the percentage coverage of different sediment types over time.

  • Interpret the patterns identified in the data and draw conclusions about sediment dynamics in the study area.

Libraries Overview

Here’s a quick overview of the most important new imports used in the KMeans segmentation lesson:

sklearn.cluster (KMeans): A machine learning tool for clustering data, useful in tasks like color quantization or image segmentation.

skimage.segmentation (slic): A function for segmenting images using a superpixel approach, useful for simplifying image data for analysis.

skimage.util (img_as_float): Converts image data to floating-point representation, often needed for processing images in scientific computations.

Key Concepts

Superpixels

Superpixels are groups of pixels with similar characteristics that are treated as a single entity. In image segmentation, superpixels help simplify an image by reducing the number of pixels that need to be analyzed, making algorithms more efficient. The slic function from the skimage library is used to generate superpixels. This helps in dividing the image into meaningful regions, which makes subsequent analysis, like clustering, more effective.

Example of Superpixel Segmentation.
Credit: NSF/UW/CSSF

Figure 1:Example of Superpixel Segmentation. Credit: NSF/UW/CSSF


KMeans Clustering

KMeans is a clustering algorithm used to partition data into distinct groups based on similarity. In the context of image segmentation, KMeans helps in grouping pixels into clusters based on their color and intensity values. This allows us to differentiate between areas of biogenic and inert sediments by assigning them into separate clusters, which can then be quantified for analysis.

KMeans Clustering applied to an Underwater Image.
Credit: NSF/UW/CSSF

KMeans Clustering applied to an Underwater Image. Credit: NSF/UW/CSSF


CLAHE (Contrast Limited Adaptive Histogram Equalization)

CLAHE is an image enhancement technique that improves the contrast of images, especially in areas with poor lighting. It is particularly useful for underwater footage, where visibility can be challenging due to the presence of particulate matter and variations in light. CLAHE is uniquely suited to biogenic sediment analysis for camera systems set at an oblique or in heavily shadowed environments. This is because often times color and value are the most important distinctions between sediment types, and applying image-wide brightness adjustments will not preserve the difference in color and will miss a lot. By enhancing the contrast, CLAHE makes it easier for segmentation algorithms, like KMeans, to identify different features in the image more effectively.

Effect of CLAHE on Underwater Image.
Credit: NSF/UW/CSSF

Figure 3:Effect of CLAHE on Underwater Image. Credit: NSF/UW/CSSF

Requirement already satisfied: moviepy in /usr/local/lib/python3.11/dist-packages (1.0.3)
Requirement already satisfied: scikit-image in /usr/local/lib/python3.11/dist-packages (0.25.1)
Requirement already satisfied: scikit-learn in /usr/local/lib/python3.11/dist-packages (1.6.1)
Requirement already satisfied: decorator<5.0,>=4.0.2 in /usr/local/lib/python3.11/dist-packages (from moviepy) (4.4.2)
Requirement already satisfied: imageio<3.0,>=2.5 in /usr/local/lib/python3.11/dist-packages (from moviepy) (2.37.0)
Requirement already satisfied: imageio_ffmpeg>=0.2.0 in /usr/local/lib/python3.11/dist-packages (from moviepy) (0.6.0)
Requirement already satisfied: tqdm<5.0,>=4.11.2 in /usr/local/lib/python3.11/dist-packages (from moviepy) (4.67.1)
Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.11/dist-packages (from moviepy) (1.26.4)
Requirement already satisfied: requests<3.0,>=2.8.1 in /usr/local/lib/python3.11/dist-packages (from moviepy) (2.32.3)
Requirement already satisfied: proglog<=1.0.0 in /usr/local/lib/python3.11/dist-packages (from moviepy) (0.1.10)
Requirement already satisfied: scipy>=1.11.2 in /usr/local/lib/python3.11/dist-packages (from scikit-image) (1.13.1)
Requirement already satisfied: networkx>=3.0 in /usr/local/lib/python3.11/dist-packages (from scikit-image) (3.4.2)
Requirement already satisfied: pillow>=10.1 in /usr/local/lib/python3.11/dist-packages (from scikit-image) (11.1.0)
Requirement already satisfied: tifffile>=2022.8.12 in /usr/local/lib/python3.11/dist-packages (from scikit-image) (2025.1.10)
Requirement already satisfied: packaging>=21 in /usr/local/lib/python3.11/dist-packages (from scikit-image) (24.2)
Requirement already satisfied: lazy-loader>=0.4 in /usr/local/lib/python3.11/dist-packages (from scikit-image) (0.4)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn) (1.4.2)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn) (3.5.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests<3.0,>=2.8.1->moviepy) (3.4.1)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests<3.0,>=2.8.1->moviepy) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests<3.0,>=2.8.1->moviepy) (2.3.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/dist-packages (from requests<3.0,>=2.8.1->moviepy) (2025.1.31)
Source
WARNING:py.warnings:/usr/local/lib/python3.11/dist-packages/moviepy/video/io/sliders.py:61: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if event.key is 'enter':

Set and Define Functions

A diagram showing the I/O of the following functions
Credit: Carter

Figure 4:A diagram showing the I/O of the following functions Credit: Carter

Run the following cell to set up your notebook for the clustering workflow. See the figure above to understand the flow of the following functions.

Video downloaded successfully and saved to: /content/2022SHRSubset.avi
Frames extracted and saved to: /content/frames
Segmentation completed, results saved.
Moviepy - Building video /content/segmented_videos/segmented_video.mp4.
Moviepy - Writing video /content/segmented_videos/segmented_video.mp4

Fetching long content....
Moviepy - Done !
Moviepy - video ready /content/segmented_videos/segmented_video.mp4
Video saved to: /content/segmented_videos/segmented_video.mp4

Displaying Cluster Colors with Original Image and Video Frame

This section defines a function to display the cluster colors, original image, and a video frame clip. It reads cluster information from a text file, extracts HSV color values, loads the corresponding image, and creates color swatches using Matplotlib to visualize the clusters. It then displays the swatches along with the original and clustered images using Plotly for interactive viewing.

Source
Loading...
Loading...
<Figure size 500x200 with 4 Axes>

Displaying the Segmented Video

This section defines a function to display the segmented video within the notebook. It reads the video file, encodes it in base64 format, and then generates an HTML video tag to embed the video for playback.

Loading...

Generating and Displaying Stacked Bar Chart of Cluster Coverage Over Time

This section focuses on quantifying the cluster coverage over time and visualizing it. It extracts cluster percentage data from the text files generated during segmentation, creates a Pandas DataFrame to store the data, and then uses Plotly to generate a stacked bar chart showing the percentage cover of each cluster across the video frames.

Source
Loading...

Interactive Cluster Renaming and Merging

This section enables interactive renaming of clusters and merging of data based on the new names. It uses ipywidgets to create text boxes for users to input new names for each cluster. When a button is clicked, it merges the cluster data in the DataFrame based on the assigned new names, effectively combining clusters represented by the same name into a single category. It saves the result in the mergeddf dataframe.

Source
Enter new names for the clusters:
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

This section performs linear regression analysis on the cluster percentage cover data over time. For each cluster (or merged cluster), it calculates a linear regression model to determine the trend of its coverage. It then visualizes the original cluster data along with the regression line on a Plotly chart, including the regression equation and R-squared value to provide insights into the strength and direction of the trend.

Source
Loading...

Summary Statistics and Detailed Linear Regression Output

This section calculates and displays summary statistics and detailed linear regression output for each cluster. It first prints descriptive statistics for the DataFrame containing cluster percentage cover values (mergeddf). Then, for each cluster, it performs linear regression and prints the detailed regression summary, including coefficients, standard errors, t-statistics, p-values, and R-squared, providing a comprehensive view of the regression results.

Source
Summary Statistics:
               bio          bg
count  331.000000  331.000000
mean    22.094743   77.905408
std      1.092196    1.091915
min     19.200000   76.010000
25%     21.170000   76.905000
50%     22.100000   77.900000
75%     23.090000   78.830000
max     23.990000   80.800000

Running Linear Regression Model:


Linear Regression Summary for Cluster: bio

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.476
Model:                            OLS   Adj. R-squared:                  0.474
Method:                 Least Squares   F-statistic:                     298.4
Date:                Mon, 10 Feb 2025   Prob (F-statistic):           4.86e-48
Time:                        18:21:08   Log-Likelihood:                -391.53
No. Observations:                 331   AIC:                             787.1
Df Residuals:                     329   BIC:                             794.7
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const         23.3935      0.087    269.260      0.000      23.223      23.564
x1            -0.0079      0.000    -17.274      0.000      -0.009      -0.007
==============================================================================
Omnibus:                        6.278   Durbin-Watson:                   1.947
Prob(Omnibus):                  0.043   Jarque-Bera (JB):                5.530
Skew:                          -0.245   Prob(JB):                       0.0630
Kurtosis:                       2.600   Cond. No.                         380.
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Linear Regression Summary for Cluster: bg

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.476
Model:                            OLS   Adj. R-squared:                  0.474
Method:                 Least Squares   F-statistic:                     298.5
Date:                Mon, 10 Feb 2025   Prob (F-statistic):           4.68e-48
Time:                        18:21:08   Log-Likelihood:                -391.40
No. Observations:                 331   AIC:                             786.8
Df Residuals:                     329   BIC:                             794.4
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const         76.6069      0.087    882.079      0.000      76.436      76.778
x1             0.0079      0.000     17.278      0.000       0.007       0.009
==============================================================================
Omnibus:                        6.453   Durbin-Watson:                   1.946
Prob(Omnibus):                  0.040   Jarque-Bera (JB):                5.639
Skew:                           0.246   Prob(JB):                       0.0596
Kurtosis:                       2.592   Cond. No.                         380.
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.