OpenCV چیست؟ آموزش کامل پردازش تصویر و ویدئو با پایتون

در این آموزش جامع OpenCV، نصب کتابخانه، خواندن و ویرایش تصویر، رنگ، فیلتر، Threshold، تشخیص لبه و کانتور، پردازش ویدئو، ساخت اسکنر سند و اتصال تصویر به هوش مصنوعی درواره را عملی یاد می‌گیرید.

Share
OpenCV چیست؟ آموزش کامل پردازش تصویر و ویدئو با پایتون

بینایی ماشین یا Computer Vision یکی از مهم‌ترین حوزه‌های هوش مصنوعی است. در این حوزه تلاش می‌کنیم کامپیوتر بتواند تصویر و ویدئو را پردازش کند، اجزای آن را تشخیص دهد، اطلاعات بصری را استخراج کند و براساس آن خروجی ساختاریافته تولید کند.

OpenCV یکی از شناخته‌شده‌ترین کتابخانه‌های متن‌باز برای پردازش تصویر و ویدئو است. این کتابخانه ابزارهایی برای خواندن تصویر، تغییر اندازه، تبدیل رنگ، کاهش نویز، تشخیص لبه، استخراج کانتور، پردازش ویدئو و اجرای مدل‌های بینایی ماشین ارائه می‌دهد.

در این مقاله یاد می‌گیرید:

  • OpenCV چیست و چه کاربردهایی دارد
  • چگونه OpenCV را در پایتون نصب کنید
  • تفاوت پکیج‌های مختلف OpenCV چیست
  • تصویر در OpenCV چگونه ذخیره می‌شود
  • چگونه تصویر را بخوانید، نمایش دهید و ذخیره کنید
  • چگونه Crop، Resize، Rotate و Flip انجام دهید
  • چگونه فضای رنگ را تغییر دهید
  • چگونه Blur، Threshold و Morphology اعمال کنید
  • چگونه لبه و Contour اشیا را استخراج کنید
  • چگونه ویدئو و وب‌کم را پردازش کنید
  • چگونه یک اسکنر ساده سند بسازید
  • چگونه تصویر را برای تحلیل به API هوش مصنوعی درواره بفرستید

OpenCV چیست؟

OpenCV مخفف Open Source Computer Vision Library است. این کتابخانه مجموعه بزرگی از الگوریتم‌ها و ابزارهای پردازش تصویر، ویدئو و بینایی ماشین را ارائه می‌کند.

OpenCV در اصل با C++ توسعه داده شده، اما Binding رسمی پایتون آن باعث می‌شود بتوانیم بسیاری از قابلیت‌های کتابخانه را با کد پایتون استفاده کنیم.

طبق مستندات رسمی OpenCV، این کتابخانه ماژول‌هایی برای پردازش تصویر، تحلیل ویدئو، کالیبراسیون دوربین، استخراج Feature، Machine Learning و اجرای شبکه‌های عصبی دارد.

کاربردهای رایج OpenCV عبارت‌اند از:

  • تغییر اندازه و فرمت تصویر
  • Crop خودکار تصویر
  • بهبود اولیه کیفیت تصویر
  • کاهش Noise
  • تشخیص لبه و شکل
  • شمارش اشیای ساده
  • خواندن فریم‌های ویدئو
  • استخراج Thumbnail از ویدئو
  • آماده‌سازی ورودی مدل‌های هوش مصنوعی
  • ساخت اسکنر سند
  • تشخیص ناحیه متن پیش از OCR
  • پردازش تصویر محصول
  • تشخیص تغییر میان دو تصویر
  • ساخت Dataset بینایی ماشین
  • رسم Bounding Box و Label

تفاوت پردازش تصویر و بینایی ماشین

این دو عبارت مرتبط‌اند، اما دقیقاً یکسان نیستند.

پردازش تصویر

در Image Processing معمولاً ورودی و خروجی هر دو تصویر هستند.

برای مثال:

  • کاهش Noise
  • افزایش Contrast
  • Resize
  • Threshold
  • Sharpen
  • حذف بخش‌های اضافی
  • تغییر فضای رنگ

بینایی ماشین

در Computer Vision هدف استخراج مفهوم یا اطلاعات از تصویر است.

برای مثال:

  • چه اشیایی در تصویر وجود دارند؟
  • محل هر شیء کجاست؟
  • تصویر متعلق به کدام دسته است؟
  • چه متنی در تصویر نوشته شده؟
  • آیا میان دو تصویر تغییر مهمی رخ داده است؟

OpenCV برای پردازش کلاسیک تصویر بسیار قدرتمند است و می‌تواند پیش‌پردازش ورودی مدل‌های هوش مصنوعی را نیز انجام دهد.

نصب OpenCV در پایتون

ابتدا محیط مجازی بسازید:

python -m venv .venv

فعال‌سازی در ویندوز:

.venv\Scripts\activate

فعال‌سازی در Linux یا macOS:

source .venv/bin/activate

به‌روزرسانی Pip:

python -m pip install --upgrade pip

نصب نسخه اصلی:

python -m pip install opencv-python

برای مثال‌های این آموزش:

python -m pip install opencv-python numpy matplotlib pillow requests

بررسی نصب:

python -c "import cv2; print(cv2.__version__)"

نکته مهم این است که نام پکیج هنگام نصب opencv-python و نام ماژول هنگام Import برابر cv2 است:

import cv2

نباید از دستور زیر استفاده کنید:

pip install cv2

تفاوت پکیج‌های OpenCV

چند پکیج رایج برای OpenCV در PyPI وجود دارد.

پکیجکاربرد
opencv-pythonماژول‌های اصلی همراه قابلیت‌های GUI
opencv-contrib-pythonماژول‌های اصلی به‌علاوه Contrib
opencv-python-headlessنسخه بدون وابستگی‌های GUI برای سرور
opencv-contrib-python-headlessنسخه Contrib بدون GUI

برای لپ‌تاپ و اجرای cv2.imshow:

python -m pip install opencv-python

برای سرور، Docker، FastAPI یا محیطی که پنجره گرافیکی ندارد:

python -m pip install opencv-python-headless

برای قابلیت‌های اضافه Contrib:

python -m pip install opencv-contrib-python

معمولاً نباید چند نسخه مختلف را هم‌زمان در یک محیط نصب کنید. اگر قبلاً چند نسخه نصب شده‌اند:

python -m pip uninstall \
    opencv-python \
    opencv-contrib-python \
    opencv-python-headless \
    opencv-contrib-python-headless

سپس فقط نسخه موردنیاز را نصب کنید.

تصویر در OpenCV چگونه نمایش داده می‌شود؟

