$ cd ~/projects

Block Rev Image

updated 18 days agosource

// how it works

> Verify where a face photo appears online, then stamp the evidence immutably on Polygon Amoy. --- ## What It Does Given a photo containing a face, this system: 1. **Detects the face** and generates a 512-dimensional ArcFace embedding 2. **Searches the web** using reverse image search (Google Lens via SerpApi) 3. **Verifies candidates** by comparing image similarity (pHash) and face similarity (ArcFace cosine) 4. **Records evidence** on Polygon Amoy testnet — a SHA-256 hash of all findings stored in a smart contract 5. **Produces a transaction** anyone can verify on [Amoy Polygonscan](htt

Verify where a face photo appears online, then stamp the evidence immutably on Polygon Amoy.


What It Does

Given a photo containing a face, this system:

  1. Detects the face and generates a 512-dimensional ArcFace embedding
  2. Searches the web using reverse image search (Google Lens via SerpApi)
  3. Verifies candidates by comparing image similarity (pHash) and face similarity (ArcFace cosine)
  4. Records evidence on Polygon Amoy testnet — a SHA-256 hash of all findings stored in a smart contract
  5. Produces a transaction anyone can verify on Amoy Polygonscan

Architecture

                         INPUT PHOTO
                              |
              +---------------+---------------+
              |               |               |
              v               v               v
       [Strategy A]     [Strategy B]     [Strategy C]
    Single Search     Cascaded Search   Dual-Engine +
    (direct match)    (5 query forms)   ArcFace gate

     All 3 run in parallel via orchestrator.py
              |               |               |
              v               v               v
       evidence_a.json  evidence_b.json  evidence_c.json
              |               |               |
              +---------------+---------------+
                              |
                              v
                     consensus check
                              |
                              v
                     final_report.json
                              |
                              v
                     Polygon Amoy TX

Strategy Comparison

Property Strategy A Strategy B Strategy C
Approach Direct match Multi-form cascade Dual-engine + two-gate
Query forms 1 (original) 5 (orig, face, 2x, ctx, norm) 1 (original)
Search engines Google Lens Google Lens (cascaded) Google Lens + TinEye
Verification gates 1 (image sim) 1 (image sim) 2 (image + face)
Best for Clean demo Hard-to-find images Most defensible result
Runtime ~10s ~15-40s ~20-30s

Quick Start

Prerequisites

  • Python 3.10+
  • A SerpApi API key (free: 100 searches/month)
  • MetaMask wallet on Polygon Amoy testnet (free test POL from faucet)

1. Clone & Install

git clone https://github.com/vaibhav7087/block_rev_image.git
cd block_rev_image
pip install -r requirements.txt

2. Configure

cp .env.example .env

Edit .env with your keys:

SERPAPI_KEY=your_serpapi_key_here
WALLET_PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
POLYGON_AMOY_RPC=https://polygon-amoy.g.alchemy.com/v2/YOUR_KEY

3. Deploy Contract

python -c "from src.blockchain.contract import deploy_contract; print(deploy_contract())"

Copy the contract_address into your .env:

CONTRACT_ADDRESS=0x...

4. Run

# Single strategy
python src/main.py --image samples/test.jpg --strategy A

# All 3 strategies in parallel
python src/main.py --image samples/test.jpg --strategy ALL

Or use the one-click demo:

bash run_demo.sh

Project Structure

