К основному содержанию
правило

opencv-python — правило для Cursor: что делает и как установить

Набор инструкций для Cursor, нацеленный на быстрый код компьютерного зрения на Python. Правило запрещает циклы по пикселям и требует векторизации.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/opencv-python.mdc
Открыть на GitHub

Что делает opencv-python

Правило задаёт стандарты написания кода с opencv-python для всех файлов **/*.py. Главное требование — отказ от ручных циклов перебора пикселей в пользу векторных операций NumPy и оптимизированных C++ вызовов OpenCV. Логика разбивается на небольшие функции вместо монолитных сценариев.

Инструкции напоминают о проверке результата cv2.imread, который возвращает None при сбоях чтения. Без этой проверки скрипты падают при первом отсутствующем файле. Также правило требует явно следить за порядком каналов BGR и RGB при выводе через Matplotlib и контролировать типы данных вроде np.uint8 и np.float32.

Для всех функций обязательны аннотации типов с numpy.ndarray. Копирование массивов через copy() разрешено только при необходимости независимой правки, чтобы срезы не тратили оперативную память впустую.

Какие задачи решает

  • устранить медленные циклы по пикселям с помощью векторизации
  • предотвратить падения из-за непроверенного результата cv2.imread
  • исправить искажения цветов при передаче BGR-картинок в Matplotlib
  • настроить строгую типизацию аргументов с numpy.ndarray

Примеры запросов агенту

  • Напиши функцию инверсии цветов без циклов по пикселям
  • Сделай модульный конвейер детекции границ Canny для входного изображения
  • Добавь безопасную загрузку картинки с проверкой на None и конвертацией в RGB

Как установить opencv-python

Вручную: положить файлы

.cursor/rules/opencv-python.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о opencv-python

Как установить opencv-python в Cursor?

Сохраните файл правила по пути .cursor/rules/opencv-python.mdc в корне вашего проекта. Cursor автоматически применит его ко всем файлам с маской **/*.py.

Что делает правило opencv-python?

Оно заставляет модель генерировать векторизованный код вместо вложенных циклов по пикселям. Правило следит за разделением логики на функции, типизацией массивов и контролем форматов данных.

Как правило решает проблему с порядком цветов BGR и RGB?

Инструкция требует явного вызова cv2.cvtColor при работе со сторонними библиотеками вроде Matplotlib. Это исключает показ искажённых цветовых каналов.

Исходный текст

