Sobel

saalek110

Well-Known Member
سوبل چیست؟

Deepseek:

در پردازش تصویر، Sobel (سُبـِل) یک عملگر (Operator) یا فیلتر تشخیص لبه است. به زبان ساده، روشی ریاضی برای پیدا کردن مرزهای اشیا در یک تصویر است.

کارش اینه که جاهایی از تصویر رو پیدا کنه که تغییرات شدید و ناگهانی در روشنایی وجود داره (مثلاً جایی که یک شیء تیره به پس‌زمینه روشن می‌رسه). این تغییرات همون "لبه‌ها" هستن.

ایده اصلی: مشتق‌گیری

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

چون تصویر هم جهت افقی (X) داره و هم عمودی (Y)، سوبل از دو هسته (Kernel) یا فیلتر مجزا استفاده میکنه:

· هسته افقی (Gx): لبه‌های عمودی رو پیدا میکنه (تغییرات در راستای افق).
· هسته عمودی (Gy): لبه‌های افقی رو پیدا میکنه (تغییرات در راستای عمود).

این هسته‌ها (معمولاً ۳x۳) روی تصویر اعمال میشن:

```
[ -1 0 +1 ] [ -1 -2 -1 ]
Gx = [ -2 0 +2 ] , Gy = [ 0 0 0 ]
[ -1 0 +1 ] [ +1 +2 +1 ]
```

چطور کار میکنه؟ (مراحل ساده)

۱. اعمال هسته‌ها: هسته Gx و Gy رو جداگانه روی تک‌تک پیکسل‌های تصویر میکشیم. این کار "کانولوشن" نام داره. خروجی دو تا تصویر جدید هست:
- یکی که لبه‌های عمودی رو پررنگ کرده.
- دیگری که لبه‌های افقی رو پررنگ کرده.
۲. ترکیب نتایج: برای اینکه لبه نهایی در هر نقطه رو به‌دست بیاریم، اندازه (Magnitude) گرادیان رو به این شکل حساب میکنیم:
|G| = \sqrt{G_x^2 + G_y^2}


یا برای سادگی و سرعت بیشتر:
|G| \approx |G_x| + |G_y|


۳. جهت لبه: سوبل میتونه جهت لبه رو هم مشخص کنه. این زاویه از این فرمول به‌دست میاد:
\theta = \arctan\left(\frac{G_y}{G_x}\right)

چرا سوبل انقدر محبوبه؟

۱. کاهش نویز: برخلاف فیلترهای ساده‌تر، هسته‌های سوبل یک عمل میانگین‌گیری جزئی هم انجام میدن (مثلاً ضربدر ۲ در ردیف وسط). این کار باعث میشه کمی در برابر نویزهای تصادفی تصویر مقاوم‌تر باشه.
۲. سرعت و سادگی: محاسباتش سنگین نیست و پیاده‌سازی و اجراش آسونه.
۳. اطلاعات جهتی: برخلاف بعضی روش‌های دیگه که فقط محل لبه رو میگن، سوبل جهت لبه رو هم مشخص میکنه که کاربردهای زیادی داره.

کجاها استفاده میشه؟

· پیش‌پردازش: مرحله اول در بسیاری از الگوریتم‌های پیچیده‌تر بینایی کامپیوتر مثل تشخیص اشیا.
· استخراج ویژگی: پیدا کردن خطوط و بافت‌ها برای آنالیز تصویر.
· تشخیص گوشه‌ها: به‌عنوان بخشی از الگوریتم‌های معروف مثل Harris Corner Detector به کار میره.

در یک کلام، سوبل یکی از ساده‌ترین و پایه‌ای‌ترین روش‌ها برای تبدیل یک تصویر به یک نقشه راهنما از خطوط و مرزهای اشیاست.
 

saalek110

Well-Known Member
سالک: جهت لبه چیست؟
Deepseek:

حتماً. بذارید با یک مثال ساده توضیح بدم که "جهت لبه" در فیلتر سوبل یعنی چی.

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

راحت‌ترین راه برای فهمیدنش این است که به یک لبه مثل یک سراشیبی تپه فکر کنید.

جهت لبه ≠ جهت خط

اول یک نکته خیلی مهم: جهت لبه با جهتی که خط کشیده شده فرق دارد. جهت لبه همیشه عمود بر جهت خط است.