تصویر در OpenCV یک آرایه NumPy است.

import cv2

image = cv2.imread(
    "sample.jpg"
)

print(type(image))
print(image.shape)
print(image.dtype)

برای یک تصویر رنگی، Shape معمولاً چنین است:

(height, width, channels)

برای مثال:

(900, 1600, 3)

یعنی:

  • ارتفاع: ۹۰۰ پیکسل
  • عرض: ۱۶۰۰ پیکسل
  • تعداد Channel: سه

مقادیر تصویر معمولی اغلب از نوع uint8 و در بازه صفر تا ۲۵۵ هستند.

ترتیب رنگ BGR در OpenCV

OpenCV تصاویر رنگی را به‌صورت پیش‌فرض با ترتیب BGR می‌خواند:

Blue, Green, Red

اما ابزارهایی مانند Matplotlib معمولاً انتظار RGB دارند:

Red, Green, Blue

به همین دلیل اگر تصویر OpenCV را مستقیم با Matplotlib نمایش دهید، ممکن است رنگ قرمز و آبی جابه‌جا شوند.

تبدیل BGR به RGB:

rgb_image = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2RGB
)

خواندن تصویر با cv2.imread

import cv2

image = cv2.imread(
    "sample.jpg"
)

همیشه نتیجه را بررسی کنید:

if image is None:
    raise FileNotFoundError(
        "Image could not be loaded"
    )

براساس راهنمای رسمی OpenCV، تابع imread تصویر را از مسیر مشخص‌شده می‌خواند و در قالب یک آرایه برمی‌گرداند.

حالت‌های متداول:

color_image = cv2.imread(
    "sample.jpg",
    cv2.IMREAD_COLOR
)

gray_image = cv2.imread(
    "sample.jpg",
    cv2.IMREAD_GRAYSCALE
)

unchanged_image = cv2.imread(
    "sample.png",
    cv2.IMREAD_UNCHANGED
)

IMREAD_UNCHANGED می‌تواند Alpha Channel فایل PNG را نیز حفظ کند.

مشکل مسیر یا نام فارسی فایل

در بعضی محیط‌ها، cv2.imread ممکن است با مسیرهای دارای نویسه فارسی یا Unicode مشکل داشته باشد. یک روش جایگزین:

import cv2
import numpy as np

def read_image_unicode(path):
    file_bytes = np.fromfile(
        path,
        dtype=np.uint8
    )

    image = cv2.imdecode(
        file_bytes,
        cv2.IMREAD_UNCHANGED
    )

    if image is None:
        raise ValueError(
            f"Cannot decode image: {path}"
        )

    return image

استفاده:

image = read_image_unicode(
    "تصاویر/محصول.jpg"
)

نمایش تصویر روی کامپیوتر

cv2.imshow(
    "Image",
    image
)

cv2.waitKey(0)
cv2.destroyAllWindows()

waitKey(0) منتظر فشردن یک کلید می‌ماند.

در سرور یا نسخه Headless نمی‌توانید از imshow استفاده کنید. در این محیط‌ها تصویر را ذخیره کنید یا در Notebook با Matplotlib نمایش دهید.

نمایش تصویر در Jupyter و Google Colab

import matplotlib.pyplot as plt

rgb_image = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2RGB
)

plt.figure(
    figsize=(10, 6)
)

plt.imshow(rgb_image)
plt.axis("off")
plt.show()

برای تصویر Grayscale:

plt.imshow(
    gray_image,
    cmap="gray"
)

plt.axis("off")
plt.show()

ذخیره تصویر

success = cv2.imwrite(
    "output.jpg",
    image
)

if not success:
    raise IOError(
        "Image could not be saved"
    )

تنظیم کیفیت JPEG:

cv2.imwrite(
    "output.jpg",
    image,
    [
        cv2.IMWRITE_JPEG_QUALITY,
        90
    ]
)

تنظیم فشرده‌سازی PNG:

cv2.imwrite(
    "output.png",
    image,
    [
        cv2.IMWRITE_PNG_COMPRESSION,
        6
    ]
)

کیفیت JPEG معمولاً بین صفر تا ۱۰۰ است. کیفیت بیشتر معمولاً حجم فایل را نیز افزایش می‌دهد.

ذخیره فایل با مسیر فارسی

from pathlib import Path
import cv2

def write_image_unicode(
    path,
    image,
    extension=".jpg",
    params=None
):
    path = Path(path)

    if params is None:
        params = []

    success, encoded = cv2.imencode(
        extension,
        image,
        params
    )

    if not success:
        raise ValueError(
            "Image encoding failed"
        )

    encoded.tofile(
        str(path)
    )

استفاده:

write_image_unicode(
    "خروجی/تصویر.jpg",
    image,
    extension=".jpg",
    params=[
        cv2.IMWRITE_JPEG_QUALITY,
        90
    ]
)

دسترسی به پیکسل‌ها

height, width = image.shape[:2]

print("Width:", width)
print("Height:", height)

دریافت پیکسل:

blue, green, red = image[
    100,
    200
]

print(blue, green, red)

تغییر یک پیکسل:

image[100, 200] = [
    0,
    0,
    255
]

برای تغییر ناحیه، بهتر است از Slicing استفاده شود:

image[
    50:150,
    100:300
] = [0, 0, 255]

حلقه‌زدن روی تک‌تک پیکسل‌ها در پایتون معمولاً کند است. عملیات برداری NumPy و توابع OpenCV انتخاب بهتری هستند.

Crop کردن تصویر

cropped = image[
    100:500,
    200:900
]

ترتیب Slicing چنین است:

image[y1:y2, x1:x2]

اعتبارسنجی مختصات:

x1 = max(
    0,
    min(x1, width)
)

x2 = max(
    0,
    min(x2, width)
)

y1 = max(
    0,
    min(y1, height)
)

y2 = max(
    0,
    min(y2, height)
)

if x2 <= x1 or y2 <= y1:
    raise ValueError(
        "Invalid crop coordinates"
    )

cropped = image[
    y1:y2,
    x1:x2
]

تغییر اندازه تصویر

resized = cv2.resize(
    image,
    (800, 450)
)

در OpenCV ترتیب اندازه برابر است با:

(width, height)

نه ارتفاع و عرض.

حفظ نسبت تصویر

