Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | import { NextResponse } from 'next/server' import { spawn } from 'child_process' import path from 'path' import { TRAINING_PYTHON, PYTHON_ENV, ensureVenvReady } from '../config' import { withAuth } from '@/lib/auth/withAuth' interface PipelineStepVariant { image_base64: string label: string description: string } interface PipelineStep { step: number name: string title: string description: string image_base64?: string variants?: PipelineStepVariant[] error?: string note?: string original_size?: string target_size?: string } interface PipelinePreviewResult { steps: PipelineStep[] } /** * Preview the preprocessing pipeline using the EXACT SAME Python code as training. * * Shows the image at each step: * 1. Raw image (loaded) * 2. Marker masking (ArUco markers obscured) * 3. Color augmentation (brightness/contrast/saturation variations) * 4. Resize (to 224x224) * 5. Normalize (to [0, 1] range) * * This ensures the preview matches exactly what goes through the training pipeline. */ export const POST = withAuth( async (request) => { try { const body = await request.json() const { imageData, corners, applyMasking = true, applyAugmentation = true } = body if (!imageData) { return NextResponse.json({ error: 'Missing imageData' }, { status: 400 }) } if (!corners) { return NextResponse.json({ error: 'Missing corners' }, { status: 400 }) } // Validate corners format if (!corners.topLeft || !corners.topRight || !corners.bottomLeft || !corners.bottomRight) { return NextResponse.json( { error: 'Invalid corners format - need topLeft, topRight, bottomLeft, bottomRight', }, { status: 400 } ) } // Ensure venv is ready const venvResult = await ensureVenvReady() if (!venvResult.success) { return NextResponse.json( { error: `Python environment not ready: ${venvResult.error}` }, { status: 500 } ) } // Prepare input for Python script const pythonInput = JSON.stringify({ image_base64: imageData, corners: [corners.topLeft, corners.topRight, corners.bottomLeft, corners.bottomRight], apply_masking: applyMasking, apply_augmentation: applyAugmentation, }) // Path to the pipeline preview script const scriptPath = path.join( process.cwd(), 'scripts', 'train-boundary-detector', 'pipeline_preview.py' ) // Run Python script using the training venv const result = await new Promise<PipelinePreviewResult>((resolve, reject) => { const pythonProcess = spawn(TRAINING_PYTHON, [scriptPath], { cwd: path.join(process.cwd(), 'scripts', 'train-boundary-detector'), env: PYTHON_ENV, }) // Send input via stdin pythonProcess.stdin.write(pythonInput) pythonProcess.stdin.end() let stdout = '' let stderr = '' pythonProcess.stdout.on('data', (data) => { stdout += data.toString() }) pythonProcess.stderr.on('data', (data) => { stderr += data.toString() }) pythonProcess.on('close', (code) => { if (code !== 0) { reject(new Error(`Python script failed: ${stderr}`)) return } try { const output = JSON.parse(stdout) resolve(output) } catch { reject(new Error(`Failed to parse Python output: ${stdout}`)) } }) pythonProcess.on('error', (err) => { reject(err) }) }) return NextResponse.json({ success: true, pipeline: result, }) } catch (error) { console.error('[preview-augmentation] Error:', error) return NextResponse.json( { error: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 } ) } }, { role: 'admin' } ) |