· جهت خط (Line Direction): مسیری که خودِ مرز یا خط در طول آن کشیده شده است.
· جهت لبه (Edge Direction): مسیری که اگر از خط خارج شوید، سریع‌ترین تغییر روشنایی را می‌بینید.

مثال ۱: یک خط عمودی

یک خط عمودی سیاه روی پس‌زمینه سفید را تصور کنید (مثل یک میله پرچم).

· جهت خط: عمودی است (بالا به پایین).
· تغییرات روشنایی: اگر شما روی این مرز باشید و به سمت چپ یا راست حرکت کنید، ناگهان از سفید به سیاه (یا برعکس) می‌روید. تغییرات در راستای افقی (محور X) حداکثر است.
· جهت لبه (برداری که سوبل می‌دهد): افقی است (به سمت چپ یا راست). چون ∇ تغییرات، افقی است.

مثال ۲: یک خط افقی

یک خط افقی سیاه روی پس‌زمینه سفید را تصور کنید (مثل افق).

· جهت خط: افقی است (چپ به راست).
· تغییرات روشنایی: اگر در راستای بالا یا پایین حرکت کنید، تغییر سفید به سیاه رخ می‌دهد. تغییرات در راستای عمودی (محور Y) حداکثر است.
· جهت لبه: عمودی است (به سمت بالا یا پایین).

فرمول ریاضی به زبان ساده

جهت لبه از حاصل arctan(Gy / Gx) به‌دست میاد، که دقیقاً مفهوم بالا رو می‌رسونه:

· اگر Gx خیلی بزرگ باشه و Gy نزدیک صفر (مثل مثال خط عمودی): جهت لبه حول و حوش ۰ یا ۱۸۰ درجه خواهد بود (یعنی افقی و کاملاً رو به راست یا چپ).
· اگر Gy خیلی بزرگ باشه و Gx نزدیک صفر (مثل مثال خط افقی): جهت لبه حول و حوش ۹۰ یا ۲۷۰ درجه خواهد بود (یعنی عمودی و کاملاً رو به بالا یا پایین).

جهت لبه مثل سوزن یک قطب‌نما عمل می‌کنه که جهت "شیب" تغییرات روشنایی رو نشون میده، و این جهت همیشه عمود بر جهت خود مرز هست.
 

saalek110

Well-Known Member
سوبل چیست دوم؟

خیلی خب، بذار خیلی فشرده و با دیدی که الان داری دوباره بگم سوبل چیه:

فیلتر سوبل عملگریه که دو کار اصلی انجام میده:

1. پیدا کردن نقاط لبه: جاهایی از تصویر رو پیدا میکنه که تغییرات شدت روشنایی زیاده.
2. محاسبه جهت این تغییرات: در هر نقطه، جهتی رو که این تغییرات در آن شدیدترین هست (مثل جهت شیب یک سراشیبی) مشخص میکنه.

خروجی این عملگر:
برای هر پیکسل، دو عدد به ما میده: اندازه (قدرت لبه) و جهت (زاویه لبه) .

چطور این کار رو میکنه؟
با اندازه‌گیری نرخ تغییرات در دو راستای مجزا (افقی و عمودی) و سپس ترکیب این دو:

· تغییرات در راستای افقی (Gx): این رو با یک فیلتر (هسته) که به تغییرات عمودی حساسه اندازه میگیره. عدد بزرگ Gx یعنی یه لبه عمودی وجود داره و جهت تغییرات، افقی هست.
· تغییرات در راستای عمودی (Gy): این رو با فیلتری که به تغییرات افقی حساسه اندازه میگیره. عدد بزرگ Gy یعنی یه لبه افقی وجود داره و جهت تغییرات، عمودی هست.

جمع‌بندی نهایی:
سوبل مثل یک قطب‌نمای تشخیص مرز عمل میکنه. قدرت سیگنال رو میسنجه (قدرت لبه) و سوزنش رو به سمتی میچرخونه که ناگهانی‌ترین تغییر روشنایی رخ میده (جهت لبه). این "جهت" دقیقاً همون مفهوم سراشیبی هست که عمود بر راستای خود لبه است.
 

saalek110

Well-Known Member
شرح مشتق:


۱. مشتق (Derivative) چیه؟