def resize_keep_aspect(
    image,
    target_width=None,
    target_height=None
):
    height, width = image.shape[:2]

    if (
        target_width is None
        and target_height is None
    ):
        return image.copy()

    if target_width is not None:
        scale = (
            target_width / width
        )

        new_width = target_width
        new_height = int(
            height * scale
        )
    else:
        scale = (
            target_height / height
        )

        new_height = target_height
        new_width = int(
            width * scale
        )

    interpolation = (
        cv2.INTER_AREA
        if scale < 1
        else cv2.INTER_CUBIC
    )

    return cv2.resize(
        image,
        (
            new_width,
            new_height
        ),
        interpolation=interpolation
    )

استفاده:

small_image = resize_keep_aspect(
    image,
    target_width=800
)

روش‌های رایج Interpolation:

روشکاربرد معمول
INTER_AREAکوچک‌کردن تصویر
INTER_LINEARتغییر اندازه عمومی
INTER_CUBICبزرگ‌کردن با کیفیت بهتر و سرعت کمتر
INTER_NEARESTMask و Labelهای دسته‌ای

برای Resize کردن Mask دسته‌بندی از INTER_NEAREST استفاده کنید تا مقدارهای Class با هم ترکیب نشوند.

Rotate کردن تصویر

چرخش ۹۰ درجه:

rotated = cv2.rotate(
    image,
    cv2.ROTATE_90_CLOCKWISE
)

گزینه‌های دیگر:

cv2.ROTATE_90_COUNTERCLOCKWISE
cv2.ROTATE_180

چرخش با زاویه دلخواه:

height, width = image.shape[:2]

center = (
    width / 2,
    height / 2
)

rotation_matrix = (
    cv2.getRotationMatrix2D(
        center,
        angle=15,
        scale=1.0
    )
)

rotated = cv2.warpAffine(
    image,
    rotation_matrix,
    (
        width,
        height
    ),
    borderMode=cv2.BORDER_REPLICATE
)

این روش ممکن است گوشه‌های تصویر را Crop کند. اگر حفظ تمام تصویر مهم است باید اندازه Canvas جدید محاسبه شود.

Flip کردن تصویر

افقی:

horizontal = cv2.flip(
    image,
    1
)

عمودی:

vertical = cv2.flip(
    image,
    0
)

هر دو جهت:

both = cv2.flip(
    image,
    -1
)

Flip در Data Augmentation نیز کاربرد دارد، اما باید با معنای داده سازگار باشد.

تبدیل فضای رنگ

BGR به RGB

rgb = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2RGB
)

BGR به Grayscale

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

BGR به HSV

hsv = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2HSV
)

BGR به LAB

lab = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2LAB
)

کاربردهای متداول:

  • Grayscale: Threshold، Edge Detection و کاهش حجم محاسبات
  • HSV: جداسازی رنگ از روشنایی
  • LAB: تحلیل روشنایی و تفاوت رنگ
  • RGB: نمایش در Matplotlib و بسیاری از مدل‌ها

جداسازی یک محدوده رنگ با HSV

import numpy as np

hsv = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2HSV
)

lower_blue = np.array([
    90,
    70,
    50
])

upper_blue = np.array([
    130,
    255,
    255
])

mask = cv2.inRange(
    hsv,
    lower_blue,
    upper_blue
)

result = cv2.bitwise_and(
    image,
    image,
    mask=mask
)

محدوده رنگ باید با تصویر، نور محیط و دوربین تنظیم شود. Threshold ثابت در شرایط نوری متفاوت همیشه نتیجه یکسانی تولید نمی‌کند.

کاهش Noise و Blur

Gaussian Blur

blurred = cv2.GaussianBlur(
    image,
    (5, 5),
    0
)

اندازه Kernel باید معمولاً فرد باشد.

Median Blur

median = cv2.medianBlur(
    image,
    5
)

Median Blur برای بعضی Noiseهای نقطه‌ای مناسب است.

Bilateral Filter

bilateral = cv2.bilateralFilter(
    image,
    d=9,
    sigmaColor=75,
    sigmaSpace=75
)

Bilateral Filter تلاش می‌کند هم‌زمان Noise را کاهش و لبه‌ها را بهتر حفظ کند، اما از Gaussian Blur کندتر است.

Blur بیش از حد می‌تواند جزئیات واقعی تصویر را از بین ببرد.

افزایش Contrast با Histogram Equalization

برای تصویر Grayscale:

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

equalized = cv2.equalizeHist(
    gray
)

برای کنترل محلی بهتر می‌توان از CLAHE استفاده کرد:

clahe = cv2.createCLAHE(
    clipLimit=2.0,
    tileGridSize=(8, 8)
)

enhanced = clahe.apply(
    gray
)

CLAHE تصویر را به ناحیه‌های کوچک تقسیم می‌کند و Contrast را به‌صورت محلی تنظیم می‌کند.

افزایش Contrast همیشه به معنای افزایش اطلاعات واقعی تصویر نیست و ممکن است Noise را نیز برجسته کند.

Threshold کردن تصویر

Threshold یک تصویر Grayscale را به Mask دودویی تبدیل می‌کند.

Threshold ثابت

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

threshold_value, binary = cv2.threshold(
    gray,
    127,
    255,
    cv2.THRESH_BINARY
)

Otsu Threshold

threshold_value, binary = cv2.threshold(
    gray,
    0,
    255,
    cv2.THRESH_BINARY
    + cv2.THRESH_OTSU
)

print(
    "Selected threshold:",
    threshold_value
)

Otsu به‌صورت خودکار یک Threshold سراسری انتخاب می‌کند و برای بعضی تصاویر دارای Foreground و Background مشخص مناسب است.

Adaptive Threshold

adaptive = cv2.adaptiveThreshold(
    gray,
    255,
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY,
    blockSize=21,
    C=7
)

Adaptive Threshold برای تصاویری با نور نامتوازن، مانند عکس سند، مفید است.

blockSize باید عددی فرد و بزرگ‌تر از یک باشد.

عملیات Morphology

Morphology روی Maskهای دودویی انجام می‌شود.

ساخت Kernel:

kernel = cv2.getStructuringElement(
    cv2.MORPH_RECT,
    (5, 5)
)

Erosion

eroded = cv2.erode(
    binary,
    kernel,
    iterations=1
)

Erosion ناحیه سفید را کوچک‌تر می‌کند.

Dilation

dilated = cv2.dilate(
    binary,
    kernel,
    iterations=1
)

Dilation ناحیه سفید را بزرگ‌تر می‌کند.

Opening

opened = cv2.morphologyEx(
    binary,
    cv2.MORPH_OPEN,
    kernel
)

Opening می‌تواند Noiseهای سفید کوچک را حذف کند.

Closing

closed = cv2.morphologyEx(
    binary,
    cv2.MORPH_CLOSE,
    kernel
)

Closing می‌تواند فاصله‌ها و سوراخ‌های کوچک را پر کند.

