This code implements the image segmentation algorithm described in the paper:
"Image Segmentation using the Split Bregman Method"
published in IPOL Journal - Image Processing On Line (https://ipol.im)

Authors:
Olakunle Abawonse, olakunle.abawonse@aims.ac.rw, African Institute of Mathematical Sciences
Gunay Dogan, gunay.dogan@nist.gov, National Institute of Standard and Technology

Version: 1.0  (9/1/2024)


Overview
========
This code implements an algorithm for two-phase image segmentation, i.e.
the algorithm partitions the domain of a given 2d image into foreground
and background regions, and each pixel of the image is assigned membership
to one of these two regions. The underlying assumption for the segmentation
model is that the pixel values of the input image can be summarized by two
distinct average values, and that the region boundaries are smooth. These
assumptions are encoded in a segmentation energy, which is minimized using
the split Bregman method to compute the optimal segmentation.


System requirements
===================
This code runs on Python 3. It also requires the NumPy and SciPy packages
for array handling and related computations, and Matplotlib to read and
to save images.


List of Source Files
=====================
This source code includes two Python files: segmentation.py and experiments.py

segmentation.py	: Includes the functions to perform two-phase image segmentation.

	segment_two_phase():	This is the main function that computes a two-phase
				segmentation from an input grayscale image, and
				returns it in a boolean array denoting regions.

	_jacobi_update_for_u():	Computes one Jacobi iteration on the PDE below,
				and returns the update to u.
				\Delta u = (lambda/gamma) r + div(d - b)
	_update_data_term():	Updates the image intensity averages c_1 and c_2,
				also updates the data term:
				r = (f- c_1)^2 - (f- c_2)^2.
	_subproblem_d():	Solves the d subproblem at each Bregman iteration.
	_update_b():		Updates the variable b = b_prev + step_size*(\nabla u - d)
	compute_energy():	Computes the segmentation energy corresponding
				to the current segmentation function u.
	check_convergence():	Given current u and its energy, this function
				checks if the convergence criterion is satisfied.
	_initialize_u_f_g():	Initializes the functions u, f, g before the
				iterations start.

experiments.py : Includes the functions to generate the experimental results and figures.

	figure_2_snapshots()
	figure_3_energy_plots()
	figure_4_regularization()


Example of use
==============
For a given a grayscale input image f with pixel values in range [0,1],
we can import the file segmentation.py, and use the segment_two_phase()
function to compute a segmentation u. The following example shows how
we can do this in Python command line.

	import matplotlib.pyplot as plt
	from segmentation import segment_two_phase
	f = plt.imread('galaxy.png')
	u = segment_two_phase(f)
	plt.figure()
	plt.sublot(1,2,1);  plt.imshow(f);  plt.gray()
	plt.sublot(1,2,2);  plt.imshow(u);  plt.gray()
	plt.show()

It is also possible to run the segmentation function directly from
the terminal, passing the function parameters as arguments:

	python segmentation.py --data_weight 0.1 galaxy.png mask_out.png

To reproduce all the results and figures in the paper, we can run
the following command in a terminal window:

	python experiments.py

This will generate and save the figures.

