الرؤية الحاسوبية1986تأسيسي10 دقيقة قراءة

مقاربة حسابية لكشف الحواف

A Computational Approach to Edge Detection

Canny, J. — IEEE Transactions on Pattern Analysis and Machine Intelligence

المشكلة

كاشفات الحواف المبكرة — مثل روبرتس وبريويت وسوبل — كانت تعتمد على أقنعة اشتقاق بسيطة للبحث عن التغيُّرات في شدة الإضاءة. سرعتها كانت ميزتها الوحيدة، لكن نتائجها كانت مليئة بالتشويش: حواف سميكة ومتقطعة لا تعكس الحدود الفعلية بدقة. والمشكلة الأعمق أنّ زيادة التنعيم لمكافحة التشويش كانت تُضيّع دقة مواقع الحواف نفسها. لم يكن هناك إطار نظري واضح يوازن بين جودة الكشف ودقة التحديد المكاني، ولا آلية تضمن أن كل حافة حقيقية تظهر كخط استجابة واحد فقط.

الإسهام

حوّل كاني مسألة إلى مسألة أمثَلة رياضية مبنية على ثلاثة معايير واضحة: الأول هو تعظيم (أي أن يكتشف الحواف الحقيقية ويتجاهل التشويش)، والثاني هو تقليل الانحراف عن الموقع الفعلي للحافة، والثالث هو ضمان ظهور استجابة واحدة فقط لكل حافة. أثبت أنّ هذه المعايير تقود إلى مرشّح يُقرَّب بدقة عالية الأولى لدالة غاوسية، ثم بنى مساراً عملياً من أربع مراحل: تنعيم غاوسي ← حساب التدرُّج ← كبت غير الأعظميات ← ترشيح بعتبة مزدوجة. المحصّلة: حواف نظيفة بعرض بكسل واحد مع رفض منهجي للتشويش.

الأثر

هذه الورقة هي الأكثر اقتباساً في تاريخ كشف الحواف ضمن (قرابة 30,000 اقتباس). كاشف كاني أصبح الخطوة الأولى شبه الإلزامية في أي نظام رؤية حاسوبية كلاسيكي — سواء في كشف الأجسام أو التصوير الطبي أو الفحص الصناعي. الإطار النظري الذي وضعه كاني أثّر في تصميم كاشفات السمات لعقود، ومسار معالجته لا يزال مدمجاً في OpenCV وMATLAB وكل مكتبة معالجة صور كبرى. كلٌّ من SIFT وHOG يقوم في جوهره على حسابات التدرُّج التي تعود جذورها إلى صياغة كاني.

تخيّل أنك في غرفة مظلمة تمرّر إصبعك على جدار لتحدّد أين ينتهي لون ويبدأ لون آخر. إصبعك العاري يلتقط كل شقّ وحبّة غبار — وهذا بالضبط ما نسميه . الآن لو لبستَ قفازاً سميكاً، ستختفي هذه التفاصيل الزائفة، لكنك ستتجاوز الحدّ الحقيقي بسنتيمتر أو أكثر — أي أنك كسبتَ جودة الكشف على حساب دقة التحديد المكاني.

كاشف كاني هو بمثابة القفاز المصمَّم بعناية رياضية: يُنعّم بالقدر الكافي تماماً لإخماد الضوضاء دون أن يُبعد إصبعك عن الحدّ الحقيقي أكثر مما تفرضه قوانين معالجة الإشارات. ثم بدلاً من ترك أثر سميك، يسير على قمة التغيُّر بالضبط ويرسم خطاً واحداً حاداً لا أكثر.

المشكلة: الكاشفات المبكرة مشوّشة وسميكة وبلا أساس نظري

قبل كاني، كان كشف الحواف أشبه بمجموعة وصفات متفرّقة لا يجمعها إطار نظري. مثلاً، مُعامل سوبل يُجري عملية مع الصورة باستخدام بحجم 3×3 لتقريب المشتقات الأفقية والرأسية، ثم يحسب مقدار . النتيجة مقبولة من حيث المبدأ، لكنها تُنتج حوافاً سميكة ومشوَّشة لأنه لا توجد آلية لإخماد الضوضاء دون إضاعة دقة مواقع الحواف، ولا ضمان لظهور خط نظيف واحد عند كل حدّ حقيقي.