معنای عملیات به این بستگی دارد که Foreground در Mask سفید یا سیاه باشد.

تشخیص لبه با Canny

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

blurred = cv2.GaussianBlur(
    gray,
    (5, 5),
    0
)

edges = cv2.Canny(
    blurred,
    threshold1=50,
    threshold2=150
)

مراحل معمول:

  1. تبدیل به Grayscale
  2. کاهش Noise
  3. اجرای Canny
  4. انجام Morphology در صورت نیاز
  5. پیداکردن Contour

Thresholdهای Canny باید براساس Contrast و Noise تصویر تنظیم شوند.

پیداکردن Contour

Contour مرز یک ناحیه متصل در تصویر دودویی است.

contours, hierarchy = (
    cv2.findContours(
        edges,
        cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE
    )
)

print(
    "Contours:",
    len(contours)
)

رسم تمام Contourها:

output = image.copy()

cv2.drawContours(
    output,
    contours,
    contourIdx=-1,
    color=(0, 255, 0),
    thickness=2
)

فیلترکردن Contour براساس مساحت

minimum_area = 1000

large_contours = [
    contour
    for contour in contours
    if cv2.contourArea(
        contour
    ) >= minimum_area
]

مرتب‌سازی:

large_contours = sorted(
    large_contours,
    key=cv2.contourArea,
    reverse=True
)

ساخت Bounding Box

output = image.copy()

for contour in large_contours:
    x, y, width, height = (
        cv2.boundingRect(
            contour
        )
    )

    cv2.rectangle(
        output,
        (x, y),
        (
            x + width,
            y + height
        ),
        (0, 255, 0),
        2
    )

Bounding Box چرخیده:

rectangle = cv2.minAreaRect(
    large_contours[0]
)

box = cv2.boxPoints(
    rectangle
)

box = np.int32(box)

cv2.drawContours(
    output,
    [box],
    0,
    (255, 0, 0),
    2
)

محاسبه مرکز Contour

moments = cv2.moments(
    contour
)

if moments["m00"] != 0:
    center_x = int(
        moments["m10"]
        / moments["m00"]
    )

    center_y = int(
        moments["m01"]
        / moments["m00"]
    )

رسم مرکز:

cv2.circle(
    output,
    (
        center_x,
        center_y
    ),
    radius=5,
    color=(0, 0, 255),
    thickness=-1
)

رسم متن و شکل

Rectangle:

cv2.rectangle(
    image,
    (50, 50),
    (350, 250),
    (0, 255, 0),
    3
)

Circle:

cv2.circle(
    image,
    (200, 200),
    70,
    (255, 0, 0),
    3
)

Line:

cv2.line(
    image,
    (20, 20),
    (500, 300),
    (0, 0, 255),
    2
)

متن انگلیسی:

cv2.putText(
    image,
    "Product",
    (50, 40),
    cv2.FONT_HERSHEY_SIMPLEX,
    1,
    (255, 255, 255),
    2,
    cv2.LINE_AA
)

نوشتن متن فارسی روی تصویر

cv2.putText پشتیبانی مناسبی از فونت و اتصال حروف فارسی ندارد. برای متن فارسی می‌توان از Pillow استفاده کرد.

python -m pip install pillow

کد:

import cv2
import numpy as np
from PIL import (
    Image,
    ImageDraw,
    ImageFont
)

def put_persian_text(
    image,
    text,
    position,
    font_path,
    font_size=36,
    color=(255, 255, 255)
):
    rgb = cv2.cvtColor(
        image,
        cv2.COLOR_BGR2RGB
    )

    pil_image = Image.fromarray(
        rgb
    )

    draw = ImageDraw.Draw(
        pil_image
    )

    font = ImageFont.truetype(
        font_path,
        font_size
    )

    draw.text(
        position,
        text,
        font=font,
        fill=color,
        direction="rtl"
    )

    result = cv2.cvtColor(
        np.array(pil_image),
        cv2.COLOR_RGB2BGR
    )

    return result

استفاده:

image = put_persian_text(
    image=image,
    text="گزارش پردازش تصویر",
    position=(500, 40),
    font_path="Vazirmatn-Regular.ttf",
    font_size=42
)

پشتیبانی direction="rtl" به امکانات نصب‌شده Pillow و موتورهای متن محیط وابسته است. خروجی را در محیط نهایی بررسی کنید.

پردازش ویدئو با OpenCV

ویدئو مجموعه‌ای از Frameهاست. OpenCV هر Frame را به‌صورت یک تصویر NumPy در اختیار برنامه قرار می‌دهد.

خواندن فایل ویدئویی

import cv2

capture = cv2.VideoCapture(
    "input.mp4"
)

if not capture.isOpened():
    raise RuntimeError(
        "Video could not be opened"
    )

دریافت مشخصات:

fps = capture.get(
    cv2.CAP_PROP_FPS
)

frame_count = int(
    capture.get(
        cv2.CAP_PROP_FRAME_COUNT
    )
)

width = int(
    capture.get(
        cv2.CAP_PROP_FRAME_WIDTH
    )
)

height = int(
    capture.get(
        cv2.CAP_PROP_FRAME_HEIGHT
    )
)

duration = (
    frame_count / fps
    if fps > 0
    else None
)

print("FPS:", fps)
print("Frames:", frame_count)
print("Size:", width, height)
print("Duration:", duration)

خواندن تمام Frameها

try:
    while True:
        success, frame = (
            capture.read()
        )

        if not success:
            break

        gray = cv2.cvtColor(
            frame,
            cv2.COLOR_BGR2GRAY
        )

        cv2.imshow(
            "Video",
            gray
        )

        if (
            cv2.waitKey(1)
            & 0xFF
        ) == ord("q"):
            break
finally:
    capture.release()
    cv2.destroyAllWindows()

استفاده از finally کمک می‌کند منبع ویدئو حتی در صورت خطا آزاد شود.

دریافت تصویر از وب‌کم

معمولاً دوربین پیش‌فرض Index صفر دارد:

capture = cv2.VideoCapture(
    0
)

کد:

if not capture.isOpened():
    raise RuntimeError(
        "Camera could not be opened"
    )

try:
    while True:
        success, frame = (
            capture.read()
        )

        if not success:
            break

        cv2.imshow(
            "Camera",
            frame
        )

        if (
            cv2.waitKey(1)
            & 0xFF
        ) == ord("q"):
            break
finally:
    capture.release()
    cv2.destroyAllWindows()

فقط در برنامه‌ای که کاربر آگاهانه اجرا کرده است از دوربین استفاده کنید و دسترسی دوربین را شفاف نگه دارید.

