A powerful yet user-friendly OpenCV wrapper that makes computer vision accessible for everyone. Easy OpenCV provides a streamlined interface to perform complex computer vision operations with simple, intuitive function calls.
"Computer vision simplified with human-readable function calls and sensible defaults"
pip install easy-opencv-wrapperfrom easy_opencv import cv # Note: underscores, not hyphens!Requirements: Python 3.7+ β’ OpenCV 4.5+ β’ NumPy 1.19+ β’ Pillow 8.0+
π Critical: The PyPI package name is
easy-opencv-wrapper(with hyphens), but you import it aseasy_opencv(with underscores). This is standard Python convention. See INSTALLATION_GUIDE.md for troubleshooting.
# β WRONG - These will cause ModuleNotFoundError
import easy_opencv_wrapper
import easy-opencv
# β
CORRECT - This is how you import Easy OpenCV
from easy_opencv import cvRun our verification script to test your installation:
python verify_import.pyThis script will test both correct and incorrect imports and verify basic functionality.
from easy_opencv import cv
# Load and enhance image (handles errors automatically)
image = cv.load_image('photo.jpg')
enhanced = cv.apply_noise_reduction(image)
enhanced = cv.adjust_brightness_contrast(enhanced, brightness=10, contrast=1.2)
# Detect faces and draw boxes
faces = cv.detect_faces(enhanced)
for (x, y, w, h) in faces:
enhanced = cv.draw_rectangle(enhanced, (x, y), (x+w, y+h), color=(0, 255, 0))
# Save result
cv.save_image(enhanced, 'enhanced_photo.jpg')Easy OpenCV dramatically reduces the complexity of computer vision code while maintaining all the power of OpenCV underneath. It helps you:
- Write 50-70% less code for common tasks
- Eliminate boilerplate code with smart defaults
- Focus on your application instead of OpenCV's complex API
- Reduce errors with built-in validation and clearer error messages
- Learn computer vision concepts with intuitive function names
# OpenCV original:
img = cv2.imread('image.jpg')
if img is None:
raise FileNotFoundError("Image not found")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
blurred = cv2.GaussianBlur(img_rgb, (15, 15), 0)
edges = cv2.Canny(blurred, 100, 200)
# Easy OpenCV equivalent:
img = cv.load_image('image.jpg', mode='rgb') # Load and convert in one step
blurred = cv.apply_gaussian_blur(img, kernel_size=15)
edges = cv.apply_edge_detection(blurred)π See DIFFERENCE.md for 22+ side-by-side code comparisons and EASY_OPENCV_BENEFITS.md for detailed benefits analysis.
- Intuitive API Design: Human-readable function names and parameters
- Intelligent Defaults: Functions work out-of-the-box with sensible parameters
- Automatic Processing: Many preprocessing steps are handled automatically
- Built-in Error Handling: Validation and clear error messages
- Comprehensive Documentation: Every function has detailed docstrings with examples
- Image Operations: Load, save, resize, crop, and convert images with simple function calls
- Video Processing: Handle video files, extract frames, and create videos from image sequences
- Image Processing: Apply filters, enhance images, and perform various image transformations
- Feature Detection: Detect corners, keypoints, contours, and match features between images
- Object Detection: π Class-based system with automatic webcam fallback - Face, eye, motion, and DNN object detection
- Drawing Operations: Draw shapes, text, and annotations on images
- Filters: Apply various filters including blur, sharpen, vintage, cartoon effects
- Transformations: Rotate, flip, warp, and apply perspective transformations
- Utilities: Helper functions for FPS counting, color picking, and image comparison
Easy OpenCV now features a powerful class-based object detection system with automatic webcam fallback:
from easy_opencv import FaceDetector, EyeDetector, ColorDetector
# π― Face detection with automatic webcam fallback
detector = FaceDetector()
results = detector.detect_from_source() # Uses webcam if no source provided
# π¨ Detect red objects from webcam
color_detector = ColorDetector(target_color='red')
results = color_detector.detect_from_source()
# πΉ Motion detection with live preview
motion_detector = MotionDetector()
results = motion_detector.detect_from_source(show_live=True)
# π₯ Alternative webcam access methods
video = cv.load_video(0) # Use camera index 0 (default webcam)
# Or use the WebcamCapture class for more control
webcam = cv.WebcamCapture()
webcam.capture(camera_id=0, save_path="recording.mp4") # With optional recordingKey Features:
- π₯ Automatic webcam fallback when no image/video path provided
- π Support for images, videos, and live webcam streams
- ποΈ Reusable detector objects with custom parameters
- π Built-in live visualization with bounding boxes
- π Full backward compatibility with legacy functions
For reliable webcam access, there are several approaches:
# Method 1: Using the load_video function with camera index
video = cv.load_video(0) # 0 = default webcam
while True:
ret, frame = video.read()
if not ret:
break
# Process frame
cv.show_image(frame, 'Video', wait=False)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video.release()
# Method 2: Using WebcamCapture class for interactive controls
webcam = cv.WebcamCapture()
webcam.capture(camera_id=0) # Interactive session with keyboard controls
# Method 3: Using object detectors with built-in webcam support
detector = FaceDetector()
detector.detect_from_source(source=None) # None defaults to webcam
β οΈ Note: When usingcv.show_image()in a video loop, setwait=Falseto prevent blocking.
pip install easy-opencvgit clone https://github.com/yourusername/easy-opencv.git
cd easy-opencv
pip install -r requirements.txt
pip install -e .- Python 3.7+
- OpenCV 4.5.0+
- NumPy 1.19.0+
- Pillow 8.0.0+
from easy_opencv import cv
# Load an image (automatically handles errors and converts to preferred format)
image = cv.load_image('path/to/image.jpg', mode='rgb')
# Get image information
info = cv.get_image_info(image)
print(f"Image dimensions: {info['width']}x{info['height']}, channels: {info['channels']}")
# Resize with aspect ratio preservation
resized = cv.resize_image(image, width=800) # Height calculated automatically
# Apply a filter with one simple function call
blurred = cv.apply_gaussian_blur(image, kernel_size=15)
# Show the result (handles window creation and keypress waiting)
cv.show_image(blurred, 'Blurred Image')
# Save the result with quality control
cv.save_image(blurred, 'output.jpg', quality=95)from easy_opencv import cv
# Load image (handles errors automatically)
image = cv.load_image('portrait.jpg')
# Detect faces with simple parameters
faces = cv.detect_faces(image, scale_factor=1.1, min_neighbors=5)
# Process each face
for i, (x, y, w, h) in enumerate(faces):
# Draw rectangle with built-in function
image = cv.draw_rectangle(image, (x, y), (x+w, y+h), color=(0, 255, 0), thickness=2)
# Add label with customization options
image = cv.draw_text(image, f"Face {i+1}", (x, y-10),
font_scale=0.5, color=(255, 255, 255),
background=True, bg_color=(0, 200, 0))
# Extract face region for further processing
face_img = cv.crop_image(image, x, y, w, h)
# Detect eyes within the face
eyes = cv.detect_eyes(face_img)
print(f"Found {len(eyes)} eyes in face {i+1}")
# Save and display the result
cv.save_image(image, 'detected_faces.jpg')
cv.show_image(image, 'Face Detection Results')from easy_opencv import cv
# Start with a single image
image = cv.load_image('scene.jpg')
# Create multiple processed versions
grayscale = cv.convert_color_space(image, 'rgb', 'gray')
blurred = cv.apply_gaussian_blur(image, kernel_size=15)
edges = cv.apply_edge_detection(image)
vintage = cv.apply_vintage_filter(image, intensity=0.7)
cartoon = cv.apply_cartoon_filter(image)
# Create a comparison grid with labels
images = [image, grayscale, blurred, edges, vintage, cartoon]
labels = ["Original", "Grayscale", "Blurred", "Edges", "Vintage", "Cartoon"]
# Add labels to images
labeled_images = []
for img, label in zip(images, labels):
img_with_label = cv.draw_text(img.copy(), label, (10, 30),
font_scale=0.8, color=(255, 255, 255),
background=True)
labeled_images.append(img_with_label)
# Create image grid (automatically handles different sized images)
grid = cv.create_image_grid(labeled_images, grid_size=(2, 3))
# Show the results
cv.show_image(grid, "Image Processing Effects")| Function | Description | Key Features |
|---|---|---|
load_image(path, mode='color') |
Load images in different color modes | Handles errors, auto-converts color spaces |
save_image(image, path, quality=95) |
Save images with quality control | Supports multiple formats, compression control |
resize_image(image, width=None, height=None, scale=None) |
Flexible image resizing | Preserves aspect ratio, multiple methods |
crop_image(image, x, y, width, height) |
Crop images to specified regions | Boundary checking, aspect ratio options |
convert_color_space(image, src_space='bgr', dst_space='rgb') |
Convert between color spaces | Intuitive naming ('rgb' vs 'COLOR_BGR2RGB') |
merge_channels(channels) |
Merge image channels | Automatic validation |
split_channels(image) |
Split image into channels | Returns named tuple for clarity |
π NEW Class-Based API with Webcam Support:
# Import the new video operation classes
from easy_opencv import VideoLoader, VideoPlayer, WebcamCapture, VideoAnalyzer
# Load video files or webcam streams
loader = VideoLoader()
video = loader.load("video.mp4") # or loader.load(0) for webcam
# Play videos with advanced controls
player = VideoPlayer(default_speed=1.0, default_loop=True)
player.play("video.mp4") # Interactive playback with controls
# Analyze video content
analyzer = VideoAnalyzer()
info = analyzer.get_info("video.mp4")
motion_data = analyzer.analyze_motion("video.mp4")
# Capture from webcam with recording
webcam = WebcamCapture()
webcam.capture(camera_id=0, save_path="recording.mp4")Available Video Classes:
VideoLoader- Loading videos from files or webcam sourcesVideoSaver- Saving videos with customizable parametersVideoPlayer- Playing videos with advanced playback controlsFrameExtractor- Extracting frames from videosVideoAnalyzer- Analyzing video properties and motionWebcamCapture- Capturing from webcams with interactive controls
Legacy Functions (Still Supported):
| Function | Description | Key Features |
|---|---|---|
load_video(path) |
Load video files | Metadata extraction, error handling |
extract_frames(video_path, output_dir, frame_interval=1) |
Extract frames from videos | Progress tracking, flexible naming |
create_video_from_frames(frame_paths, output_path, fps=30.0) |
Create videos from image sequences | Auto resolution detection, codec options |
webcam_capture(camera_id=0, save_path=None) |
Capture from webcam | Interactive controls, recording options |
get_video_info(video_path) |
Get video metadata | FPS, resolution, duration, codec |
apply_video_filter(video_path, filter_func, output_path=None) |
Process entire videos | Progress bar, parallel processing |
| Function | Description | Key Features |
|---|---|---|
apply_blur(image, blur_type='gaussian', strength=5) |
Apply various blur effects | Multiple algorithms, automatic kernel handling |
apply_edge_detection(image, method='canny') |
Edge detection algorithms | Auto-threshold, pre-processing |
apply_threshold(image, threshold_type='binary') |
Thresholding techniques | Multiple methods, auto-threshold option |
adjust_brightness_contrast(image, brightness=0, contrast=1.0) |
Brightness/contrast adjustment | Preview option, clip protection |
equalize_histogram(image, adaptive=False) |
Enhance image contrast | CLAHE adaptive option |
remove_noise(image, method='median') |
Noise removal | Multiple algorithms |
sharpen_image(image, strength=1.0) |
Sharpen images | Unsharp mask option |
invert_colors(image) |
Invert image colors | Handles all color spaces |
| Function | Description | Key Features |
|---|---|---|
detect_corners(image, method='harris') |
Corner detection | Multiple algorithms, filtration |
detect_keypoints(image, detector='sift') |
Keypoint detection | Multiple detectors (SIFT, ORB, etc.) |
match_features(desc1, desc2, method='bf') |
Feature matching | Ratio test, RANSAC options |
detect_contours(image, threshold_value=127) |
Contour detection | Hierarchy, filtering options |
find_template(image, template, method='ccoeff') |
Template matching | Multiple methods, threshold |
find_lines(image, method='hough') |
Line detection | Standard and probabilistic Hough |
find_circles(image) |
Circle detection | Parameter optimization |
match_histograms(source, reference) |
Match histogram between images | Channel-wise matching |
π NEW Class-Based API with Webcam Support:
# Import the new detection classes
from easy_opencv import FaceDetector, EyeDetector, ColorDetector, MotionDetector
# Face detection with automatic webcam fallback
face_detector = FaceDetector(scale_factor=1.1, min_neighbors=5)
results = face_detector.detect_from_source() # Uses webcam automatically
# Color detection from webcam
color_detector = ColorDetector(target_color='red', tolerance=20)
results = color_detector.detect_from_source(show_live=True)
# Motion detection with video output
motion_detector = MotionDetector(sensitivity=500)
results = motion_detector.detect_from_source(output_path="motion.mp4")Available Detector Classes:
FaceDetector- Face detection using Haar cascadesEyeDetector- Eye detection using Haar cascadesCascadeDetector- Generic cascade detector for custom XML filesMotionDetector- Motion detection with background subtractionCircleDetector- Circle detection using Hough TransformLineDetector- Line detection using Hough TransformColorDetector- Color-based object detection in HSV spaceDNNObjectDetector- Deep learning object detection (SSD MobileNet V2)
Legacy Functions (Still Supported):
| Function | Description | Key Features |
|---|---|---|
detect_faces(image, scale_factor=1.1) |
Face detection | Multiple models, confidence control |
detect_eyes(image, scale_factor=1.1) |
Eye detection | Works within face regions |
detect_motion(video_path, sensitivity=500) |
Motion detection | ROI selection, threshold control |
color_detection(image, target_color='red') |
Color-based detection | HSV/RGB support, tolerance setting |
detect_objects_dnn(image) |
DNN object detection | Pre-trained models, confidence threshold |
| Function | Description | Key Features |
|---|---|---|
draw_rectangle(image, start_point, end_point, color=(0,255,0)) |
Draw rectangles | Fill, opacity, rounded corners |
draw_circle(image, center, radius, color=(0,255,0)) |
Draw circles | Fill, opacity control |
draw_text(image, text, position, font_scale=1.0) |
Add text to images | Background, auto-positioning |
draw_bounding_boxes(image, boxes, labels=None) |
Draw multiple bounding boxes | Labels, confidence scores |
draw_polygon(image, points, color=(0,255,0)) |
Draw polygons | Fill, antialiased |
draw_arrow(image, start_point, end_point, color=(0,255,0)) |
Draw arrows | Width, head size control |
draw_grid(image, grid_size, color=(128,128,128)) |
Draw grid lines | Thickness, style options |
draw_crosshair(image, position, size=20, color=(0,255,0)) |
Draw crosshair | Thickness, style options |
| Function | Description | Key Features |
|---|---|---|
apply_gaussian_blur(image, kernel_size=15) |
Gaussian blur filter | Auto odd kernel size |
apply_vintage_filter(image, intensity=0.5) |
Vintage/sepia effect | Adjustable intensity |
apply_cartoon_filter(image) |
Cartoon effect | Style parameters |
apply_motion_blur(image, size=15, angle=0) |
Motion blur effect | Direction control |
apply_emboss_filter(image) |
Emboss effect | Strength, direction |
apply_pencil_sketch(image, strength=0.5) |
Pencil sketch effect | Color/grayscale options |
apply_hdr_effect(image) |
HDR effect | Intensity control |
apply_custom_kernel(image, kernel) |
Apply custom convolution | Border handling options |
| Function | Description | Key Features |
|---|---|---|
rotate_image(image, angle, center=None) |
Rotate images | Auto center, border handling |
flip_image(image, direction='horizontal') |
Flip images | Multiple directions |
apply_perspective_transform(image, src_points, dst_points) |
Perspective transformation | Auto size preservation |
apply_fisheye_effect(image, strength=0.5) |
Fisheye lens effect | Adjustable strength |
warp_image(image, transform_matrix) |
Apply affine/perspective warp | Border handling |
translate_image(image, x_shift, y_shift) |
Translate images | Border handling |
resize_with_padding(image, width, height) |
Resize with padding | Border color, position |
apply_barrel_distortion(image, strength=0.5) |
Barrel distortion | Center point, strength |
| Function | Description | Key Features |
|---|---|---|
fps_counter() |
FPS measurement | Running average, display |
color_picker(image) |
Interactive color picking | RGB/HSV display, zoom |
image_comparison(image1, image2, method='side_by_side') |
Compare images | Multiple methods |
create_image_grid(images, grid_size) |
Create image grids | Auto-sizing, padding, titles |
apply_watermark(image, text) |
Add watermarks | Position, opacity |
get_dominant_colors(image, num_colors=5) |
Extract dominant colors | K-means clustering |
auto_canny(image, sigma=0.33) |
Automatic edge detection | Adaptive thresholds |
get_image_hash(image, hash_method='phash') |
Generate image hash | Multiple algorithms |
from easy_opencv import cv
# Load and process an image with error handling
try:
image = cv.load_image('input.jpg', mode='rgb')
except Exception as e:
print(f"Error loading image: {e}")
image = cv.create_blank_image(800, 600, color=(240, 240, 240)) # Create blank image as fallback
# Get image information
info = cv.get_image_info(image)
print(f"Image size: {info['width']}x{info['height']}, {info['channels']} channels, {info['dtype']} type")
# Resize with aspect ratio preservation (multiple methods available)
resized = cv.resize_image(image, width=800, method='lanczos') # Higher quality algorithm
# Apply enhancement pipeline
enhanced = image.copy()
enhanced = cv.remove_noise(enhanced, method='bilateral') # Preserve edges while removing noise
enhanced = cv.adjust_brightness_contrast(enhanced, brightness=10, contrast=1.2)
enhanced = cv.apply_unsharp_mask(enhanced, radius=2.0, amount=1.0) # Sharpen details
# Create side-by-side comparison with labels
comparison = cv.image_comparison(image, enhanced, method='side_by_side', labels=['Original', 'Enhanced'])
cv.save_image(comparison, 'comparison.jpg', quality=95)from easy_opencv import cv
import time
# Start the FPS counter
fps = cv.fps_counter()
# Load an image with faces
image = cv.load_image('group_photo.jpg', mode='rgb')
# Face detection with confidence control
faces = cv.detect_faces(image, scale_factor=1.1, min_neighbors=5, min_size=(30, 30))
print(f"Found {len(faces)} faces in the image")
# For each face, detect features and add annotations
result = image.copy()
for i, (x, y, w, h) in enumerate(faces):
# Extract the face region
face_img = cv.crop_image(image, x, y, w, h)
# Get the face region information
face_info = f"Face {i+1}"
# Detect eyes within this face
eyes = cv.detect_eyes(face_img)
if len(eyes) > 0:
face_info += f" ({len(eyes)} eyes)"
# Try to detect a smile
smile_detected = cv.detect_smile(face_img)
if smile_detected:
face_info += ", smiling"
# Draw enhanced bounding box with information
result = cv.draw_rectangle(result, (x, y), (x+w, y+h), color=(0, 255, 0), thickness=2)
result = cv.draw_text(result, face_info, (x, y-10), font_scale=0.5,
color=(255, 255, 255), background=True, bg_color=(0, 128, 0))
# Color-based object detection in HSV space for more robust detection
red_mask = cv.color_detection(image, target_color='red', color_space='hsv', tolerance=15)
red_objects = cv.detect_contours(red_mask, min_area=100)
print(f"Found {len(red_objects)} red objects")
# Add red object outlines to the result
result = cv.draw_contour(result, red_objects, color=(0, 0, 255), thickness=2)
# Calculate and display FPS
fps_value = fps.get()
result = cv.draw_text(result, f"FPS: {fps_value:.1f}", (10, 30), font_scale=0.7,
color=(255, 255, 255), background=True)
# Save the final result
cv.save_image(result, 'detection_results.jpg')from easy_opencv import cv
# Load two images for feature matching
img1 = cv.load_image('scene.jpg', mode='rgb')
img2 = cv.load_image('object.jpg', mode='rgb')
# Detect keypoints and compute descriptors (SIFT by default)
keypoints1, descriptors1 = cv.detect_keypoints(img1, detector='sift')
keypoints2, descriptors2 = cv.detect_keypoints(img2, detector='sift')
print(f"Found {len(keypoints1)} keypoints in image 1")
print(f"Found {len(keypoints2)} keypoints in image 2")
# Match features between images
matches = cv.match_features(descriptors1, descriptors2, method='flann', ratio_threshold=0.7)
print(f"Found {len(matches)} good matches")
# Draw matches between images
match_img = cv.draw_matches(img1, keypoints1, img2, keypoints2, matches)
# Draw keypoints on original images
img1_kp = cv.draw_keypoints(img1, keypoints1)
img2_kp = cv.draw_keypoints(img2, keypoints2)
# Create a comparison grid
grid = cv.create_image_grid([img1_kp, img2_kp, match_img],
grid_size=(2, 2),
labels=["Image 1 Keypoints", "Image 2 Keypoints", "Matches"])
cv.show_image(grid, "Feature Matching")from easy_opencv import cv
import os
# Get information about a video file
video_info = cv.get_video_info('input_video.mp4')
print(f"Video dimensions: {video_info['width']}x{video_info['height']}")
print(f"Frame rate: {video_info['fps']:.2f} fps, Duration: {video_info['duration']:.2f} seconds")
print(f"Total frames: {video_info['frame_count']}, Codec: {video_info['codec']}")
# Extract frames with progress tracking
output_dir = 'extracted_frames'
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Extract every 10th frame (10% of the video) with progress feedback
frame_paths = cv.extract_frames('input_video.mp4', output_dir,
frame_interval=10,
show_progress=True,
filename_format='frame_{:04d}.jpg')
print(f"Extracted {len(frame_paths)} frames to {output_dir}")
# Process extracted frames with a filter
processed_frames = []
for frame_path in frame_paths:
frame = cv.load_image(frame_path)
processed = cv.apply_vintage_filter(frame, intensity=0.6)
output_path = frame_path.replace('.jpg', '_vintage.jpg')
cv.save_image(processed, output_path)
processed_frames.append(output_path)
# Create a new video from processed frames with custom settings
cv.create_video_from_frames(
processed_frames,
'vintage_video.mp4',
fps=24.0,
codec='mp4v', # Codec options: 'mp4v', 'avc1', 'xvid', etc.
size=None, # Auto-detect from first frame
is_color=True
)
# Motion detection with mask and visualization
cv.detect_motion(
'input_video.mp4',
'motion_output.mp4',
sensitivity=500,
min_area=500,
blur_size=15,
dilate_iterations=2,
draw_bounding_boxes=True,
show_progress=True
)from easy_opencv import cv
import numpy as np
# Create a blank canvas for drawing
canvas = cv.create_blank_image(800, 600, color=(240, 240, 240))
# Interactive color picker tool (click to get color values)
def on_color_pick(color, x, y):
print(f"Picked color at ({x}, {y}): RGB={color}, HEX=#{color[0]:02x}{color[1]:02x}{color[2]:02x}")
cv.color_picker(image, window_name='Color Picker', callback=on_color_pick)
# Compare image processing methods with custom layout
original = cv.load_image('sample.jpg')
methods = {
'Original': original,
'Grayscale': cv.convert_color_space(original, 'rgb', 'gray'),
'Blurred': cv.apply_gaussian_blur(original, kernel_size=15),
'Edges': cv.apply_edge_detection(original),
'Cartoon': cv.apply_cartoon_filter(original),
'Vintage': cv.apply_vintage_filter(original)
}
# Create a comparison with multiple layouts
comparisons = {
'Side by Side': cv.image_comparison(methods['Original'], methods['Cartoon'], method='side_by_side'),
'Slider': cv.image_comparison(methods['Original'], methods['Vintage'], method='slider'),
'Split': cv.image_comparison(methods['Original'], methods['Edges'], method='split'),
'Blend': cv.image_comparison(methods['Original'], methods['Blurred'], method='blend', alpha=0.5)
}
# Create image grid with auto-sizing and labels
grid = cv.create_image_grid(
list(methods.values()),
grid_size=(2, 3),
image_size=(300, 200), # Target size for each grid cell
padding=10, # Padding between images
background_color=(20, 20, 20),
labels=list(methods.keys())
)
# Add watermark
grid = cv.apply_watermark(
grid,
text="Easy OpenCV Demo",
position='bottom_right',
font_scale=0.8,
color=(255, 255, 255),
opacity=0.7
)
cv.show_image(grid, 'Effect Comparison')
# Analyze image histograms
hist = cv.calculate_histogram(original)
hist_image = cv.draw_histogram(hist, size=(600, 400))
cv.show_image(hist_image, 'RGB Histogram')from easy_opencv import cv
# Start webcam capture with options
def frame_processor(frame):
"""Process each frame from the webcam"""
# Apply real-time cartoon effect
cartoon = cv.apply_cartoon_filter(frame)
# Add FPS counter to the frame
fps = cv.fps_counter().get()
cartoon = cv.draw_text(cartoon, f"FPS: {fps:.1f}", (10, 30),
font_scale=0.7, color=(255, 255, 255), background=True)
return cartoon
# Start webcam capture with the frame processor
cv.webcam_capture(
camera_id=0, # Use default camera
frame_processor=frame_processor,
window_name="Cartoon Webcam",
save_path="webcam_recording.mp4", # Optional recording
record_fps=30.0,
width=640,
height=480
)Error: ModuleNotFoundError: No module named 'easy_opencv_wrapper'
Solution: Use the correct import statement: from easy_opencv import cv
Error: ModuleNotFoundError: No module named 'easy-opencv'
Solution: The package name uses underscores in imports, not hyphens: from easy_opencv import cv
Error: AttributeError: 'EasyCV' object has no attribute 'open_webcam'
Solution: Use cv.load_video(0) instead for webcam access, or the WebcamCapture class.
Error: Webcam freezes when using show_image in a loop
Solution: Set wait=False in cv.show_image() when using it in a video loop.
# Correct way to use show_image in a video loop
while True:
ret, frame = video.read()
if not ret:
break
cv.show_image(frame, 'Video', wait=False) # Set wait=False to prevent blocking
if cv2.waitKey(1) & 0xFF == ord('q'):
breakError: No key detection when processing video frames
Solution: Use direct OpenCV for keyboard detection:
import cv2 # Import OpenCV directly for keyboard handling
# In your video loop
if cv2.waitKey(1) & 0xFF == ord('q'):
break # Exit on 'q' key pressIf you encounter problems not covered in this troubleshooting guide:
- Check our Documentation folder for more examples
- See DIFFERENCE.md for detailed code comparisons
- File an issue on our GitHub repository
- Join our community Discord server for live help
Remember that Easy OpenCV is a wrapper around OpenCV, so you can always mix both APIs when needed for specific functionality.
- Python 3.7+: Core language support
- OpenCV 4.5.0+: Core computer vision functionality
- NumPy 1.19.0+: Numerical processing
- Pillow 8.0.0+: Image processing support
| Resource | Description |
|---|---|
| DIFFERENCES.md | 22+ Side-by-side code comparisons between OpenCV and Easy OpenCV for common tasks |
| EASY_OPENCV_BENEFITS.md | Detailed analysis of benefits and performance considerations |
| USAGE_GUIDE.md | Comprehensive guide with detailed explanations and step-by-step tutorials |
| WHY_EASY_OPENCV.md | In-depth explanation of design philosophy and technical benefits |
| PROJECT_STRUCTURE.md | Package organization and module overview for developers |
| TEST_ANALYSIS_REPORT.md | Detailed test coverage analysis and recommendations |
| DEBUGGED_SUMMARY.md | Summary of debugging processes and resolved issues |
# Install the package
pip install easy-opencv
# Import the library
from easy_opencv import cv
# Load an image and convert to RGB in one line
img = cv.load_image('photo.jpg', mode='rgb')
# Apply multiple effects sequentially
enhanced = cv.adjust_brightness_contrast(img, brightness=10, contrast=1.2)
cartoon = cv.apply_cartoon_filter(enhanced)
# Show the result and save
cv.show_image(cartoon, "Cartoon Effect")
cv.save_image(cartoon, "cartoon_result.jpg")- Write 50-70% less code for common computer vision tasks
- Eliminate complex parameters with intuitive function calls
- Avoid common errors with built-in validation
- Improve readability with consistent API design
- Learn computer vision with intuitive function names
- Simplify color space handling with semantic naming
For developers already familiar with OpenCV, Easy OpenCV makes your code cleaner and more maintainable. For newcomers to computer vision, it provides a gentle learning curve with powerful functionality.
See the EASY_OPENCV_BENEFITS.md document for a detailed analysis of these benefits.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with β€οΈ for computer vision enthusiasts everywhere
Easy OpenCV - Computer vision made simple