مقاربة لابلاسيان الغاوسية (LoG) خطت خطوة للأمام بتنعيم الصورة أولاً ثم البحث عن نقاط عبور الصفر في المشتقة الثانية. لكن هذه النقاط تُشكّل محيطات مغلقة لا تتطابق بالضرورة مع حدود الأجسام الفعلية، والطريقة ظلّت تفتقر إلى توازن منهجي بين مقاومة الضوضاء ودقة التحديد المكاني.

ما كان المجال يحتاجه فعلاً ليس إضافياً — بل تعريف رياضي واضح لمعنى «كشف حواف جيّد»، بحيث يمكن اشتقاق الحل الأمثل منه مباشرةً.

افتح في المختبر
قارن نتائج سوبل ولابلاسيان الغاوسية وكاني على الصورة نفسها. لاحظ كيف ينتج كاني حوافاً رفيعة ونظيفة، بينما حواف سوبل سميكة ولابلاسيان الغاوسية تُعطي حلقات مغلقة لا تعكس حدود الأجسام.
تستيقظ التجربة عند وصولك…

رؤية كاني: عرِّف معنى «الجيد» ثم حسِّن

الإنجاز الحقيقي لكاني لم يكن اختراع مرشّح جديد — بل طرح سؤال جديد من الأساس. سأل: ماذا لو صغنا رياضياً الصفات التي يجب أن يمتلكها كاشف حواف مثالي، ثم تركنا تقودنا إلى شكل المرشّح الأنسب؟ وقد حدّد ثلاثة معايير لا بدّ لأي كاشف جيد أن يحقّقها:

1. الكشف (نسبة إشارة إلى ضوضاء عالية) — يجب أن يلتقط الكاشف كل حافة حقيقية ويتجاهل الضوضاء. رياضياً، هذا يعني تعظيم نسبة استجابة المرشّح للحافة الحقيقية مقارنةً باستجابته للتشويش.

2. دقة التحديد المكاني — يجب أن تقع الحافة المكتشَفة أقرب ما يمكن إلى الموقع الفعلي للحافة في الصورة، أي أن يكون خطأ التموضع في حدّه الأدنى.

3. الاستجابة الوحيدة — كل حافة حقيقية يجب أن تولّد خطاً واحداً فقط في الخرج، وليس عدة خطوط متوازية. هذا الشرط يمنع ظهور حواف سميكة أو مكرّرة.

SNR=W0f(x)G(x)dxσnW0f2(x)dx\text{SNR} = \frac{\left|\int_{-W}^{0} f(-x)\, G'(x)\,dx\right|} {\sigma_n \sqrt{\int_{-W}^{0} f^2(x)\,dx}}
معيار الكشف — نسبة الإشارة إلى الضوضاءفي البسط نجد استجابة المرشّح لحافة درَجية، وهي الإشارة المفيدة التي نريد التقاطها. أما المقام فيمثّل مقدار استجابة المرشّح للضوضاء الغاوسية العشوائية. حين نعظّم هذه النسبة، نضمن أن المرشّح يستجيب بقوة للحواف الحقيقية ويبقى هادئاً أمام التشويش.
Localization=f(0)σnW0f2(x)dx\text{Localization} = \frac{|f'(0)|} {\sigma_n \sqrt{\int_{-W}^{0} f'^2(x)\,dx}}
معيار التموضع — دقة موضع الحافةهذا المعيار يقيس مدى حدّة الذروة في خرج المرشّح عند الموقع الحقيقي للحافة. كلما ارتفعت القيمة، كان الموقع المكتشَف أقرب إلى الموقع الفعلي للحافة في الصورة.
افتح في المختبر
حرّك شريط سيغما لتشاهد المقايضة بنفسك: قيمة صغيرة تحافظ على دقة مواقع الحواف لكنها تسمح بمرور الضوضاء، وقيمة كبيرة تُزيل الضوضاء لكنها تُفقد الحواف دقتها المكانية.
تستيقظ التجربة عند وصولك…

مسار كاني: أربع مراحل من البكسلات إلى الحواف

حوّل كاني معاييره النظرية إلى عملية تمرّ بأربع مراحل متتالية. كل مرحلة تعالج جانباً محدداً من المشكلة، والمحصّلة النهائية هي حواف نظيفة بعرض واحد ومُحدَّدة مكانياً بدقة. تخيّلها كخط إنتاج: الصورة المشوّشة تدخل من جهة، وتخرج من الجهة الأخرى حواف مصقولة جاهزة للاستخدام.

افتح في المختبر
اضغط على كل مرحلة لتشاهد أثرها على الصورة، وتابع التحوّل عبر المراحل الأربع.
تستيقظ التجربة عند وصولك…