ذخیره ویدئوی پردازش‌شده

capture = cv2.VideoCapture(
    "input.mp4"
)

fps = capture.get(
    cv2.CAP_PROP_FPS
)

width = int(
    capture.get(
        cv2.CAP_PROP_FRAME_WIDTH
    )
)

height = int(
    capture.get(
        cv2.CAP_PROP_FRAME_HEIGHT
    )
)

fourcc = cv2.VideoWriter_fourcc(
    *"mp4v"
)

writer = cv2.VideoWriter(
    "output.mp4",
    fourcc,
    fps,
    (
        width,
        height
    )
)

if not writer.isOpened():
    capture.release()

    raise RuntimeError(
        "Output video could not be opened"
    )

try:
    while True:
        success, frame = (
            capture.read()
        )

        if not success:
            break

        processed = cv2.GaussianBlur(
            frame,
            (5, 5),
            0
        )

        writer.write(
            processed
        )
finally:
    capture.release()
    writer.release()

اندازه Frame ورودی writer.write باید با اندازه تعریف‌شده در VideoWriter یکسان باشد.

استخراج Frame از ویدئو

برای ذخیره یک Frame در هر ثانیه:

from pathlib import Path
import cv2

output_directory = Path(
    "frames"
)

output_directory.mkdir(
    parents=True,
    exist_ok=True
)

capture = cv2.VideoCapture(
    "input.mp4"
)

fps = capture.get(
    cv2.CAP_PROP_FPS
)

if fps <= 0:
    capture.release()

    raise ValueError(
        "Invalid video FPS"
    )

frame_interval = max(
    1,
    round(fps)
)

frame_index = 0
saved_index = 0

try:
    while True:
        success, frame = (
            capture.read()
        )

        if not success:
            break

        if (
            frame_index
            % frame_interval
            == 0
        ):
            output_path = (
                output_directory
                / f"frame-{saved_index:05d}.jpg"
            )

            cv2.imwrite(
                str(output_path),
                frame
            )

            saved_index += 1

        frame_index += 1
finally:
    capture.release()

برای تحلیل ویدئو با مدل چندوجهی، معمولاً لازم نیست تمام Frameها ارسال شوند. ابتدا Frameهای نماینده را انتخاب کنید.

پروژه عملی: ساخت اسکنر ساده سند

هدف پروژه:

  1. خواندن عکس سند
  2. تغییر اندازه برای پردازش سریع‌تر
  3. تبدیل به Grayscale
  4. کاهش Noise
  5. تشخیص لبه
  6. پیداکردن بزرگ‌ترین Contour چهارضلعی
  7. اصلاح Perspective
  8. ساخت خروجی شبیه اسکن

تابع مرتب‌کردن چهار نقطه

چهار گوشه باید به ترتیب زیر مرتب شوند:

  • بالا چپ
  • بالا راست
  • پایین راست
  • پایین چپ
import numpy as np

def order_points(points):
    rectangle = np.zeros(
        (4, 2),
        dtype=np.float32
    )

    sums = points.sum(
        axis=1
    )

    differences = np.diff(
        points,
        axis=1
    ).reshape(-1)

    rectangle[0] = points[
        np.argmin(sums)
    ]

    rectangle[2] = points[
        np.argmax(sums)
    ]

    rectangle[1] = points[
        np.argmin(differences)
    ]

    rectangle[3] = points[
        np.argmax(differences)
    ]

    return rectangle

تابع اصلاح Perspective

import cv2
import numpy as np

def four_point_transform(
    image,
    points
):
    rectangle = order_points(
        points
    )

    top_left, top_right, \
        bottom_right, bottom_left = (
            rectangle
        )

    width_a = np.linalg.norm(
        bottom_right
        - bottom_left
    )

    width_b = np.linalg.norm(
        top_right
        - top_left
    )

    max_width = int(
        max(
            width_a,
            width_b
        )
    )

    height_a = np.linalg.norm(
        top_right
        - bottom_right
    )

    height_b = np.linalg.norm(
        top_left
        - bottom_left
    )

    max_height = int(
        max(
            height_a,
            height_b
        )
    )

    destination = np.array(
        [
            [0, 0],
            [
                max_width - 1,
                0
            ],
            [
                max_width - 1,
                max_height - 1
            ],
            [
                0,
                max_height - 1
            ]
        ],
        dtype=np.float32
    )

    matrix = (
        cv2.getPerspectiveTransform(
            rectangle,
            destination
        )
    )

    warped = cv2.warpPerspective(
        image,
        matrix,
        (
            max_width,
            max_height
        )
    )

    return warped

پیداکردن مرز سند

import cv2
import numpy as np

image = cv2.imread(
    "document.jpg"
)

if image is None:
    raise FileNotFoundError(
        "document.jpg was not found"
    )

original = image.copy()

original_height = (
    image.shape[0]
)

target_height = 700

scale = (
    original_height
    / target_height
)

resized_width = int(
    image.shape[1]
    / scale
)

resized = cv2.resize(
    image,
    (
        resized_width,
        target_height
    ),
    interpolation=cv2.INTER_AREA
)

gray = cv2.cvtColor(
    resized,
    cv2.COLOR_BGR2GRAY
)

blurred = cv2.GaussianBlur(
    gray,
    (5, 5),
    0
)

edges = cv2.Canny(
    blurred,
    50,
    150
)

kernel = cv2.getStructuringElement(
    cv2.MORPH_RECT,
    (5, 5)
)

edges = cv2.morphologyEx(
    edges,
    cv2.MORPH_CLOSE,
    kernel
)

پیداکردن Contourها:

contours, _ = cv2.findContours(
    edges,
    cv2.RETR_LIST,
    cv2.CHAIN_APPROX_SIMPLE
)

contours = sorted(
    contours,
    key=cv2.contourArea,
    reverse=True
)[:10]

پیداکردن چهارضلعی:

document_contour = None

for contour in contours:
    perimeter = cv2.arcLength(
        contour,
        True
    )

    approximation = (
        cv2.approxPolyDP(
            contour,
            0.02 * perimeter,
            True
        )
    )

    if len(approximation) == 4:
        document_contour = (
            approximation.reshape(
                4,
                2
            )
        )

        break

if document_contour is None:
    raise RuntimeError(
        "Document boundary was not detected"
    )

اصلاح Perspective روی تصویر اصلی:

original_points = (
    document_contour
    * scale
)

scanned = four_point_transform(
    original,
    original_points
)

ساخت نسخه سیاه‌وسفید:

scanned_gray = cv2.cvtColor(
    scanned,
    cv2.COLOR_BGR2GRAY
)

