Project: s41467-025-56622-2 | Function: fill_hull (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Computes convex hull of binary mask and fills the region. Provides two modes: convex hull filling for smooth boundaries and internal filling within existing boundaries.

**KEY TERMS:** {
  "convex_points": "convex hull vertices",
  "hull.vertices": "ConvexHull function from SciPy",
  "fillPoly": "fill convex hull region",
  "binary mask": "training labels created from manual annotation"
}

**CONTEXT CODE:**     name_list = []
    for filename in os.listdir(directory):
        f = os.path.join(directory, filename)
        # checking if it is a file
        if os.path.isfile(f):
            if 'csv' in filename: 
                name_list.append(filename)
    name_list_df = pd.DataFrame(name_list, columns =['subject']) 
    name_list_df['subject_id'] = [x.split('.')[0] for x in name_list_df['subject']] # remove .csv
    
    # process the baseline subject
    for filename in name_list:
        export_matrix(filename, x_axis, y_axis, gate_pre, gate, directory, convex, seq, dest)
    print("process table finished")


def filter(path_list):
    """
    keep only npy files in path list, just in case there are hidden sync files
    args:
        path_list: path containing the data
    """
    path_ = []
    for path in path_list:
        if 'npy' in path:
            path_.append(path)
    return path_

def train_test_val_split(gate, path, dest = '.', train_pred = 'train'):
    """
    Prepare the subject list for training and prediction
    args:
        gate: the gate name that needs to be gated
    """
    if not os.path.exists(f"{dest}/Data/Data_{gate}/{train_pred}"):
        os.mkdir(f"{dest}/Data/Data_{gate}/{train_pred}")

    subj_list = os.listdir(path)
    subj_list = [x+'.npy' for x in subj_list if 'csv' in x]

    imgs_ = [f"{dest}/Data/Data_{gate}/Raw_Numpy/"+x for x in subj_list]
    masks_ = [f"{dest}/Data/Data_{gate}/Mask_Numpy/"+x for x in subj_list]

    imgs = filter(imgs_)
    masks = filter(masks_)
    path = pd.DataFrame(list(zip(imgs, masks)), columns = ['Image','Mask'])

    path.to_csv(f"{dest}/Data/Data_{gate}/{train_pred}/subj.csv", index=False)


def fill_hull(image, convex=True):
    """
    Compute the filled region of the given binary image.

    This function processes binary images to create filled regions based on the
    convex parameter. When convex=True, it computes the convex hull of all non-zero
    points and creates a filled convex region. When convex=False, it fills only
    the interior regions within existing boundaries using contour detection.

    Args:
        image: Binary numpy array representing the input image
        convex: Boolean flag controlling the filling method
                True - compute convex hull and fill
                False - fill existing object boundaries only

    Returns:
        Binary numpy array with filled regions, same shape as input
    """
    raise NotImplementedError("This function has been masked for testing purposes")

Complete the function implementation replacing "raise NotImplementedError".