المرحلة الأولى: التنعيم الغاوسي — ممحاة الضوضاء

أي صورة حقيقية تحتوي على قدر من الضوضاء. مستشعر الكاميرا يُضيف تذبذبات عشوائية إلى قيم البكسلات، كما أنّ النسيج السطحي للأجسام يخلق تغيُّرات دقيقة في الإضاءة لا علاقة لها بالحدود الفعلية. لو حسبنا المشتقات مباشرة على الصورة الخام، لظهرت كل نقطة عشوائية وكأنها حافة.

الحل هو تنعيم الصورة أولاً باستخدام مرشّح غاوسي. الفكرة بسيطة: نستبدل كل بكسل بمتوسط مُرجَّح لجيرانه، بحيث يحصل الجيران القريبون على أوزان أعلى والبعيدون على أوزان أقل — تماماً كشكل الجرس. المعامل σ (سيغما) يتحكم في عرض هذا الجرس: قيمة صغيرة تعني تنعيماً خفيفاً، وقيمة كبيرة تعني تنعيماً قوياً. والميزة العملية أنّ الالتفاف الغاوسي ثنائي الأبعاد يمكن تفكيكه إلى التفافين أحاديَّي البُعد (أفقي ثم رأسي)، مما يجعل الحساب أسرع بكثير.

G(x,y)=12πσ2ex2+y22σ2G(x, y) = \frac{1}{2\pi\sigma^2}\, e^{-\frac{x^2 + y^2}{2\sigma^2}}
نواة غاوسية ثنائية الأبعادالبكسل المركزي يحصل على أعلى وزن، ثم يتناقص الوزن بسلاسة كلما ابتعدنا عنه. المعامل σ يحدّد مدى الانتشار: σ صغيرة تعني تنعيماً خفيفاً يحافظ على التفاصيل، وσ كبيرة تعني تنعيماً قوياً يُزيل التشويش لكنه قد يُضيّع بعض الحدود الدقيقة.
افتح في المختبر
غيّر قيمة σ وراقب أثر التنعيم الغاوسي. القيم الصغيرة تحافظ على التفاصيل لكنها تُبقي التشويش، والقيم الكبيرة تُزيل التشويش لكنها تُفقد الحواف حدّتها.
تستيقظ التجربة عند وصولك…

المرحلة الثانية: حساب التدرُّج — إيجاد تغيُّرات الشدة

بعد التنعيم، نحتاج إلى تحديد المواقع التي يتغيّر فيها السطوع بسرعة — فهذه هي المرشَّحة لأن تكون حوافاً. تدرُّج الصورة المُنعَّمة يعطينا معلومتين أساسيتين: مقدار التغيُّر (أي مدى قوة الحافة المحتملة) واتجاهه (أي الجهة التي يتغيّر فيها السطوع).

من الناحية العملية، أثبت كاني أنّ تنعيم الصورة ثم اشتقاقها يُعادل إجراء التفاف واحد مع مشتقة الدالة الغاوسية مباشرةً — أي خطوة واحدة بدلاً من خطوتين. تُحسب الأفقية والرأسية باستخدام مُعاملات فرق بسيطة تشبه أنوية سوبل، ثم يُحسب من ناتجها مقدار التدرُّج واتجاهه عند كل بكسل.

I=Gx2+Gy2,θ=arctan ⁣(GyGx)|\nabla I| = \sqrt{G_x^2 + G_y^2}, \qquad \theta = \arctan\!\left(\frac{G_y}{G_x}\right)
مقدار التدرُّج واتجاههG_x وG_y هما المشتقتان الأفقية والرأسية للصورة بعد التنعيم. المقدار يدلّنا على قوة الحافة عند كل نقطة، والاتجاه يُحدّد الجهة التي يتغيّر فيها السطوع — وهي دائماً عمودية على امتداد الحافة نفسها.
افتح في المختبر
لاحظ كيف تتضافر المشتقتان الأفقية والرأسية لتُعطي مقدار التدرُّج واتجاهه. الأسهم توضّح اتجاه التغيُّر عند كل بكسل.
تستيقظ التجربة عند وصولك…

المرحلة الثالثة: كبت غير الأعظميات — الترقيق إلى بكسل واحد

