Skip to content

ibrahimjspy/PointOfFocus

Repository files navigation

PointOfFocus

A lightweight Flask service that computes the most salient (attention-grabbing) point in an image using OpenCV saliency detectors, and returns JSON:

{
  "focus": { "x": 1432, "y": 514 },
  "width": 1920,
  "height": 1080,
  "algorithm": "fine_grained"
}

It supports remote images (URL), local files (filesystem path), and multipart uploads. Ships with a Dockerfile for containerized deployment.

Deployment note: Designed for private / VPC use. path= is intentionally supported for internal callers. Resource limits protect workers from oversized inputs; there is no public-internet SSRF IP blocklist.


Features

  • Saliency-based focus detection via OpenCV contrib (fine_grained default, optional spectral_residual)
  • Mild center bias + peak-based focus (more stable than raw contour-only picking)
  • Optional crop box around the focus point
  • Supports URL, local path, or multipart file upload
  • /health for liveness checks
  • Docker-ready with Gunicorn
  • Pytest suite + GitHub Actions CI

Prerequisites

  • Python 3.12+ (3.12 recommended)
  • Git
  • Docker (optional)

Local Installation & Running

1. Clone & virtualenv

git clone https://your.git.host/flask-saliency-focus.git
cd flask-saliency-focus
python3 -m venv venv
source venv/bin/activate   # Windows: .\venv\Scripts\Activate.ps1

2. Install dependencies

pip install --upgrade pip
pip install -r requirements.txt          # runtime
pip install -r requirements-dev.txt      # tests + lint

3. Run the app

export FLASK_APP=app.main
export LOG_LEVEL=INFO
flask run --host=0.0.0.0 --port=5000

Or directly:

python -m app.main

Docker Deployment

docker build -t saliency-focus .
docker run --rm -p 5000:5000 saliency-focus

With a local images directory:

docker run --rm -v $(pwd)/images:/data -p 5000:5000 saliency-focus
curl "http://localhost:5000/focus?path=/data/image1.jpg"

Health check: GET /health{"status":"ok"}.


API Usage

GET /

Service metadata: version, endpoints, and supported algorithms.

GET /health

{ "status": "ok" }

GET|POST /focus

Param Type Required? Description
url string one of url / path / file HTTP(S) URL of an image
path string one of url / path / file Filesystem path to a local image
file file POST multipart only Uploaded image file
algorithm string no fine_grained (default) or spectral_residual
center_bias float no 0..1 pull toward image center (default 0.15)
include_crop_box bool no If true, include a suggested crop box
crop_aspect_ratio float no Crop width/height (e.g. 1.5). Defaults to source aspect

Examples

# Remote image
curl "http://localhost:5000/focus?url=https://example.com/pic.jpg"

# Local file
curl "http://localhost:5000/focus?path=image1.jpg"

# Spectral residual + crop box
curl "http://localhost:5000/focus?path=image1.jpg&algorithm=spectral_residual&include_crop_box=true&crop_aspect_ratio=1.5"

# Upload
curl -F "file=@image1.jpg" "http://localhost:5000/focus?include_crop_box=true"

Success (200):

{
  "focus": { "x": 1432, "y": 514 },
  "width": 1920,
  "height": 1080,
  "algorithm": "fine_grained",
  "saliency_score": 0.9922,
  "crop_box": { "x1": 800, "y1": 200, "x2": 1600, "y2": 800 }
}
  • saliency_score (0..1) is the normalized saliency at the focus point — a rough confidence signal.
  • crop_box is only present when include_crop_box=true.

Error (4xx/5xx):

{ "error": "Could not load image at path: /invalid.jpg", "code": "PATH_NOT_FOUND" }

Common codes: MISSING_SOURCE, INVALID_ALGORITHM, INVALID_NUMBER, PATH_NOT_FOUND, IMAGE_TOO_SMALL, IMAGE_TOO_LARGE, URL_FETCH_FAILED, DECODE_FAILED, NOT_FOUND, METHOD_NOT_ALLOWED, INTERNAL_ERROR.


Configuration (env)

Variable Default Meaning
LOG_LEVEL INFO Logging level
MAX_IMAGE_BYTES 15728640 (15 MB) Max download / upload size
MAX_IMAGE_DIMENSION 8192 Max width or height in pixels
MIN_IMAGE_DIMENSION 16 Min width or height in pixels
URL_TIMEOUT_SECONDS 10 HTTP fetch timeout
DEFAULT_ALGORITHM fine_grained Default saliency algorithm
CENTER_BIAS 0.15 Default center bias (0..1)
INCLUDE_CROP_BOX false Always include crop box
CROP_ASPECT_RATIO unset Default crop aspect ratio

Algorithm notes

  • fine_grained — OpenCV StaticSaliencyFineGrained. Detail-sensitive; can latch onto busy textures (murals, lattices).
  • spectral_residual — OpenCV StaticSaliencySpectralResidual. Coarser “blob” attention; often better for interiors.
  • Both apply mild center bias and prefer a smoothed saliency peak (with contour fallback).

Classical OpenCV saliency is contrast-based, not semantic. For human-like fixation quality on hard property photos, evaluate lighter deep models (e.g. FastSal) separately — DeepGaze-class models need GPU and are not drop-in cheap.


Project Structure

flask-saliency-focus/
├── Dockerfile
├── requirements.txt
├── requirements-dev.txt
├── pyproject.toml
├── .github/workflows/ci.yml
├── docs/QUALITY_AND_TESTING_SPEC.md
├── app/
│   ├── __init__.py      # create_app export
│   ├── main.py          # Flask factory, routes, error handlers
│   ├── saliency.py      # image load + saliency + crop box
│   ├── config.py        # env settings
│   └── errors.py        # typed AppError hierarchy
└── tests/
    ├── conftest.py
    ├── test_api.py
    └── test_saliency.py

Testing & lint

pytest
pytest --cov=app --cov-report=term-missing
ruff check app tests

Troubleshooting

  • ImportError: cv2 has no attribute saliency Install the contrib headless package (not plain opencv-python):

    pip uninstall -y opencv-python opencv-contrib-python opencv-python-headless opencv-contrib-python-headless
    pip install -r requirements.txt
  • Timeout downloading remote images Raise URL_TIMEOUT_SECONDS or check URL reachability from the host/container.

  • 413 Payload too large Raise MAX_IMAGE_BYTES / MAX_IMAGE_DIMENSION if your pipeline needs larger inputs.

About

This project focuses on identifying the most attention-grabbing regions in an image. These saliency maps can be used to enhance thumbnails, create dynamic zoom effects, guide text animations, and support various other visual applications where highlighting key areas of an image is essential.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors