Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
pytestdebug.log

# Jupyter Notebook
.ipynb_checkpoints

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
pythonenv*

# IDE specific files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
*.sublime-workspace
*.sublime-project

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# Log files
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Local development files
local_settings.py
.env.local
.env.development
.env.test

# Documentation
docs/_build/

# Example output files
examples/output/

# MacOS specific
.DS_Store
._*

# Windows specific
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

# Linux specific
*~

# Visual Studio Code specific
*.code-workspace

# PyCharm specific
.idea/

# Virtual environment specific
*.venv/

# Build and release specific
*.pyc
*.pyo
*.pyd
__pycache__/
*.so

project_structure.txt
153 changes: 153 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# ImageCompare API Documentation

## Table of Contents
- [REST API Endpoints](#rest-api-endpoints)
- [Python API](#python-api)
- [CLI Interface](#cli-interface)
- [Error Handling](#error-handling)
- [Examples](#examples)

## REST API Endpoints

### Base URL
`http://localhost:8000` (when running locally)

### 1. Compare Two Images
`POST /compare`

**Parameters:**
- `file1`: First image file (required)
- `file2`: Second image file (required)
- `method`: Comparison method (`pixel`, `histogram`, `phash`, `ssim`)

**Example Request:**
```bash
curl -X POST "http://localhost:8000/compare?method=phash" \
-H "accept: application/json" \
-F "file1=@image1.jpg" \
-F "file2=@image2.jpg"
```

**Response:**
```json
{
"match": true,
"confidence": 0.92,
"method": "phash",
"threshold": 0.85
}
```

### 2. Cascading Comparison
`POST /compare/cascade`

**Parameters:**
- `file1`: Base image file
- `file2`: Comparison image file
- `confidence_threshold`: Minimum confidence (0.0-1.0)
- `timeout`: Max processing time in seconds

**Example Response:**
```json
{
"best_match": {
"method": "phash",
"confidence": 0.92,
"match": true
},
"all_results": [
{
"method": "pixel",
"confidence": 0.45,
"match": false
},
{
"method": "phash",
"confidence": 0.92,
"match": true
}
]
}
```

## Python API

### Basic Usage
```python
from imagecompare import compare_images

match, confidence = compare_images("img1.jpg", "img2.jpg", method="phash")
```

### Available Methods
```python
from imagecompare import get_comparison_methods

print(get_comparison_methods())
# Output: {'pixel': 'Fast comparison', 'phash': 'Perceptual hash', ...}
```

### Advanced Usage
```python
from imagecompare.core.comparators import SSIMComparator

comparator = SSIMComparator(threshold=0.8)
match, confidence = comparator.compare(img1_array, img2_array)
```

## CLI Interface

### Basic Comparison
```bash
imagecompare image1.jpg image2.jpg --method phash
```

### Batch Processing
```bash
imagecompare base.jpg compare*.jpg --output json > results.json
```

### Available Options
```
Options:
-m, --method TEXT Comparison method (pixel, histogram, phash, ssim)
-t, --threshold FLOAT Similarity threshold (0.0-1.0)
-o, --output TEXT Output format (simple, json, verbose)
```

## Error Handling

### Common Errors
| Code | Error | Resolution |
|------|----------------------|-------------------------------------|
| 400 | Invalid method | Use one of: pixel, histogram, etc. |
| 422 | Invalid file upload | Check image file format |
| 500 | Processing error | Check server logs |

## Examples

### 1. Find duplicate images in a folder
```python
from glob import glob
from imagecompare import compare_images

images = glob("*.jpg")
for i, img1 in enumerate(images):
for img2 in images[i+1:]:
match, _ = compare_images(img1, img2)
if match:
print(f"Duplicates: {img1} and {img2}")
```

### 2. Web API with Python
```python
import requests

response = requests.post(
"http://your-api/compare",
files={"file1": open("img1.jpg", "rb"),
"file2": open("img2.jpg", "rb")},
params={"method": "phash"}
)
print(response.json())
```
24 changes: 24 additions & 0 deletions examples/basic_usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Basic usage example of ImageCompare Python API
"""
from imagecompare import compare_images, get_comparison_methods

# List available methods
print("Available methods:")
for name, desc in get_comparison_methods().items():
print(f"- {name}: {desc}")

# Compare two images
image1 = "tests/test_data/images/base/empuran_prithvi_1.jpg"
image2 = "tests/test_data/images/variants/empuran_prithvi_variant_2.jpg"
differentImage = "tests/test_data/images/base/thudarum_1.png"

print("\nComparing images:")
match, confidence = compare_images(image1, image2, method="phash")
print(f"Result: {'MATCH' if match else 'NO MATCH'}")
print(f"Confidence: {confidence:.2f}")

print("\nComparing different images:")
match, confidence = compare_images(image1, differentImage, method="phash")
print(f"Result: {'MATCH' if match else 'NO MATCH'}")
print(f"Confidence: {confidence:.2f}")
67 changes: 67 additions & 0 deletions imagecompare/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
ImageCompare - A versatile image comparison toolkit
"""

from pathlib import Path
from typing import Union, Tuple, Dict
from .core.comparators import (
PixelComparator,
HistogramComparator,
PHashComparator,
SSIMComparator
)
from .core.preprocessing import normalize_for_comparison

# Initialize default comparators
_DEFAULT_COMPARATORS = {
"pixel": PixelComparator(threshold=0.95),
"histogram": HistogramComparator(threshold=0.85),
"phash": PHashComparator(threshold=0.85),
"ssim": SSIMComparator(threshold=0.8)
}

def compare_images(
image1: Union[str, Path],
image2: Union[str, Path],
method: str = "phash",
**kwargs
) -> Tuple[bool, float]:
"""
Compare two images using specified method

Args:
image1: Path to first image
image2: Path to second image
method: Comparison method (pixel, histogram, phash, ssim)
**kwargs: Additional comparator-specific parameters

Returns:
Tuple of (match: bool, confidence: float)

Example:
>>> from imagecompare import compare_images
>>> match, confidence = compare_images("img1.jpg", "img2.jpg", method="phash")
>>> print(f"Match: {match}, Confidence: {confidence:.2f}")
"""
if method not in _DEFAULT_COMPARATORS:
raise ValueError(
f"Invalid method '{method}'. Available: {list(_DEFAULT_COMPARATORS.keys())}"
)

comparator = _DEFAULT_COMPARATORS[method]

return comparator.compare(str(image1), str(image2))

def get_comparison_methods() -> Dict[str, str]:
"""
Get available comparison methods with descriptions

Returns:
Dictionary of method names to descriptions
"""
return {
"pixel": "Fast pixel-level comparison (strict)",
"histogram": "Color distribution comparison",
"phash": "Perceptual hash (balanced speed/accuracy)",
"ssim": "Structural Similarity (most accurate but slow)"
}
Loading