بعد حساب التدرُّج، تظهر الحواف على شكل تلال عريضة ذات قيم مرتفعة — تخيّلها كسلاسل جبلية تنظر إليها من الأعلى. ما نريده هو مسار واحد رفيع يسير على قمة كل سلسلة، وليس الجبل كلّه. هنا يأتي دور : عند كل بكسل، تنظر الخوارزمية في اتجاه التدرُّج وتسأل: «هل أنا الأعلى قيمةً مقارنة بجارَيَّ في هذا الاتجاه؟» إذا لم يكن كذلك، تُصفَّر قيمته.

الصورة الذهنية الأوضح: تخيّل أنك تُسلّط شعاعاً عبر كل تلّ في اتجاه التدرُّج — القمة وحدها تبقى مضيئة، والمنحدرات على الجانبين تُمحى. النتيجة هي حواف بعرض بكسل واحد بالضبط — أدقّ تمثيل ممكن لكل حدّ.

افتح في المختبر
راقب كيف تتحوّل تلال التدرُّج العريضة إلى خطوط بعرض بكسل واحد. في كل اتجاه، القمة فقط هي التي تنجو من الحذف.
تستيقظ التجربة عند وصولك…

المرحلة الرابعة: الترشيح بعتبة مزدوجة — ربط ذكي للحواف

بعد كبت غير الأعظميات، نحصل على خطوط رفيعة — لكن بعضها يمثّل حوافاً حقيقية وبعضها مجرد أثر ضوضاء. لو استخدمنا عتبة واحدة لفصلهما، سنقع في مشكلة: عتبة مرتفعة تحذف حوافاً ضعيفة لكنها حقيقية، وعتبة منخفضة تُدخل التشويش. حلّ كاني الذكي هو استخدام عتبتين — عُليا ودُنيا:

  • أي بكسل فوق العتبة العُليا يُعتبر حافة مؤكّدة فوراً.
  • أي بكسل تحت العتبة الدُنيا يُستبعد تماماً.
  • أي بكسل بين العتبتين لا يُقبل إلا إذا كان متصلاً ببكسل حافة مؤكّدة — أي أنه يلتحق بجار واثق.

آلية العتبة المزدوجة هذه (hysteresis) هي السرّ في إنتاج محيطات حواف متصلة ونظيفة. الفكرة أشبه بسلسلة معدنية: الحلقة القوية تبدأ السلسلة، والحلقات الأضعف يمكنها أن تمتدّ منها، لكن حلقة ضعيفة بمفردها لا تستطيع أن تبدأ سلسلة جديدة.

افتح في المختبر
حرّك شريطَي العتبة العُليا والدُنيا. الحواف القوية (الخضراء) تبدأ السلاسل، والحواف الضعيفة (الصفراء) تمتدّ منها فقط إذا كانت متصلة بها. البكسلات المرفوضة (الحمراء) تقع تحت العتبة الدُنيا.
تستيقظ التجربة عند وصولك…

الخوارزمية الكاملة في شيفرة برمجية

كشف حواف كاني، خطوة بخطوةpython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

import numpy as np
from scipy.ndimage import gaussian_filter, sobel

def canny(image, sigma=1.0, low=0.05, high=0.15):
    """كاشف كاني الكامل من الصفر."""
    # المرحلة 1: التنعيم الغاوسي — إزالة الضوضاء
    smoothed = gaussian_filter(image, sigma=sigma)

    # المرحلة 2: مقدار التدرُّج واتجاهه
    gx = sobel(smoothed, axis=1)          # المشتقة الأفقية
    gy = sobel(smoothed, axis=0)          # المشتقة الرأسية
    mag = np.hypot(gx, gy)                # قوة الحافة
    mag = mag / mag.max()                 # تسوية إلى [0, 1]
    angle = np.arctan2(gy, gx)            # اتجاه التدرُّج

    # المرحلة 3: كبت غير الأعظميات — أبقِ قمم التلال فقط
    nms = np.zeros_like(mag)
    angle_q = (np.round(angle / (np.pi / 4)) % 4).astype(int)
    rows, cols = mag.shape
    for i in range(1, rows - 1):
        for j in range(1, cols - 1):
            q = angle_q[i, j]
            # تحقّق من الجيران في اتجاه التدرُّج
            if q == 0:   n1, n2 = mag[i, j-1], mag[i, j+1]
            elif q == 1: n1, n2 = mag[i-1, j+1], mag[i+1, j-1]
            elif q == 2: n1, n2 = mag[i-1, j], mag[i+1, j]
            else:        n1, n2 = mag[i-1, j-1], mag[i+1, j+1]
            if mag[i, j] >= n1 and mag[i, j] >= n2:
                nms[i, j] = mag[i, j]

    # المرحلة 4: الترشيح بعتبة مزدوجة — ربط الحواف
    strong = nms >= high
    weak = (nms >= low) & ~strong
    edges = np.zeros_like(nms, dtype=bool)
    edges[strong] = True
    # وصل البكسلات الضعيفة بالجيران الأقوياء
    from scipy.ndimage import binary_dilation
    edges = edges | (weak & binary_dilation(strong))
    return edges.astype(np.float64)

