Skip to main content

Audit Repeat Runs for Virtual Try-On Checkpoints in Node.js

Updated 5 min readMarkdown

A promising virtual try-on result can be hard to reproduce. If a reviewer marked a cuff as correct in one run and broken in another, a summary should show both judgments. This Node.js script counts checkpoint outcomes across repeat runs and keeps hidden details separate from blank review entries.

1. Record the runs you can compare

Use one set of garment and model references, pose instructions, and generation settings per batch. Assign every output a unique run ID. Make a new batch if you change an input. This script assumes you have already made that grouping.

Agree on checkpoint IDs before review. For a fictional shirt, collar can mean the collar shape matches the reference and cuff can mean the expected button is visible and intact. Record pass or fail when the detail can be assessed. Use hidden when the detail is obscured and omit the key when nobody recorded a review.

2. Validate and count the observations

Save this function as checkpoints.mjs. It rejects repeated run IDs, unexpected checkpoint names and invalid outcome values. Each run contributes one count per checkpoint.

const outcomes = ["pass", "fail", "hidden"];

export function summarizeCheckpoints(checkpoints, runs) {
  if (!Array.isArray(checkpoints) || !checkpoints.length ||
      checkpoints.some(id => typeof id !== "string" || !id.trim()) ||
      new Set(checkpoints).size !== checkpoints.length ||
      !Array.isArray(runs) || !runs.length) {
    throw new TypeError("Expected unique checkpoint names and at least one run");
  }

  const counts = new Map(checkpoints.map(id => [
    id, { checkpoint: id, pass: 0, fail: 0, hidden: 0, missing: 0 },
  ]));
  const runIds = new Set();
  for (const run of runs) {
    if (typeof run?.id !== "string" || !run.id.trim() || runIds.has(run.id) ||
        !run.results || typeof run.results !== "object" || Array.isArray(run.results)) {
      throw new TypeError("Expected a unique run ID and a results object");
    }
    runIds.add(run.id);

    for (const [id, outcome] of Object.entries(run.results)) {
      if (!counts.has(id) || !outcomes.includes(outcome)) {
        throw new TypeError("Unknown checkpoint or outcome in " + run.id);
      }
    }

    for (const [id, row] of counts) {
      const outcome = Object.hasOwn(run.results, id) ? run.results[id] : "missing";
      row[outcome]++;
    }
  }

  return [...counts.values()].map(row => ({
    ...row,
    mixed: row.pass > 0 && row.fail > 0,
  }));
}

The output flag mixed means the reviewer recorded at least one pass and one failure. The other columns preserve the context, including how many observations were hidden or missing.

3. Try a sample batch

Save the example as demo.mjs. Four reviews agree on the collar. The cuff has a pass, a failure, a hidden observation and a blank entry.

import { summarizeCheckpoints } from "./checkpoints.mjs";

const checkpoints = ["collar", "cuff"];
const runs = [
  { id: "a", results: { collar: "pass", cuff: "pass" } },
  { id: "b", results: { collar: "pass", cuff: "fail" } },
  { id: "c", results: { collar: "pass", cuff: "hidden" } },
  { id: "d", results: { collar: "pass" } },
];
console.table(summarizeCheckpoints(checkpoints, runs));

The collar row should show four passes and mixed false. The cuff row should show one in each count column and mixed true. Use the original run notes to find the images behind the cuff counts before deciding whether another experiment would help.

4. Test the input rules

Save these assertions as test.mjs. They check counts, invalid values, duplicate IDs and a checkpoint name that could collide with an inherited JavaScript property.

import assert from "node:assert/strict";
import { summarizeCheckpoints } from "./checkpoints.mjs";

const runs = [
  { id: "a", results: { cuff: "pass" } },
  { id: "b", results: { cuff: "fail" } },
  { id: "c", results: { cuff: "hidden" } },
  { id: "d", results: {} },
];
assert.deepEqual(summarizeCheckpoints(["cuff"], runs), [{
  checkpoint: "cuff", pass: 1, fail: 1, hidden: 1, missing: 1, mixed: true,
}]);
assert.equal(summarizeCheckpoints(["cuff"], [runs[0]])[0].mixed, false);
assert.equal(summarizeCheckpoints(["cuff"], [runs[3]])[0].missing, 1);
assert.equal(summarizeCheckpoints(["cuff"], [runs[2]])[0].hidden, 1);
assert.throws(() => summarizeCheckpoints(["cuff", "cuff"], runs), TypeError);
assert.throws(() => summarizeCheckpoints([], runs), TypeError);
assert.throws(() => summarizeCheckpoints(["cuff"], []), TypeError);
assert.throws(() => summarizeCheckpoints(["cuff"], [runs[0], runs[0]]), TypeError);
assert.throws(() => summarizeCheckpoints(["collar"], runs), TypeError);
assert.throws(() => summarizeCheckpoints(["cuff"], [
  { id: "x", results: { cuff: "unknown" } },
]), TypeError);
assert.throws(() => summarizeCheckpoints(["cuff"], [
  { id: "x", results: [] },
]), TypeError);
assert.equal(summarizeCheckpoints(["constructor"], [
  { id: "x", results: {} },
])[0].missing, 1);
console.log("12 checks passed");

5. Run the audit

Put the three files in the same directory and run the demo and tests. Save the summary beside the run IDs and retain the individual notes so you can trace mixed outcomes to the reviewed images.

node demo.mjs
node test.mjs

6. Compare another batch

Run the same audit on the next set using identical checkpoint definitions. Start by comparing the counts and reviewing the cases behind any mixed row. With a small batch, use the output to guide inspection. The script counts human observations and does not examine the images.

The example uses synthetic review data. Drafted with AI assistance.

PixMind source: Unnatural AI Virtual Try-On Results: Fix Garment, Model, and Pose.

Technical reference: Node.js strict assertion mode.

About the author

  • The PixMind team shares practical AI image and video workflows. PixMind brings text-to-image, reference-based creation, editing, and video tools into one workspace. Website: https://www.pixmind.io/

No comments yet. Be the first to comment.

More from this blog