Spaces:
Running
Running
| title: BitCheck Image Verification API | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| # BitCheck Image Verification Backend | |
| BitCheck is a multi-signal image verification API. It does not claim that an image is definitely fake or definitely real. It combines validation, metadata, provenance, visible watermark checks, lightweight forensics, a PyTorch classifier, and Grad-CAM explainability into a risk-based JSON report. | |
| ## Architecture | |
| `POST /verify/image` runs these signals where available: | |
| 1. File validation for JPG, JPEG, PNG, and WEBP uploads. | |
| 2. SHA256 hash, dimensions, mode, MIME type, and file size extraction. | |
| 3. Filename analysis for AI-generation keywords. | |
| 4. EXIF, XMP, PNG text chunks, software, creator, camera, lens, exposure, ISO, and GPS metadata analysis. | |
| 5. AI-tool metadata marker detection. | |
| 6. Optional C2PA / Content Credentials analysis through `c2patool`. | |
| 7. Visible watermark OCR using `pytesseract`. | |
| 8. Visible watermark template matching with OpenCV templates in `templates/watermarks/`. | |
| 9. CPU-friendly forensic checks for sharpness, noise, compression, blur, edge density, and brightness/contrast anomalies. | |
| 10. PyTorch EfficientNet classifier inference. | |
| 11. Grad-CAM heatmap, overlay, and boxed high-influence regions. | |
| 12. Dynamic weighted trust scoring. | |
| The classifier is one signal, not the final authority. | |
| ## Model | |
| BitCheck first looks for: | |
| ```text | |
| models/bitcheck_efficientnet_b0_production.pth | |
| ``` | |
| For local compatibility it can fall back to the included EfficientNet-B0 checkpoints under `models/`. If no model is available, the API still returns a partial report from the other modules. | |
| ## Run Locally | |
| ```bash | |
| python -m venv .venv | |
| source .venv/bin/activate | |
| pip install -r requirements.txt | |
| uvicorn main:app --host 0.0.0.0 --port 7860 | |
| ``` | |
| Dependencies are pinned to CPU-only PyTorch and TorchVision wheels. BitCheck does not require CUDA or GPU runtime packages. | |
| Open: | |
| ```text | |
| http://127.0.0.1:7860/docs | |
| ``` | |
| Browser test console: | |
| ```text | |
| http://127.0.0.1:7860/test-client | |
| ``` | |
| ## API | |
| - `GET /` returns service info. | |
| - `GET /health` returns classifier, OCR, C2PA, and device status. | |
| - `GET /test-client` opens a browser test console for manual uploads. | |
| - `POST /verify/image` accepts multipart image uploads. | |
| - `GET /reports?user_email=user@example.com` lists persisted report summaries for one user. | |
| - `GET /reports/{verification_id}` returns a persisted report. | |
| - `GET /outputs/{filename}` serves generated Grad-CAM and forensic output images. | |
| Example request: | |
| ```bash | |
| curl -X POST "http://127.0.0.1:7860/verify/image" \ | |
| -F "user_email=user@example.com" \ | |
| -F "file=@sample.jpg" \ | |
| -F "run_explainability=true" \ | |
| -F "run_ocr=true" \ | |
| -F "run_forensics=true" \ | |
| -F "run_c2pa=true" | |
| ``` | |
| Required fields: | |
| - `user_email` | |
| - `file` | |
| Optional fields: | |
| - `threshold` | |
| - `run_explainability` | |
| - `run_ocr` | |
| - `run_forensics` | |
| - `run_c2pa` | |
| ## Example Response Shape | |
| ```json | |
| { | |
| "verification_id": "uuid", | |
| "service": "BitCheck", | |
| "file_type": "image", | |
| "status": "completed", | |
| "processing_time_ms": 1234.5, | |
| "user_email": "user@example.com", | |
| "input": { | |
| "filename": "example.png", | |
| "sha256": "...", | |
| "width": 1024, | |
| "height": 1024, | |
| "format": "PNG", | |
| "mode": "RGB", | |
| "mime_type": "image/png", | |
| "file_size_bytes": 123456 | |
| }, | |
| "filename_analysis": {}, | |
| "metadata": {}, | |
| "provenance": {}, | |
| "visible_watermark_ocr": {}, | |
| "visible_watermark_template": {}, | |
| "synthid": { | |
| "checked": false, | |
| "status": "not_available", | |
| "reason": "No official SynthID detector/API integrated." | |
| }, | |
| "classifier": {}, | |
| "forensics": {}, | |
| "explainability": {}, | |
| "trust": {}, | |
| "risk_flags": [], | |
| "recommended_actions": [], | |
| "limitations": [] | |
| } | |
| ``` | |
| ## Grad-CAM | |
| When the classifier is loaded and `run_explainability=true`, BitCheck writes: | |
| - `/outputs/{verification_id}_gradcam_heatmap.jpg` | |
| - `/outputs/{verification_id}_gradcam_overlay.jpg` | |
| - `/outputs/{verification_id}_gradcam_boxes.jpg` | |
| Grad-CAM shows regions that influenced the model prediction. It is not proof of manipulation. | |
| ## Hugging Face Spaces | |
| Create a Docker Space and push this repository. The Dockerfile: | |
| - uses `python:3.11-slim` | |
| - installs `tesseract-ocr`, `libgl1`, and `libglib2.0-0` | |
| - installs Python dependencies from `requirements.txt` | |
| - exposes port `7860` | |
| - runs `uvicorn main:app --host 0.0.0.0 --port 7860` | |
| ## Limitations | |
| BitCheck is honest by design: | |
| - Missing metadata is a weak signal, not proof. | |
| - Missing C2PA provenance is not proof of AI generation. | |
| - OCR can miss or misread visible text. | |
| - Template matching only works when templates are provided. | |
| - Forensic checks are lightweight indicators. | |
| - The classifier is probabilistic. | |
| - No official SynthID detector/API is integrated. | |