scanned_output = (
    cv2.adaptiveThreshold(
        scanned_gray,
        255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY,
        31,
        10
    )
)

cv2.imwrite(
    "scanned-document.png",
    scanned_output
)

این پروژه برای سندهایی با کنتراست مناسب و پس‌زمینه نسبتاً ساده عملکرد بهتری دارد. در عکس‌های پیچیده باید پارامترها و روش تشخیص مرز بهبود پیدا کنند.

ساخت Pipeline پردازش دسته‌ای تصویر

فرض کنید می‌خواهید تمام تصاویر یک پوشه را:

  • بخوانید
  • جهت EXIF را اصلاح کنید
  • به عرض مشخص Resize کنید
  • در قالب WebP ذخیره کنید

OpenCV به‌تنهایی همیشه Orientation ثبت‌شده در EXIF را مانند همه ابزارها مدیریت نمی‌کند. برای خواندن مطمئن Orientation می‌توان از Pillow استفاده کرد.

from pathlib import Path
from PIL import (
    Image,
    ImageOps
)
import cv2
import numpy as np

def load_with_orientation(path):
    with Image.open(path) as pil_image:
        pil_image = (
            ImageOps.exif_transpose(
                pil_image
            )
        )

        pil_image = (
            pil_image.convert("RGB")
        )

        rgb = np.array(
            pil_image
        )

    return cv2.cvtColor(
        rgb,
        cv2.COLOR_RGB2BGR
    )

پردازش پوشه:

input_directory = Path(
    "input-images"
)

output_directory = Path(
    "output-images"
)

output_directory.mkdir(
    parents=True,
    exist_ok=True
)

allowed_extensions = {
    ".jpg",
    ".jpeg",
    ".png",
    ".webp"
}

for input_path in (
    input_directory.iterdir()
):
    if (
        input_path.suffix.lower()
        not in allowed_extensions
    ):
        continue

    try:
        image = load_with_orientation(
            input_path
        )

        processed = resize_keep_aspect(
            image,
            target_width=1200
        )

        output_path = (
            output_directory
            / (
                input_path.stem
                + ".webp"
            )
        )

        success = cv2.imwrite(
            str(output_path),
            processed,
            [
                cv2.IMWRITE_WEBP_QUALITY,
                85
            ]
        )

        if not success:
            raise IOError(
                "Save failed"
            )

        print(
            "Saved:",
            output_path
        )

    except Exception as error:
        print(
            "Failed:",
            input_path,
            error
        )

آماده‌سازی تصویر برای مدل هوش مصنوعی

پیش از ارسال تصویر به مدل می‌توانید:

  • جهت تصویر را اصلاح کنید
  • ابعاد بسیار بزرگ را کاهش دهید
  • فرمت را به JPEG یا WebP تبدیل کنید
  • اطلاعات غیرضروری را Crop کنید
  • کیفیت را در حد مناسب نگه دارید
  • حجم Base64 را کنترل کنید

تابع آماده‌سازی:

import cv2

def prepare_image_for_api(
    image,
    max_width=1600,
    jpeg_quality=88
):
    height, width = image.shape[:2]

    if width > max_width:
        scale = (
            max_width / width
        )

        image = cv2.resize(
            image,
            (
                max_width,
                int(height * scale)
            ),
            interpolation=cv2.INTER_AREA
        )

    success, encoded = cv2.imencode(
        ".jpg",
        image,
        [
            cv2.IMWRITE_JPEG_QUALITY,
            jpeg_quality
        ]
    )

    if not success:
        raise ValueError(
            "JPEG encoding failed"
        )

    return encoded.tobytes()

اتصال OpenCV به API چندوجهی درواره

OpenCV برای پردازش قطعی تصویر مناسب است. مدل چندوجهی می‌تواند محتوای تصویر را توصیف یا اطلاعات سطح بالاتر آن را تحلیل کند.

فرایند پیشنهادی:

  1. تصویر با OpenCV خوانده شود
  2. Resize و Crop انجام شود
  3. تصویر Encode شود
  4. به یک مدل دارای قابلیت ورودی تصویر ارسال شود
  5. خروجی مدل اعتبارسنجی شود

برای دسترسی به مدل‌های دارای قابلیت تصویر می‌توانید در درواره ثبت‌نام کنید. مدل مناسب و قیمت به‌روز آن را در صفحه مدل‌های درواره بررسی کنید.

نگهداری API Key

در Linux یا macOS:

export DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"

در PowerShell:

$env:DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"

تبدیل تصویر به Data URL

import base64

image_bytes = (
    prepare_image_for_api(
        image,
        max_width=1600,
        jpeg_quality=88
    )
)

image_base64 = base64.b64encode(
    image_bytes
).decode("utf-8")

data_url = (
    "data:image/jpeg;base64,"
    + image_base64
)

ارسال تصویر به API درواره

import os
import requests

response = requests.post(
    "https://api.darvareh.ir/v1/chat/completions",
    headers={
        "Authorization": (
            f"Bearer "
            f"{os.environ['DARVAREH_API_KEY']}"
        ),
        "Content-Type": "application/json"
    },
    json={
        "model": "YOUR_MODEL_ID",
        "messages": [
            {
                "role": "system",
                "content": (
                    "تو یک دستیار تحلیل تصویر هستی. "
                    "فقط مواردی را بیان کن که از تصویر "
                    "قابل مشاهده‌اند. اگر مطمئن نیستی، "
                    "عدم قطعیت را شفاف اعلام کن."
                )
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": (
                            "این تصویر را به فارسی "
                            "توصیف کن و عناصر اصلی، "
                            "متن قابل مشاهده و کیفیت "
                            "کلی تصویر را در قالب "
                            "بخش‌های جداگانه بنویس."
                        )
                    },
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": data_url
                        }
                    }
                ]
            }
        ],
        "temperature": 0.1
    },
    timeout=90
)

response.raise_for_status()

result = response.json()

print(
    result["choices"][0]
          ["message"]
          ["content"]
)

YOUR_MODEL_ID را با شناسه یکی از مدل‌های دارای قابلیت ورودی تصویر در درواره جایگزین کنید.

ترکیب OpenCV و مدل چندوجهی

تقسیم وظایف مناسب:

وظیفهابزار پیشنهادی
Resize و CropOpenCV
تبدیل رنگOpenCV
Threshold و EdgeOpenCV
Contour و Bounding BoxOpenCV
فشرده‌سازی و EncodeOpenCV
توصیف معنایی تصویرمدل چندوجهی
استخراج پاسخ زبانیمدل چندوجهی
ساخت گزارش فارسیمدل زبانی یا چندوجهی
دسترسی API به مدلدرواره

اگر کاری را می‌توان با یک الگوریتم قطعی، سریع و کم‌هزینه انجام داد، لازم نیست آن را به مدل زبانی واگذار کنید.

پردازش چند تصویر با کنترل خطا

from pathlib import Path
import cv2

def process_image_file(
    input_path,
    output_path
):
    image = cv2.imread(
        str(input_path)
    )

    if image is None:
        raise ValueError(
            "Image could not be read"
        )

    gray = cv2.cvtColor(
        image,
        cv2.COLOR_BGR2GRAY
    )

    enhanced = cv2.createCLAHE(
        clipLimit=2.0,
        tileGridSize=(8, 8)
    ).apply(gray)

    success = cv2.imwrite(
        str(output_path),
        enhanced
    )

    if not success:
        raise IOError(
            "Output could not be saved"
        )

اجرای دسته‌ای:

input_directory = Path(
    "input"
)

output_directory = Path(
    "output"
)

output_directory.mkdir(
    parents=True,
    exist_ok=True
)

for input_path in (
    input_directory.glob("*.jpg")
):
    output_path = (
        output_directory
        / input_path.name
    )

    try:
        process_image_file(
            input_path,
            output_path
        )

        print(
            "Processed:",
            input_path.name
        )

    except Exception as error:
        print(
            "Failed:",
            input_path.name,
            error
        )

بهینه‌سازی OpenCV

کاهش اندازه پیش از پردازش

اگر برای تشخیص اولیه به رزولوشن کامل نیاز ندارید، ابتدا تصویر را کوچک کنید.

استفاده از ROI

فقط Region of Interest را پردازش کنید:

roi = image[
    y1:y2,
    x1:x2
]

پرهیز از Copy غیرضروری

working_image = image.copy()

فقط وقتی Copy نیاز دارید که نمی‌خواهید تصویر اصلی تغییر کند.

استفاده از عملیات برداری

به‌جای Loop روی پیکسل‌ها از NumPy و OpenCV استفاده کنید.

پردازش انتخابی Frameهای ویدئو

برای تحلیل غیر Real-time لازم نیست تمام Frameها پردازش شوند:

if frame_index % 5 != 0:
    frame_index += 1
    continue

استفاده از نسخه Headless روی سرور

python -m pip install opencv-python-headless

آزادکردن منابع

capture.release()
writer.release()
cv2.destroyAllWindows()

ساخت API پردازش تصویر با FastAPI

نصب:

python -m pip install \
    fastapi \
    uvicorn \
    python-multipart \
    opencv-python-headless \
    numpy

فایل main.py:

import cv2
import numpy as np

from fastapi import (
    FastAPI,
    File,
    HTTPException,
    UploadFile
)

from fastapi.responses import Response

app = FastAPI()

MAX_FILE_SIZE = (
    10 * 1024 * 1024
)

@app.post("/grayscale")
async def grayscale_image(
    file: UploadFile = File(...)
):
    if file.content_type not in {
        "image/jpeg",
        "image/png",
        "image/webp"
    }:
        raise HTTPException(
            status_code=415,
            detail="Unsupported image type"
        )

    contents = await file.read()

    if len(contents) > MAX_FILE_SIZE:
        raise HTTPException(
            status_code=413,
            detail="Image is too large"
        )

    array = np.frombuffer(
        contents,
        dtype=np.uint8
    )

    image = cv2.imdecode(
        array,
        cv2.IMREAD_COLOR
    )

    if image is None:
        raise HTTPException(
            status_code=400,
            detail="Invalid image"
        )

    gray = cv2.cvtColor(
        image,
        cv2.COLOR_BGR2GRAY
    )

    success, encoded = cv2.imencode(
        ".png",
        gray
    )

    if not success:
        raise HTTPException(
            status_code=500,
            detail="Encoding failed"
        )

    return Response(
        content=encoded.tobytes(),
        media_type="image/png"
    )

اجرا:

uvicorn main:app --reload

آزمایش با cURL:

curl \
  -X POST \
  -F "file=@sample.jpg" \
  http://127.0.0.1:8000/grayscale \
  --output grayscale.png

اعتبارسنجی Content Type به‌تنهایی کافی نیست؛ به همین دلیل کد تلاش می‌کند محتوای واقعی فایل را نیز Decode کند.

خطاهای رایج OpenCV

خطای نصب نبودن cv2

ModuleNotFoundError: No module named 'cv2'

راه‌حل:

python -m pip install opencv-python

یا روی سرور:

python -m pip install opencv-python-headless

خروجی imread برابر None است

image = cv2.imread(
    path
)

if image is None:
    print(
        "Invalid path or file"
    )

موارد زیر را بررسی کنید:

  • مسیر فایل
  • Working Directory
  • سطح دسترسی
  • فرمت تصویر
  • خرابی فایل
  • نویسه‌های Unicode در مسیر

نمایش مسیر فعلی:

from pathlib import Path

print(Path.cwd())

رنگ تصویر اشتباه است

برای Matplotlib:

rgb = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2RGB
)

خطای imshow روی سرور

نسخه Headless پنجره GUI ندارد. از imwrite یا نمایش تحت وب استفاده کنید.

خطای اندازه در VideoWriter

تمام Frameهای ورودی باید دقیقاً با Width و Height تعریف‌شده هنگام ساخت Writer یکسان باشند.

خروجی ویدئو اجرا نمی‌شود

Codec و Container باید با محیط سازگار باشند. گاهی لازم است Codec یا پسوند خروجی تغییر کند.

متن فارسی خراب نمایش داده می‌شود

از Pillow و فونت فارسی استفاده کنید. cv2.putText برای متن فارسی انتخاب مناسبی نیست.

Canny هیچ لبه‌ای پیدا نمی‌کند

موارد زیر را بررسی کنید:

  • تصویر بیش از حد تار است
  • Thresholdها زیاد هستند
  • Contrast پایین است
  • تصویر پیش از Canny به Grayscale تبدیل نشده
  • Noise زیاد است

Contourهای خیلی زیاد پیدا می‌شوند

راهکارها:

  • Blur پیش از Canny
  • Morphology
  • افزایش حداقل مساحت
  • استفاده از RETR_EXTERNAL
  • محدودکردن ROI

مصرف حافظه زیاد

تصویر 4K و ویدئو می‌توانند حافظه زیادی مصرف کنند. Frameها را نگهداری نکنید مگر اینکه واقعاً لازم باشند.

اشتباهات رایج در پردازش تصویر

پردازش تصویر بدون بررسی BGR و RGB

