This folder contains helper scripts and a small driver to run a pipeline that queues prompts to a ComfyUI server. The main entrypoint is process_localization.py.
-
Reads prompt JSONs from prompts/ (each must include positive_prompt, negative_prompt, and verification_prompt).
-
Loads a workflow JSON (default: workflows/pipeline_api.json) describing the server steps.
-
For each prompt file, it:
-
Clears the outputs directory.
-
Prepares the workflow (image directory, batch size, prompt texts).
-
Iterates combinations of cfg / denoise / seed and queues jobs to the server.
-
Waits for the server queue to empty.
-
Selects the best-scoring line in a results file and copies matching images to a destination folder.
-
- Image ingest —
LoadImagesFromDir //Inspirepulls a batch from the folder defined inPICTURES_DIRECTORY.process_localization.pyrewritesdirectory,image_load_cap, and related fields at runtime so the workflow always targets the current location dataset. - ControlNet preprocessing — three
AV_ControlNetPreprocessornodes derive canny edges, semantic segmentation, and normals from the source batch. The node strengths and timing are later combined inCR Multi-ControlNet Stack. - Prompt conditioning — the positive/negative prompts from each JSON file overwrite the default text in the CLIP encoders. The ControlNet stack is merged with those encodings in
CR Apply Multi-ControlNetbefore entering the sampler. - Diffusion core — the checkpoint is made tile-aware via
SeamlessTile, a circular VAE is prepared, anEmptyLatentImagesized to the batch is created, andKSamplerruns with the current cfg / denoise / seed triple. Outputs decode throughVAEDecodeandSaveImage, which receives a dynamicfilename_prefixsuch as0batch,1batch, etc. - Automatic scoring — PickScore nodes load the model, process the rendered images, and write comma-separated scores into
temp/scores.txtinside the ComfyUI tree.find_line_with_max_avg()consumes this file to decide which batch prefix produced the best result and clears the file afterwards. - Workflow JSON vs. UI graph —
workflows/pipeline_api.jsonmirrors thepipeline.jsongraph but stores only node metadata required by the HTTP API.process_localization.pymutates the serialized JSON prior to each submission (paths, prompts, sampler params), so you can keep the ComfyUI graph static and still run dynamic batches.
pip install -r requirements.txtYou also need ComfyUI running. See the installation guide
2. Create a .env file in this folder or set the following environment variables in your shell. A sample .env could look like:
SERVER_ADDRESS="127.0.0.1:8188"
WORKFLOW_FILE="pipeline_api.json"
PICTURES_DIRECTORY="<absolute-path-to-images>"
DEFAULT_OUTPUTS_PATH="<absolute-path-to-comfy>/comfy/ComfyUI/output"
DEFAULT_FIND_MAX_FILE="<absolute-path-to-comfy>/comfy/ComfyUI/temp/scores.txt"
DEFAULT_COPY_DEST="<absolute-path-to-directory>"python3 process_localization.pyIt will read all JSON files from the prompts/ directory and process each one in turn.
-
- reads env vars with
dotenvand sets sensible defaults cfgs,denoises, andseedsare defined near the top of the file and control the combinations that get queued- uses
queue_prompt()fromapi_helpers.pyto POST prompts to the server andwait_until_queue_empty()to block until processing finishes - after processing a prompt file it calls
find_line_with_max_avg()(fromhelpers.py) onDEFAULT_FIND_MAX_FILEto pick the best batch index, then copies matching images from the outputs directory into a subfolder ofDEFAULT_COPY_DEST
- reads env vars with
-
find_line_with_max_avg(file_path)reads a file where each line contains numeric scores separated by ", ". It returns the (line_number, average) of the best line and clears the file afterwards. Line numbers are 0-based in this implementation.copy_images_with_pattern(src_dir, dst_dir, org_dir, starts_with)copies files fromsrc_dirwhose filename starts withstarts_withintodst_dir. It uses the filenames listing fromorg_dirto name copied files. Note: the function signature in the repository is slightly different from how it's called inprocess_localization.py— see "Gotchas" below.clear_outputs_dir(outputs_path)deletes all files under the outputs path (destructive).
-
queue_prompt(prompt, server_address, client_id)POSTs the workflow JSON payload tohttp://{server_address}/prompt.wait_until_queue_empty(server_address, poll_interval=10.0)pollshttp://{server_address}/queueuntil the queue is empty.load_prompt(prompt_path)loads a workflow JSON from theworkflows/directory.load_prompt_text(json_path)loads a prompt JSON and validates required keys.
- Sequential orchestration —
process_localization.pyloops over every prompt file, clears the ComfyUI output directory, dispatches all cfg/denoise/seed combinations, waits for the queue to drain, then copies the top-scoring images intoDEFAULT_COPY_DEST/<prompt-name>. - Batching locations —
run_all.shiterates over each subdirectory ofpictures/. For every location it rewrites.envwith the location’sbefore/afterpaths, callsprocess_localization.py, and captures logs per folder. Completed runs restore the original.envautomatically. - Directory structure expectations — each location folder must contain
before/(input reference images) andafter/(where selected outputs land). The script creates missing folders on the fly, ensuring the workflow can run unattended across an arbitrary number of locations.
- Prompts → Edit/add JSON files in prompts/.
- Workflow → Change WORKFLOW_FILE or modify workflows/pipeline_api.json.
- Image set → Point PICTURES_DIRECTORY to a new image folder.
- Hyperparameters for tuning → Adjust cfgs, denoises, seeds in process_localization.py.
- Batch sizing → Modify image_load_cap, batch_size, limit inside process_images(). Change this if your GPU is low on VRAM
-
find_line_with_max_avg()returns 0-based line numbers (and truncates the score file after reading). The code expects this value to be used as a batch prefix when copying images.copy_images_with_pattern()inhelpers.pyis defined ascopy_images_with_pattern(src_dir: str, dst_dir: str, org_dir: str, starts_with: str), but theprocess_localization.pycalls it with three arguments:copy_images_with_pattern(DEFAULT_OUTPUTS_PATH, new_dest, copy_pattern). If you keep the current code, pass a fourth argumentorg_dir(likely the original pictures directory or a directory listing used for naming). Otherwise update the function call to match the implementation.
- If the script cannot reach the server, check
SERVER_ADDRESSand ensure the server exposes/promptand/queueendpoints compatible with the payload shape. - If
find_line_with_max_avg()prints warnings about parsing floats, inspect the score file (DEFAULT_FIND_MAX_FILE) and ensure it contains numeric values separated by ", ".