reverse_face/
├── src/
│   ├── main.py                 # CLI entry point
│   ├── orchestrator.py         # Parallel strategy launcher
│   ├── strategy_a.py           # Strategy A pipeline
│   ├── strategy_b.py           # Strategy B pipeline
│   ├── strategy_c.py           # Strategy C pipeline
│   ├── face/
│   │   ├── detector.py         # InsightFace face detection
│   │   ├── embedding.py        # ArcFace 512-dim embedding
│   │   └── multi_crop.py       # 5 query form generator
│   ├── reverse_search/
│   │   ├── google_lens.py      # SerpApi Google Lens
│   │   ├── tineye.py           # TinEye API
│   │   ├── cascade.py          # Multi-form cascade engine
│   │   └── dual_search.py      # Parallel Lens + TinEye
│   ├── verification/
│   │   ├── similarity.py       # pHash image similarity
│   │   ├── candidate_ranker.py # Composite scoring
│   │   ├── parallel_verifier.py # Async multi-candidate
│   │   └── two_gate.py         # Dual-gate decision logic
│   ├── evidence/
│   │   ├── canonicalize.py     # Deterministic JSON
│   │   └── hashing.py          # SHA-256
│   ├── blockchain/
│   │   ├── contract.py         # Web3.py, deploy + register
│   │   └── registry_abi.json   # Contract ABI
│   └── utils/
│       ├── image_io.py         # Image load/save
│       └── logging.py          # Structured logging
├── contracts/
│   └── VerificationRegistry.sol
├── strategies/                 # Architecture documentation
├── samples/                    # Test images
├── output/                     # Evidence JSONs + reports
├── requirements.txt
├── .env.example
└── run_demo.sh

Smart Contract

The VerificationRegistry contract on Polygon Amoy stores SHA-256 hashes of evidence:

function register(bytes32 evidenceHash, string calldata pipelineVersion) external
function verify(bytes32 evidenceHash) external view returns (Record memory)

Each registration is:

  • Immutable — cannot be overwritten
  • Timestamped — block timestamp proves sequence
  • Auditable — compute SHA-256 of evidence JSON and compare to on-chain hash

Environment Variables

Variable Required Description
SERPAPI_KEY Yes SerpApi API key for Google Lens
TINEYE_API_KEY No TinEye API key (Strategy C)
WALLET_PRIVATE_KEY Yes MetaMask private key for Polygon Amoy
CONTRACT_ADDRESS Yes Deployed VerificationRegistry address
POLYGON_AMOY_RPC Yes Polygon Amoy RPC endpoint
INSIGHTFACE_MODEL No Face model (default: buffalo_l)
USE_GPU No Set 1 for GPU acceleration
DEFAULT_STRATEGY No A, B, C, or ALL (default: ALL)

Evidence Format

Each strategy produces a canonical JSON:

{
  "schema_version": "1.0",
  "strategy": "A_exact_provenance",
  "case_id": "CASE-a1b2c3d4e5f6",
  "query_image_sha256": "...",
  "face_detected": true,
  "face_embedding_model": "ArcFace-R100 (buffalo_l)",
  "match_found": true,
  "matched_url": "https://instagram.com/p/...",
  "image_similarity": 0.93,
  "face_similarity": 0.91,
  "combined_score": 0.922,
  "retrieved_at": "2026-09-07T18:30:00+00:00",
  "pipeline_version": "strategy_a_v1.0"
}

The SHA-256 of this canonical JSON is what gets stored on-chain.


Limitations

Limitation Mitigation
Reverse search only finds indexed images Works best for publicly indexed social media
Face similarity ≠ identity proof Output says "visually similar face", never "this is this person"
SerpApi has rate limits (100/month free) Mock mode available for testing
Blockchain timestamp is not legal proof Documents sequence, not legal identity

Demo Output

$ python src/main.py --image samples/test.jpg --strategy ALL

[ORCH] Spawning 3 strategy worker(s): A, B, C

==================================================
  STRATEGY A — Exact / Near-Exact Provenance
==================================================
[STRAT-A] [1/6] Loading image                       OK (400x400)
[STRAT-A] [2/6] Detecting face                      OK (score=0.897)
[STRAT-A] [3/6] Generating ArcFace embedding        OK (512-dim)
[STRAT-A] [4/6] Reverse image search (Google Lens)  OK (5 candidates)
[STRAT-A] [5/6] Candidate verification              OK (score=1.000)
[STRAT-A] [6/6] Blockchain registration             OK

  Strategy A completed in 15.3s

  --- Strategy A ---
  Match Found : YES
  Image Sim   : 1.0
  Face Sim    : 1.0
  Combined    : 1.0
  TX Hash     : 0xc9ecda780fbbedb6...
  Explorer    : https://amoy.polygonscan.com/tx/0xc9ecda780fbbedb6...

License

MIT


Acknowledgments

// stack

Python