93 lines
2.9 KiB
Python
93 lines
2.9 KiB
Python
"""Quality control image analysis utility.
|
|
|
|
Analyzes the available qc-d06 PNG frames in the recheck directory
|
|
and produces structured output for visual defect review.
|
|
"""
|
|
from PIL import Image
|
|
import numpy as np
|
|
import json
|
|
import os
|
|
|
|
RECECK_DIR = '/root/qc-recheck'
|
|
MP4_DIR = '/root/qc-recheck/mp4'
|
|
|
|
def load_image(path):
|
|
"""Load image as int RGB array."""
|
|
return np.array(Image.open(path).convert('RGB')).astype(int)
|
|
|
|
def sample_color(img, y, x):
|
|
"""Sample color at coordinates."""
|
|
return (int(img[y, x, 0]), int(img[y, x, 1]), int(img[y, x, 2]))
|
|
|
|
def find_rects(img, color_range, threshold=50):
|
|
"""Find contiguous regions matching color criteria."""
|
|
r, g, b = color_range
|
|
mask = (np.abs(img[:,:,0].astype(float) - r) < threshold) & \
|
|
(np.abs(img[:,:,1].astype(float) - g) < threshold) & \
|
|
(np.abs(img[:,:,2].astype(float) - b) < threshold)
|
|
rows, cols = np.where(mask)
|
|
if len(rows) == 0:
|
|
return None
|
|
return {
|
|
'x_min': int(cols.min()), 'x_max': int(cols.max()),
|
|
'y_min': int(rows.min()), 'y_max': int(rows.max()),
|
|
'count': int(mask.sum())
|
|
}
|
|
|
|
def main():
|
|
results = {
|
|
'images': [],
|
|
'summary': {'total_images': 0, 'scanned': False}
|
|
}
|
|
|
|
# List available PNG files
|
|
mp4_files = [f for f in os.listdir(MP4_DIR) if f.endswith('.png')]
|
|
results['summary']['total_images'] = len(mp4_files)
|
|
|
|
print("QC Image Analysis Report")
|
|
print("=" * 50)
|
|
print(f"Source directory: {MP4_DIR}")
|
|
print(f"Images found: {len(mp4_files)}")
|
|
print()
|
|
|
|
for f in sorted(mp4_files):
|
|
path = os.path.join(MP4_DIR, f)
|
|
try:
|
|
img = load_image(path)
|
|
H, W, _ = img.shape
|
|
|
|
# Sample key colors
|
|
bg = sample_color(img, 300, 60) # Page background
|
|
white_area = img[386:412, 130:780]
|
|
|
|
# Count near-white pixels (250,255,250 like in original QC)
|
|
white = (img[:,:,0] > 235) & (img[:,:,1] > 235) & (img[:,:,2] > 235)
|
|
white_count = int(white.sum())
|
|
|
|
print(f"File: {f}")
|
|
print(f" Dimensions: {W}x{H}")
|
|
print(f" Page background: RGB {bg}")
|
|
print(f" Near-white pixels: {white_count}")
|
|
print()
|
|
|
|
results['images'].append({
|
|
'filename': f,
|
|
'dimensions': [W, H],
|
|
'background': bg,
|
|
'white_pixel_count': white_count
|
|
})
|
|
except Exception as e:
|
|
print(f"Error loading {f}: {e}")
|
|
|
|
results['summary']['scanned'] = True
|
|
|
|
# Write JSON output
|
|
out_path = '/root/.hermes/wizard-outputs/spark/qc_analysis_results.json'
|
|
with open(out_path, 'w') as fp:
|
|
json.dump(results, fp, indent=2)
|
|
|
|
print(f"Results written to: {out_path}")
|
|
return results
|
|
|
|
if __name__ == '__main__':
|
|
main() |