技能备份 - 2026-04-15 (40个技能)
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MacVisionOCR - macOS Vision Text Recognition via Swift script
|
||||
|
||||
Uses Apple's Vision Framework via Swift script (confirmed working).
|
||||
|
||||
Requirements:
|
||||
- macOS 10.15+ (Catalina)
|
||||
- Swift (built-in on macOS)
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
# Path to Swift script
|
||||
SWIFT_SCRIPT_PATH = Path(__file__).parent / "macvision_swift.swift"
|
||||
|
||||
|
||||
class MacVisionOCR:
|
||||
"""macOS Vision OCR wrapper using Swift script"""
|
||||
|
||||
def __init__(self, verbose: bool = False):
|
||||
"""Initialize MacVisionOCR processor."""
|
||||
self.verbose = verbose
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
raise RuntimeError("MacVisionOCR only works on macOS")
|
||||
|
||||
if self.verbose:
|
||||
print("[INFO] MacVisionOCR initialized (via Swift)")
|
||||
|
||||
def _estimate_confidence(self, text: str) -> float:
|
||||
"""Estimate OCR confidence from text quality."""
|
||||
if not text:
|
||||
return 0.0
|
||||
|
||||
printable = sum(1 for c in text if c.isprintable() or c in '\n\r\t')
|
||||
length_factor = min(1.0, len(text) / 100)
|
||||
quality = printable / max(len(text), 1)
|
||||
|
||||
confidence = 0.85 + (0.15 * quality * length_factor)
|
||||
return round(min(confidence, 1.0), 4)
|
||||
|
||||
def extract(self, image_path: str) -> Dict:
|
||||
"""Extract text from image using Mac Vision OCR via Swift."""
|
||||
from time import time
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
return {
|
||||
'text': '',
|
||||
'confidence': 0.0,
|
||||
'error': 'MacVisionOCR only works on macOS',
|
||||
'processing_time_ms': 0
|
||||
}
|
||||
|
||||
start_time = time()
|
||||
|
||||
try:
|
||||
# Run Swift script with image path as argument
|
||||
result = subprocess.run(
|
||||
['swift', str(SWIFT_SCRIPT_PATH), image_path],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
return {
|
||||
'text': '',
|
||||
'confidence': 0.0,
|
||||
'error': result.stderr.strip(),
|
||||
'processing_time_ms': (time() - start_time) * 1000
|
||||
}
|
||||
|
||||
# Parse Chinese output
|
||||
lines = result.stdout.strip().split('\n')
|
||||
text_lines = []
|
||||
all_confidences = []
|
||||
|
||||
current_text = None
|
||||
for line in lines:
|
||||
if line.startswith('文本:'):
|
||||
current_text = line[3:].strip()
|
||||
elif line.startswith('置信度:') and current_text:
|
||||
try:
|
||||
conf_str = line[4:].strip()
|
||||
# Swift returns confidence as percentage (0-100)
|
||||
# Output format: "置信度:50.00%" -> need to divide by 100
|
||||
numeric_part = conf_str.rstrip('%').strip()
|
||||
confidence = float(numeric_part) / 100.0
|
||||
text_lines.append(current_text)
|
||||
all_confidences.append(confidence)
|
||||
current_text = None
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
|
||||
full_text = '\n'.join(text_lines)
|
||||
processing_time = (time() - start_time) * 1000
|
||||
avg_confidence = sum(all_confidences) / len(all_confidences) if all_confidences else 0.0
|
||||
|
||||
return {
|
||||
'text': full_text.strip(),
|
||||
'confidence': round(avg_confidence, 4),
|
||||
'line_count': len(text_lines),
|
||||
'processing_time_ms': round(processing_time, 2)
|
||||
}
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
return {
|
||||
'text': '',
|
||||
'confidence': 0.0,
|
||||
'error': 'MacVisionOCR timeout',
|
||||
'processing_time_ms': 60000
|
||||
}
|
||||
except Exception as e:
|
||||
processing_time = (time() - start_time) * 1000
|
||||
return {
|
||||
'text': '',
|
||||
'confidence': 0.0,
|
||||
'error': f"MacVision error: {str(e)}",
|
||||
'processing_time_ms': round(processing_time, 2)
|
||||
}
|
||||
|
||||
def batch_extract(self, image_paths: List[str]) -> List[Dict]:
|
||||
"""Process multiple images"""
|
||||
return [self.extract(path) for path in image_paths]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
print("[ERROR] MacVisionOCR only works on macOS")
|
||||
sys.exit(1)
|
||||
|
||||
if not SWIFT_SCRIPT_PATH.exists():
|
||||
print(f"[ERROR] Swift script not found: {SWIFT_SCRIPT_PATH}")
|
||||
sys.exit(1)
|
||||
|
||||
parser = argparse.ArgumentParser(description='macOS Vision OCR via Swift')
|
||||
parser.add_argument('image', help='Image file to process')
|
||||
parser.add_argument('--verbose', '-v', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
processor = MacVisionOCR(verbose=args.verbose)
|
||||
result = processor.extract(args.image)
|
||||
|
||||
print(f"\nText:\n{result['text']}")
|
||||
print(f"\nConfidence: {result['confidence']:.4f}")
|
||||
print(f"Lines: {result.get('line_count', 0)}")
|
||||
print(f"Time: {result.get('processing_time_ms', 0):.2f}ms")
|
||||
Reference in New Issue
Block a user