لماذا غيَّر كل شيء — أساس استخلاص السمات

قبل كاني، كان كشف الحواف حِرفة تعتمد على الخبرة والتجربة. بعد كاني، تحوّل إلى هندسة مبنية على أسس رياضية. أثبتت ورقته أنّ بالإمكان صياغة ما نريده من النظام البصري كمعايير رياضية دقيقة، ثم ترك الأمثَلة تقودنا إلى الحل. هذه الفلسفة — «حدّد الهدف أولاً ثم اشتقّ الحل» — أثّرت في كل ما جاء بعدها في الرؤية الحاسوبية.

حساب التدرُّج الذي يقع في صميم عمل كاني أصبح الأساس لجيل كامل من واصفات . مثلاً، HOG يقسم الصورة إلى خلايا ويبني مدرّج تكرار لاتجاهات التدرُّج في كل خلية — أي أنه يأخذ حقل التدرُّج نفسه الذي يحسبه كاني لكنه ينظّمه لأغراض التعرّف بدلاً من رسم الحواف. أما SIFT فيذهب أبعد بحساب التدرُّجات على مقاييس متعددة بحثاً عن نقاط مفتاحية تصمد أمام تغيُّرات الحجم وزاوية الرؤية.

  1. 1970

    مُعامل روبرتس المتقاطع

    من أقدم كاشفات الحواف، يعتمد على مُعامل تدرُّج متقاطع بحجم 2×2. يتميّز بسرعته لكنه شديد الحساسية للضوضاء، فتأتي نتائجه غير موثوقة.

  2. 1973

    مُعامل سوبل

    نواة التفاف بحجم 3×3 تُقرّب مشتقات الصورة. كان الأداة الأكثر استخداماً في كشف الحواف لسنوات، رغم أنّ حوافه تخرج سميكة ومشوّشة.

  3. 1980

    مار-هيلدريث (لابلاسيان الغاوسية)

    يُنعّم الصورة بدالة غاوسية ثم يبحث عن نقاط عبور الصفر في لابلاسيان الصورة. مقاربة أكثر منهجية من سابقاتها، لكنها تُنتج محيطات مغلقة لا تتطابق بالضرورة مع الحدود الفعلية للأجسام.

  4. 1986

    كاشف كاني للحواف

    كاشف الحواف الأمثل المبني على ثلاثة معايير رياضية صريحة. مساره ذو المراحل الأربع أصبح المعيار المرجعي في كشف الحواف لعقود.

  5. 1999

    SIFT

    يبني على حسابات التدرُّج لاستخراج نقاط مفتاحية تبقى مستقرة مهما تغيّر حجم الصورة أو زاوية التقاطها أو دورانها.

  6. 2005

    HOG

    ينظّم اتجاهات التدرُّج — المشابهة لما يحسبه كاني — في مدرّجات تكرار خلوية، واستُخدم بنجاح كبير في كشف المشاة والتعرّف على الأجسام.

  7. 2012

    AlexNet — كاشفات حواف مُتعلَّمة

    الشبكات الالتفافية العميقة تتعلم تلقائياً مرشّحات للحواف والتدرُّجات في طبقاتها الأولى، فتكتشف بنفسها ما كان كاني قد اشتقّه يدوياً. بداية عصر التعلُّم الآلي للسمات البصرية.

في كل مرة تكتب cv2.Canny() في OpenCV أو edge() في MATLAB، فأنت تُشغّل المسار نفسه ذا المراحل الأربع الذي صمّمه كاني عام 1986. الرياضيات لم تتغيّر لسبب بسيط: المعايير التي وضعها كانت صحيحة من الأساس. أفضل كاشف حواف لا يزال هو الذي يُعظّم الكشف، ويُقلّل خطأ التحديد المكاني، ويُنتج استجابة واحدة فقط لكل حافة حقيقية.

المرجعCanny, J.. A Computational Approach to Edge Detection. IEEE Transactions on Pattern Analysis and Machine Intelligence, 1986.

مصطلحات هذه الورقة