opencv-python.mdc · CC0-1.0
---
description: This guide provides definitive, opinionated best practices for writing high-performance, maintainable, and robust `opencv-python` code in Python applications.
globs: **/*.py
---
# `opencv-python` Best Practices

`opencv-python` is the de-facto standard for computer vision in Python. To write efficient, reliable, and maintainable code, treat OpenCV objects as NumPy arrays and prioritize vectorized operations. This guide outlines the essential practices for our team.

## Core Philosophy: Vectorize Everything

OpenCV functions are C++ optimized. Leverage them directly or use NumPy's vectorized operations instead of explicit Python loops for pixel-wise processing. This is the single most important performance rule.

❌ **BAD: Pixel-wise loop**
```python
import cv2
import numpy as np

def invert_image_slow(image: np.ndarray) -> np.ndarray:
    """Inverts an image pixel by pixel (slow)."""
    h, w, c = image.shape
    inverted_image = np.zeros_like(image)
    for y in range(h):
        for x in range(w):
            inverted_image[y, x] = 255 - image[y, x]
    return inverted_image
```

✅ **GOOD: Vectorized operation**
```python
import cv2
import numpy as np

def invert_image_fast(image: np.ndarray) -> np.ndarray:
    """Inverts an image using vectorized NumPy (fast)."""
    return 255 - image

# Or using OpenCV's built-in function for more complex ops
def convert_to_grayscale(image: np.ndarray) -> np.ndarray:
    """Converts an image to grayscale using cv2 (fast)."""
    return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
```

## Code Organization and Structure

Organize your vision pipelines into small, focused functions. Each function should perform a single, well-defined image processing step.

❌ **BAD: Monolithic script**
```python
import cv2
import numpy as np

# main.py
img = cv2.imread('input.jpg')
if img is None:
    print("Error loading image")
    exit()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blurred, 50, 150)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output_edges.jpg', edges)
```

✅ **GOOD: Modular functions**
```python
import cv2
import numpy as np
from typing import Optional

def load_image(path: str) -> Optional[np.ndarray]:
    """Loads an image, checking for errors."""
    img = cv2.imread(path)
    if img is None:
        print(f"Error: Could not load image from {path}")
    return img

def preprocess_image(image: np.ndarray) -> np.ndarray:
    """Applies grayscale, blur, and Canny edge detection."""
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)
    return edges

def display_image(window_name: str, image: np.ndarray) -> None:
    """Displays an image and waits for a key press."""
    cv2.imshow(window_name, image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# main.py
if __name__ == "__main__":
    input_path = 'input.jpg'
    output_path = 'output_edges.jpg'

    original_img = load_image(input_path)
    if original_img is not None:
        processed_img = preprocess_image(original_img)
        display_image('Processed Edges', processed_img)
        cv2.imwrite(output_path, processed_img)
```

## Common Pitfalls and Gotchas

### 1. `cv2.imread` Returns `None`

Always check the return value of `cv2.imread`. It returns `None` if the image cannot be found or loaded.

❌ **BAD: Assuming image load success**
```python
img = cv2.imread('non_existent.jpg')
# This will crash if img is None
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
```

✅ **GOOD: Robust image loading**
```python
img = cv2.imread('non_existent.jpg')
if img is None:
    raise FileNotFoundError("Image not found or could not be loaded.")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
```

### 2. Color Space Mismatches (BGR vs RGB)

OpenCV uses BGR (Blue, Green, Red) as its default color order for images. Matplotlib and many other libraries use RGB. Be explicit with conversions.

❌ **BAD: Displaying BGR as RGB**
```python
import matplotlib.pyplot as plt
img_bgr = cv2.imread('image.jpg')
plt.imshow(img_bgr) # Colors will be wrong
plt.show()
```

✅ **GOOD: Explicit color conversion**
```python
import matplotlib.pyplot as plt
img_bgr = cv2.imread('image.jpg')
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
plt.imshow(img_rgb)
plt.show()
```

### 3. Data Type Mismatches

OpenCV functions expect specific data types (e.g., `np.uint8` for most image operations, `np.float32` for some calculations like `cv2.filter2D`). Always ensure your image data has the correct `dtype`.

❌ **BAD: Incorrect data type for operations**
```python
img_float = np.random.rand(100, 100, 3) # float64
# This will likely fail or produce unexpected results
edges = cv2.Canny(img_float, 50, 150)
```

✅ **GOOD: Explicit type casting**
```python
img_float = np.random.rand(100, 100, 3).astype(np.float32) * 255
img_uint8 = img_float.astype(np.uint8)
edges = cv2.Canny(img_uint8, 50, 150)
```

## Type Hints

Always use Python type hints, especially for function arguments and return values involving `numpy.ndarray`. This improves code readability, enables static analysis, and reduces bugs.

```python
import numpy as np
import cv2
from typing import Tuple

def resize_image(image: np.ndarray, new_size: Tuple[int, int]) -> np.ndarray:
    """
    Resizes an image to the specified (width, height).
    Args:
        image: The input image as a NumPy array.
        new_size: A tuple (width, height) for the new dimensions.
    Returns:
        The resized image.
    """
    return cv2.resize(image, new_size)

# Example usage
img = cv2.imread('input.jpg')
if img is not None:
    resized_img = resize_image(img, (640, 480))
```

## Performance Considerations

1.  **Prefer `cv2` functions**: They are highly optimized C++ implementations.
2.  **Vectorize with NumPy**: For operations not directly available in `cv2`, use NumPy's vectorized functions.
3.  **Avoid unnecessary copies**: Operations like `img[y1:y2, x1:x2]` create views, which are efficient. `img.copy()` creates a new array. Use `copy()` only when you intend to modify the subset independently.
4.  **Image `dtype`**: Stick to `np.uint8` for most image storage. Convert to `np.float32` or `np.float64` only for mathematical operations requiring higher precision, then convert back if needed.
5.  **Batch Processing**: If processing many images, consider loading and processing them in batches where possible, especially for deep learning inference.

## Virtual Environments and Packaging

Always use virtual environments (`venv` or `conda`) to isolate project dependencies. Pin `opencv-python` and `numpy` versions in `requirements.txt` for reproducibility.

```bash
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows

# Install packages
pip install opencv-python==4.12.0.88 numpy<2.0 # For Python < 3.9
# pip install opencv-python==4.12.0.88 numpy<2.3.0,>=2 # For Python >= 3.9
```

`requirements.txt`:
```
opencv-python==4.12.0.88
numpy<2.0; python_version < "3.9"
numpy<2.3.0,>=2; python_version >= "3.9"
```

## Testing Approaches

Implement unit and integration tests for your image processing pipelines. `pytest` is the recommended framework.

1.  **Unit Tests**: Test individual image processing functions with known inputs and expected outputs.
2.  **Integration Tests**: Test the entire pipeline with sample images, verifying the final output.
3.  **Image Comparison**: For asserting image correctness, load a reference image and compare it pixel-wise using `numpy.array_equal` or a perceptual difference metric.

```python
# tests/test_image_processing.py
import pytest
import numpy as np
import cv2
from my_module import preprocess_image, load_image

def test_preprocess_image_grayscale():
    """Test if preprocess_image correctly grayscales and blurs."""
    # Create a dummy color image (BGR)
    dummy_img = np.zeros((10, 10, 3), dtype=np.uint8)
    dummy_img[:, :, 0] = 255 # Blue channel
    dummy_img[:, :, 1] = 128 # Green channel
    dummy_img[:, :, 2] = 64  # Red channel

    processed_img = preprocess_image(dummy_img)

    # Expected output for grayscale of (255, 128, 64) is ~125
    # Canny output is binary, so check shape and type
    assert processed_img.shape == (10, 10) # Grayscale, then Canny
    assert processed_img.dtype == np.uint8
    # Further checks could involve comparing with a pre-computed reference image
    # For example:
    # expected_edges = cv2.imread('tests/ref_edges.png', cv2.IMREAD_GRAYSCALE)
    # assert np.array_equal(processed_img, expected_edges)
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «ИИ и ML» →
opencv tondevrel Скилл подключает OpenCV к агенту: чтение и запись картинок, детекция краёв, контуров, лиц, трекинг объектов в видео. CX Codex +1 308установок computer-vision-opencv Mindrally Скилл задаёт агенту рамки работы с изображениями и видео: OpenCV, PyTorch, аугментации, трекинг. Пригодится, когда в проекте есть пайплайны обработки кадров. CX Codex +1 3 800установок data-jupyter-python Mindrally Задаёт агенту правила работы с pandas, numpy, matplotlib и seaborn: векторизация вместо циклов, воспроизводимые ноутбуки, аккуратные графики. CX Codex +1 865установок zarr-python K-Dense-AI Помогает организовать хранение и выборку многомерных массивов в Zarr-Python 3. Пригодится при настройке чанков, шардинга и чтения данных из облачных хранилищ. CX Codex +1 1 900установок amc-run-sample-calibration Shubham Agrawal Скилл выполняет калибровку на тестовом архиве синтетических камер склада для проверки развёрнутого микросервиса AutoMagicCalib. Пригодится для проверки работы стека перед боевыми данными. CX Codex +1 639установок matplotlib K-Dense-AI Скилл для построения и тонкой настройки научных графиков на Matplotlib: от отдельных осей до многопанельных фигур и экспорта в PNG, PDF и SVG. CX Codex +1 2 200установок

Из того же набора240

Весь набор →
phoenix Правило для Cursor задаёт, как писать Phoenix-приложения на Elixir: контексты, форматирование, тесты. Пригодится, если агент уже правит ваш код. ★ 3 580звёзд репо peewee Задаёт стандарты работы с ORM Peewee в Python: настройку BaseModel, внешние ключи с backref, транзакции atomic и защиту от проблемы N+1. ★ 3 580звёзд репо pdoc Правило задаёт формат docstring и type hints в Python-коде, который документируется через pdoc. Пригодится, когда нужно привести описание публичного API к единому виду. ★ 3 580звёзд репо pandas Правило для Cursor задаёт стиль работы с pandas: векторизация вместо циклов, явные .loc и .iloc, экономные типы данных. Пригодится, если агент часто пишет медленный код. ★ 3 580звёзд репо openai Правило помогает вести проект с OpenAI API: хранить промпты отдельно, правильно создавать клиент и задавать модели чёткие инструкции. Пригодится при разработке на Python. ★ 3 580звёзд репо nuxt Правило для Cursor задаёт агенту стиль кода в Nuxt-проекте: структура каталогов, Composition API, Pinia, useFetch. Пригодится, если агент уже начал плодить миксины и onMounted вместо SSR-фетча. ★ 3 580звёзд репо numpy Правило заставляет Cursor генерировать векторизованный код NumPy без медленных циклов Python. Помогает писать быстрые модульные функции с явным указанием dtype. ★ 3 580звёзд репо numba Правило задаёт практики для Numba-кода на Python: CPU-ускорение, CUDA-ядра и работу с массивами. Пригодится для численных задач в .py. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой