
Copy Move Forgery Detection
- 12 installs
- 1 repo stars
- Updated March 10, 2026
- davidcastagnetoa/skills
Use OpenCV SIFT keypoint self-matching to find cloned regions within a document image, revealing pasted photos or duplicated text.
About
Detects copy-move forgery by matching SIFT keypoints against themselves to find regions cloned within the same document image. A developer uses it alongside ELA to flag manipulated documents such as a pasted holder photo or cloned document number.
- SIFT self-matching with min-distance and ratio-test filtering
- Combined with ELA for higher-confidence manipulation calls
Copy Move Forgery Detection by the numbers
- 12 all-time installs (skills.sh)
- Ranked #1,445 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/davidcastagnetoa/skills --skill copy_move_forgery_detectionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 12 |
|---|---|
| repo stars | ★ 1 |
| Last updated | March 10, 2026 |
| Repository | davidcastagnetoa/skills ↗ |
What it does
Use OpenCV SIFT keypoint self-matching to find cloned regions within a document image, revealing pasted photos or duplicated text.
Files
copy_move_forgery_detection
Copy-Move Forgery Detection identifica regiones del documento copiadas y pegadas desde otra parte de la misma imagen, revelando manipulaciones como foto del titular pegada o número de documento clonado.
When to use
Aplicar junto con ELA como parte del pipeline de integridad del documento.
Instructions
1. Instalar: pip install opencv-contrib-python-headless (necesario para SIFT). 2. Implementar detección por SIFT keypoints:
import cv2, numpy as np
def detect_copy_move(img, min_matches=10):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(gray, None)
if descriptors is None or len(keypoints) < min_matches:
return {"copy_move_detected": False, "confidence": 0.0}
bf = cv2.BFMatcher(cv2.NORM_L2)
matches = bf.knnMatch(descriptors, descriptors, k=3)
MIN_DIST_PIXELS = 50
suspicious = []
for m in matches:
if len(m) >= 2:
best, second = m[0], m[1]
if best.queryIdx != best.trainIdx:
pt1 = keypoints[best.queryIdx].pt
pt2 = keypoints[best.trainIdx].pt
dist = np.linalg.norm(np.array(pt1) - np.array(pt2))
if dist > MIN_DIST_PIXELS and best.distance < 0.75 * second.distance:
suspicious.append((pt1, pt2))
detected = len(suspicious) >= min_matches
confidence = min(len(suspicious) / (min_matches * 3), 1.0)
return {"copy_move_detected": detected, "confidence": float(confidence)}3. Umbral: match_count >= 10 con confidence > 0.3 → flag COPY_MOVE_DETECTED. 4. Combinar con ELA: si ambos detectan anomalías → alta confianza de manipulación.
Notes
- Documentos con hologramas o patrones repetitivos pueden dar falsos positivos; calibrar
min_matchespor tipo de documento. - ORB es más rápido pero menos preciso que SIFT.
List_Agents.md
list_skills.md
CLAUDE.md
Agents.md
.DS_Store