در ریاضیات، مشتق یک تابع، نرخ تغییرات لحظه‌ای اون رو نشون میده. سه حالت داریم:

· مشتق بزرگ مثبت: تابع به سرعت در حال افزایش هست.
· مشتق بزرگ منفی: تابع به سرعت در حال کاهش هست.
· مشتق نزدیک صفر: تابع تقریباً ثابت و بدون تغییر هست.

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

---

۲. تعریف مجدد "تابع" در تصویر

در پردازش تصویر، "تابع" ما یک عکس هست. هر عکس رو میشه به صورت یک تابع دوبعدی در نظر گرفت:

f(x, y) = \text{شدت روشنایی پیکسل در مختصات } (x, y)

پس:

· در یک تصویر، x و y مختصات پیکسل هستند.
· مقدار f(x, y) یک عدد (مثلاً بین ۰ تا ۲۵۵ در تصاویر خاکستری) هست که شدت روشنایی رو نشون میده.

ایده اصلی در تشخیص لبه اینه:
لبه‌ها جاهایی از تصویر هستن که "مشتق" این تابع، ناگهان خیلی بزرگ میشه.

---

۳. چطور مشتق روی پیکسل‌ها اعمال میشه؟

چون تصویر یک موجودیت گسسته است (شامل پیکسل‌های جدا از هم)، نمیتونیم از فرمول‌های مشتق پیوسته (با حد و ε) استفاده کنیم. به جاش از تقریب‌های گسسته استفاده میکنیم. ساده‌ترین تقریب برای مشتق به این شکله:

\frac{df}{dx} \approx f(x+1) - f(x)

این یعنی:
برای پیدا کردن مشتق افقی در یک نقطه، کافیه مقدار پیکسل همسایه راست رو از مقدار همسایه چپ کم کنیم.

مثال کاملاً شفاف:

یک ردیف از پیکسل‌های یک تصویر رو با شدت روشنایی زیر در نظر بگیرید. می‌خوایم ببینیم لبه کجاست:

... ۲۰ , ۲۰ , ۲۰ , ۲۰ , ۱۵۰ , ۱۵۰ , ۱۵۰ , ۱۵۰ ...

موقعیت مقدار پیکسل ساده‌ترین تقریب مشتق (تغییرات)
... ۲۰ -
پیکسل قبل از لبه ۲۰ ۲۰ - ۲۰ = ۰ (بدون تغییر)
پیکسل روی لبه ۱۵۰ ۱۵۰ - ۲۰ = ۱۳۰ (تغییر شدید!)
پیکسل بعد از لبه ۱۵۰ ۱۵۰ - ۱۵۰ = ۰ (بدون تغییر)
... ۱۵۰ -

می‌بینی؟ مشتق دقیقاً روی پیکسلی که جهش روشنایی داشته، یک عدد خیلی بزرگ (۱۳۰) رو نشون میده و جای دیگه صفره. این یعنی همون نقطه، یک لبه رو تشخیص داده.

---

۴. تقریب سوبل — چرا فقط کم کردن دو تا پیکسل کافی نیست؟

روش بالا (کم کردن پیکسل همسایه) به شدت به نویز حساسه. اگه یه پیکسل تصادفاً یکم روشن‌تر باشه، مشتق اشتباهی یه عدد بزرگ رو نشون میده. راه حل، استفاده از هسته‌های سوبل هست که چندتا کارو همزمان انجام میده:

۱. مشتق‌گیری (پیدا کردن نرخ تغییرات):
به ردیف وسط هسته‌ها دقت کن:

G_x = \begin{bmatrix} -1 & 0 & +1 \\ -2 & 0 & +2 \\ -1 & 0 & +1 \end{bmatrix}

اینجا داریم پیکسل‌های سمت چپ رو از پیکسل‌های سمت راست کم میکنیم (مفهوم اصلی مشتق که گفتم). علت اینکه پیکسل‌های وسط صفر هستن اینه که میخوایم تغییرات رو حول پیکسل مرکزی بسنجیم (مشتق مرکزی).

۲. میانگین‌گیری برای کاهش نویز:
ببین که عمل تفریق فقط در یک ردیف انجام نمیشه، بلکه در سه ردیف تکرار میشه و مقادیر با هم جمع می‌شن:

· تفریق در ردیف بالا: (-1) + 0 + (+1)
· تفریق در ردیف وسط: (-2) + 0 + (+2)
· تفریق در ردیف پایین: (-1) + 0 + (+1)

این کار معادل اینه که اول یک فیلتر میانگین‌گیر نرم‌کننده (Smoothing) در راستای عمودی اعمال کنیم، و بعد مشتق افقی رو بگیریم. این همون ویژگی منحصربه‌فرد سوبل هست: مشتق‌گیری + کاهش نویز در یک عملیات.

اگر نماد ریاضی دوست دارید، هسته سوبل حاصلضرب یک فیلتر مشتق‌گیر [ -1 , 0 , +1 ] در یک فیلتر نرم‌کننده [ 1 , 2 , 1 ] هست که به صورت ماتریسی در هم ضرب شدن.

---

۵. آیا OpenCV خودش مشتق داشته باشه؟

خود OpenCV مفهوم "مشتق" به عنوان یک شیء (Object) نداره. بلکه مشتق از طریق توابعی که شامل هسته‌های مشتق‌گیر هستن محاسبه و اعمال میشه.

مهم‌ترین تابعی که مستقیم به سوبل مربوطه cv::Sobel() هست:

```cpp
cv::Sobel(src, dst, ddepth, dx, dy, ksize);
```

· dx=1, dy=0: یعنی فقط Gx (تغییرات افقی) رو حساب کن.
· dx=0, dy=1: یعنی فقط Gy (تغییرات عمودی) رو حساب کن.
· dx=1, dy=1: مشتق ترکیبی میده که خروجیش معمولاً اون چیزی نیست که برای تشخیص لبه می‌خوای.

همچنین تابع قدرتمندتر cv::Scharr() هم وجود داره که یک بهینه‌سازی از سوبل با هسته ۳x۳ هست و برای تشخیص تغییرات با فرکانس بالا دقت بیشتری داره. cv::Laplacian() هم مشتق مرتبه دوم رو حساب میکنه.

پس خلاصه اینکه: OpenCV خودش مفهوم مشتق رو به صورت انتزاعی ذخیره نمیکنه، بلکه توابعی داره که اون رو با کانولوشن هسته‌های خاص (مثل هسته سوبل) روی تصویر اعمال میکنن و خروجی (که همون نقشه مشتق/لبه‌هاست) رو بهت تحویل میدن.
 

saalek110

Well-Known Member
تعریف مجدد سوبل:

فیلتر سوبل (Sobel Operator) یک عملگر ریاضی در پردازش تصویر است که برای تشخیص لبه استفاده می‌شود. به زبان ساده، این فیلتر نقاطی از تصویر را که تغییر ناگهانی در شدت روشنایی دارند (لبه‌ها) پیدا می‌کند.

منطق اصلی

اساس کار آن مشتق‌گیری است. در یک لبه، مقدار پیکسل‌ها به سرعت تغییر می‌کند (مثلاً از تاریک به روشن). سوبل با محاسبه شیب (Gradient) این تغییرات، مکان و جهت لبه را مشخص می‌کند.

نحوه کار

این عملگر از دو هسته (Kernel) یا ماتریس ۳×۳ مجزا استفاده می‌کند:

· هسته افقی ($G_x$): لبه‌های عمودی را تشخیص می‌دهد.
· هسته عمودی ($G_y$): لبه‌های افقی را تشخیص می‌دهد.

G_x = \begin{bmatrix} -1 & 0 & +1 \\ -2 & 0 & +2 \\ -1 & 0 & +1 \end{bmatrix}
\quad \text{و} \quad
G_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ +1 & +2 & +1 \end{bmatrix}

این هسته‌ها روی تصویر حرکت کرده و با ضرب و جمع مقادیر، دو تصویر جدید می‌سازند. سپس با ترکیب نتایج $G_x$ و $G_y$، اندازه نهایی شیب (شدت لبه) به‌دست می‌آید:

G = \sqrt{G_x^2 + G_y^2}

و جهت لبه نیز از این رابطه محاسبه می‌شود:

\theta = \arctan\left(\frac{G_y}{G_x}\right)

چرا روش خوبی است؟

· کاهش نویز: برخلاف مشتق‌گیری ساده، مقادیر وسط بیشتر وزن دارند و تا حدی نویز را مهار می‌کند.
· محاسبه همزمان: هم شدت لبه را می‌دهد و هم جهت آن را.