این اشتباه می‌تواند خروجی مدل، نمودار یا ذخیره‌سازی را تغییر دهد.

Resize کردن بدون حفظ نسبت

تصویر کشیده یا فشرده می‌شود و شکل اشیا تغییر می‌کند.

استفاده از Threshold ثابت برای همه تصاویر

نور، دوربین، پس‌زمینه و Exposure روی مقدار مناسب Threshold اثر دارند.

اعمال Blur شدید

Blur زیاد می‌تواند لبه و متن واقعی را حذف کند.

حذف Contour کوچک بدون شناخت مسئله

ممکن است شیء موردنظر واقعاً کوچک باشد.

اعتماد کامل به مدل چندوجهی

مدل ممکن است بخشی از تصویر را اشتباه تفسیر کند. خروجی مهم باید با داده یا بررسی انسانی اعتبارسنجی شود.

ارسال تصویر بسیار بزرگ به API

رزولوشن بیش از نیاز می‌تواند حجم، Latency و هزینه را افزایش دهد.

ارسال اطلاعات تصویری غیرضروری

پیش از ارسال، ناحیه‌های غیرمرتبط را Crop کنید و فقط داده لازم را پردازش کنید. تصاویر شخصی یا محرمانه را تنها با مجوز و ضرورت مشخص استفاده کنید.

چک‌لیست پروژه OpenCV

  • نسخه مناسب OpenCV نصب شده است
  • چند پکیج OpenCV هم‌زمان نصب نشده‌اند
  • نتیجه imread بررسی می‌شود
  • تفاوت BGR و RGB رعایت شده است
  • نسبت تصویر هنگام Resize حفظ می‌شود
  • Interpolation مناسب انتخاب شده است
  • مسیرهای Unicode آزمایش شده‌اند
  • نوع و Shape آرایه کنترل می‌شود
  • Threshold براساس داده تنظیم شده است
  • Contourها براساس منطق مسئله فیلتر می‌شوند
  • منابع VideoCapture و VideoWriter آزاد می‌شوند
  • حجم فایل ورودی API محدود شده است
  • فایل واقعی Decode و اعتبارسنجی می‌شود
  • تصویر پیش از ارسال به مدل Resize شده است
  • اطلاعات غیرضروری Crop شده‌اند
  • خروجی مدل چندوجهی اعتبارسنجی می‌شود
  • API Key داخل کد ذخیره نشده است

پرسش‌های متداول

OpenCV چیست؟

OpenCV یک کتابخانه متن‌باز برای پردازش تصویر، ویدئو و بینایی ماشین است که از زبان‌هایی مانند C++، پایتون و Java پشتیبانی می‌کند.

چگونه OpenCV را در پایتون نصب کنیم؟

python -m pip install opencv-python

سپس:

import cv2

چرا نام پکیج OpenCV و نام Import آن cv2 است؟

پکیج پایتون با نام opencv-python منتشر می‌شود، اما نام تاریخی ماژول پایتون آن cv2 است.

تفاوت opencv-python و opencv-python-headless چیست؟

نسخه Headless وابستگی‌های رابط گرافیکی را ندارد و برای سرور، Docker و API مناسب‌تر است. در آن نباید به cv2.imshow وابسته باشید.

چرا رنگ تصویر در Matplotlib اشتباه نمایش داده می‌شود؟

OpenCV تصویر را به‌شکل BGR می‌خواند، اما Matplotlib انتظار RGB دارد:

rgb = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2RGB
)

چگونه تصویر را Grayscale کنیم؟

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

چگونه لبه تصویر را پیدا کنیم؟

edges = cv2.Canny(
    gray,
    50,
    150
)

معمولاً بهتر است پیش از Canny، Noise تصویر کاهش پیدا کند.

Contour چیست؟

Contour مرز یک ناحیه متصل در تصویر دودویی است و برای پیداکردن شکل، Bounding Box و مساحت اشیا استفاده می‌شود.

آیا OpenCV مدل هوش مصنوعی است؟

خیر. OpenCV یک کتابخانه پردازش تصویر و بینایی ماشین است. بعضی ماژول‌های آن امکان اجرای مدل‌های یادگیری ماشین و شبکه عصبی را نیز فراهم می‌کنند.

OpenCV بهتر است یا مدل چندوجهی؟

کاربرد آن‌ها متفاوت است. OpenCV برای عملیات قطعی مانند Resize، Threshold، Edge و Contour مناسب است. مدل چندوجهی برای درک معنایی و توصیف محتوای تصویر کاربرد دارد.

چگونه تصویر OpenCV را به API درواره ارسال کنیم؟

تصویر را با cv2.imencode به JPEG یا PNG تبدیل کنید، آن را با Base64 داخل Data URL قرار دهید و به یک مدل دارای قابلیت ورودی تصویر ارسال کنید.

جمع‌بندی

OpenCV یکی از مهم‌ترین ابزارهای برنامه‌نویسی برای پردازش تصویر و ویدئو است. با یادگیری ساختار تصویر، فضای رنگ، Filter، Threshold، Morphology، Edge و Contour می‌توانید بسیاری از Pipelineهای کاربردی Computer Vision را پیاده‌سازی کنید.

یک معماری مناسب می‌تواند چنین تقسیم وظیفه‌ای داشته باشد:

  • NumPy برای آرایه و محاسبات پیکسلی
  • OpenCV برای پردازش تصویر و ویدئو
  • Pillow برای فونت فارسی و Metadata تصویر
  • مدل چندوجهی برای درک معنایی تصویر
  • FastAPI برای ارائه سرویس پردازش
  • درواره برای دسترسی API به مدل‌های هوش مصنوعی

برای شروع، در درواره ثبت‌نام کنید، API Key بگیرید و یک مدل دارای قابلیت پردازش تصویر را از صفحه مدل‌ها و قیمت‌ها انتخاب کنید.

مقالات مرتبط

برای مطالعه شرایط استفاده و محدودیت‌های مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.

Read more

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی با ترکیب گردش‌کارهای خودکار و مدل‌های هوش مصنوعی، پردازش متن، دسته‌بندی، استخراج اطلاعات و تصمیم‌های پیشنهادی را خودکار می‌کند. در این راهنما، معماری و ساخت نمونه عملی آن با API درواره را می‌آموزید.

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce شیوه‌ای جدید برای خرید اینترنتی است که در آن ایجنت هوش مصنوعی می‌تواند نیاز کاربر را بفهمد، محصولات را جست‌وجو و مقایسه کند و فرایند خرید را پیش ببرد. در این راهنما با معماری، UCP، ACP و پیاده‌سازی آن با API درواره آشنا می‌شوید.