رفتن به محتوای اصلی
بازگشت به وبلاگ

راهنماهای هوش مصنوعی

تشخیص لبه با Sobel؛ گرادیان تصویر را دستی حساب کنیم

دو فیلتر Sobel را روی ماتریس ۳×۳ اجرا کنید؛ علامت منفی، اندازهٔ گرادیان و تفاوت لبهٔ روشنایی با مرز یک شیء را ببینید.

فیلتر Sobel تغییر روشنایی در دو جهت تصویر را تقریب می‌زند. پاسخ بزرگ می‌تواند نشانهٔ لبهٔ روشنایی باشد؛ اما به‌تنهایی نمی‌گوید آن لبه، مرز کدام شیء است. با یک ماتریس ۳×۳ می‌توان محاسبه را بدون مدل یادگیری ماشین یا نصب ابزار دید.

یک جهش عمودی در تصویر کوچک

سه سطر تصویر آموزشی ما یکسان‌اند: «۰،۰،۱۰». ستون راست روشن‌تر است. فیلتر افقیِ انتخابی سه سطر «منفی۱،۰،۱»، «منفی۲،۰،۲» و «منفی۱،۰،۱» دارد. ضرب عضوهای متناظر و جمع آن‌ها، پاسخ ۴۰ می‌دهد. فیلتر جهت عمودی برای همین مثال پاسخ صفر دارد؛ در راستای بالا به پایین تغییری نداریم.

اگر هر سطر را به «۱۰،۰،۰» برگردانیم، پاسخ افقی منفی۴۰ می‌شود. اندازهٔ تغییر در دو حالت یکسان است و جهت روشن به تیره یا تیره به روشن فرق دارد. حذف مقدارهای منفی، نیمی از این اطلاعات را از دست می‌دهد.

آزمایشپاسخ افقیپاسخ عمودیاندازه
ستون راست روشن۴۰۰۴۰
ستون چپ روشنمنفی۴۰۰۴۰
همه پیکسل‌ها ۵۰۰۰

کد قابل تکرار با قرارداد روشن

import math
kx = [[-1,0,1],[-2,0,2],[-1,0,1]]
ky = [[-1,-2,-1],[0,0,0],[1,2,1]]
def response(patch, kernel):
    if len(patch)!=3 or any(len(row)!=3 for row in patch):
        raise ValueError('3x3 patch required')
    if not all(math.isfinite(x) for row in patch for x in row):
        raise ValueError('finite values required')
    return sum(patch[r][c]*kernel[r][c] for r in range(3) for c in range(3))
for patch in ([[0,0,10]]*3, [[10,0,0]]*3, [[5,5,5]]*3):
    gx,gy = response(patch,kx),response(patch,ky)
    print('gx gy magnitude',gx,gy,math.hypot(gx,gy))
assert response([[0,0,10]]*3,kx)==40
assert response([[10,0,0]]*3,kx)==-40
assert response([[0,0,10]]*3,ky)==0
assert response([[5,5,5]]*3,kx)==0

در این تمرین کرنل را برنمی‌گردانیم؛ ضرب مستقیمِ پنجره و کرنل انجام می‌شود. در تعریف ریاضی کانولوشن، وارونه‌کردن کرنل می‌تواند علامت پاسخ را عوض کند. پس نام عملیات و ترتیب محورها را هنگام مقایسه دو پیاده‌سازی ثبت کنید؛ صرف تفاوت علامت همیشه نشانهٔ خطا نیست.

چرا خروجی را زود به عدد ۸بیتی تبدیل نکنیم؟

پاسخ می‌تواند منفی یا بزرگ‌تر از دامنهٔ پیکسل ورودی باشد. بهتر است تا پایان محاسبه در نوع عددی مناسب بماند. تبدیل زودهنگام به نمایش بدون علامت ممکن است اطلاعات منفی را حذف کند یا نتیجهٔ نامنتظره بدهد. برای نمایش اندازه، پس از حفظ پاسخ اصلی قدرمطلق یا اندازهٔ دوبعدی را بسازید؛ برای تحلیل جهت، علامت را هم نگه دارید.

کد فقط مرکز یک پنجره را حساب می‌کند و سیاست لبهٔ تصویر، نرمال‌سازی و آستانه‌گذاری ندارد. برای اجرای تمام تصویر باید دربارهٔ padding و مرزها تصمیم بگیرید. نتیجهٔ مرکزِ تصویر را با نتیجهٔ کنار آن بدون درنظرگرفتن همین قراردادها مقایسه نکنید.

لبه با شیء یا نوشته یکی نیست

سایه، بافت کاغذ و نویز هم می‌توانند پاسخ بسازند. تشخیص لبه ثابت نمی‌کند حروف درست خوانده شده‌اند یا شیء شناسایی شده است. در محدودیت‌های مدل چندوجهی هم خروجی باید به شاهد واقعی وصل بماند. برای آماده‌سازی سند، مسیر متن و تصویر در جست‌وجوی دانشی را جدا بررسی کنید.

برای آزمون خودتان، سه پنجرهٔ سادهٔ ثابت، روشن‌به‌تیره و تیره‌به‌روشن بسازید؛ سپس علامت، محور و اندازه را کنترل کنید. این تمرین هیچ دقتی برای عکس واقعی وعده نمی‌دهد. اگر مسئلهٔ عملی شما پاسخ‌گویی یا تحلیل مکالمهٔ مشتری است، خدمت مرتبط اپرا را انتخاب کنید؛ فیلتر تصویر جای آن مسیر را نمی‌گیرد.

فایل تمرین و منابع

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

تاریخ مطالعهٔ منبع: ۳ نوامبر ۲۰۲۶. محاسبه‌ها و مثال این مطلب برای آموزش طراحی شده‌اند.

برای این نیاز، کدام خدمت مناسب‌تر است؟

تماس و منشی، چت سایت و تحلیل مکالمه سه مسیر متفاوت‌اند. ابتدا خدمت متناسب نیازتان را انتخاب کنید.

انتخاب میان سه خدمتراهنمای شروع با تیم اپرا

برآورد هزینه