یک مثال ساده

تصور کنید عکس یک کاغذ سفید دارید که یک مربع سیاه وسط آن است. فیلتر سوبل، فقط خطوط مرزی آن مربع را با پیکسل‌های پررنگ‌تر (سفید) نمایش می‌دهد و داخل مربع و پس‌زمینه را خالی (سیاه) می‌کند.
 

saalek110

Well-Known Member
یافتن مربع:

: خیر، لزوماً سوبل مناسب‌ترین روش برای یافتن مربع رسم شده روی کاغذ نیست

. سوبل انتخابی سریع و ساده است، اما برای هدف دقیق «پیدا کردن یک مربع»، مراحل آستانه‌گیری تطبیقی و تقریب چندضلعی بسیار مهم‌تر از خود عملگر لبه‌یابی هستند. با این حال، اگر مجبور باشیم فقط عملگرها را مقایسه کنیم، Canny تقریباً همیشه نتایج بهتری برای مربع فراهم می‌کند.

در ادامه بررسی می‌کنم چرا:

۱. مشکل اصلی سوبل برای مربع

خروجی سوبل یک تصویر خاکستری با لبه‌های ضخیم و گاهی ناهموار است. این ضخامت باعث می‌شود وقتی می‌خواهید خطوط را پیدا کنید (مثلاً با تبدیل هاف)، ممکن است برای یک ضلع مربع، چندین خط موازی تشخیص داده شود.

· لبه‌های ضخیم: سوبل شیب را با یک هسته ۳×۳ محاسبه می‌کند و پاسخی صاف و پهن تولید می‌کند.
· حساسیت به نویز: بافت کاغذ یا نوشته‌های روی آن می‌تواند لبه‌های کاذب زیادی ایجاد کند و تشخیص مرز اصلی مربع را سخت کند.

۲. مقایسه عملگرها: کدام بهتر است؟

عملگر مزایا برای مربع معایب برای مربع
Sobel سریع، تشخیص هر دو جهت. لبه‌های ضخیم و نامرتب. فقط لبه‌های قوی را خوب می‌گیرد و با لبه‌های ضعیف‌تر مربع (مثلاً مداد کمرنگ) مشکل دارد.
Canny بهترین گزینه. لبه‌ها را دقیقاً به پهنای ۱ پیکسل نازک می‌کند (Non-Max Suppression)، نویز را عالی حذف می‌کند و لبه‌های ضعیف متصل به قوی را حفظ می‌کند (Hysteresis). نیاز به تنظیم دو پارامتر آستانه دارد.
Laplacian لبه‌ها را از هر جهت می‌گیرد. به شدت به نویز حساس است و هر لکه کوچکی را برجسته می‌کند. برای کاغذ واقعی بسیار شلوغ می‌شود.

۳. راه‌حل عملی: زنجیره پردازش مناسب برای مربع

هیچ‌کدام از اینها به تنهایی «مربع» را پیدا نمی‌کنند. هدف نهایی شما باید پیدا کردن چهار گوشه باشد. فلوچارت استاندارد این است:

1. پیش‌پردازش: تصویر را خاکستری کنید و با Gaussian Blur نویز بافت کاغذ را بگیرید.
2. لبه‌یابی (انتخاب برتر: Canny): لبه‌های نازک و تمیز تولید کند.
3. یافتن کانتورها: با cv2.findContours تمام اشکال بسته را بیابید.
4. تقریب چندضلعی: روی هر کانتور از cv2.approxPolyDP استفاده کنید.
5. فیلتر مربع: کانتوری را انتخاب کنید که تقریب آن دقیقاً ۴ رأس داشته باشد، مساحتش معقول باشد و زوایایش حدود ۹۰ درجه باشند.

نتیجه‌گیری نهایی

اگر عکس کاغذ در شرایط ایده‌آل (نور یکنواخت، پس‌زمینه تمیز) باشد، سوبل هم جواب می‌دهد. ولی در شرایط واقعی، Canny به دلیل تولید لبه‌های تک‌پیکسلی، کار را برای تشخیص دقیق چهار ضلع مربع بسیار راحت‌تر می‌کند و انتخاب بهتری است.
 

جدیدترین ارسال ها

بالا