OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

OpenCV Edge Detection ב-Python עם cv2.Canny()

מבוא

זיהוי קצוות הוא משהו שאנחנו עושים באופן טבעי, אבל הוא לא כל כך קל כשזה מגיע להגדרת כללים עבור מחשבים. בעוד ששיטות שונות הומצאו, השיטה השלטת פותחה על ידי ג'ון פ. קאני בשנת 1986, והיא נקראת כיאה שיטת קאני.

זה מהיר, חזק למדי ועובד כמעט הכי טוב שהוא יכול לעבוד עבור סוג הטכניקה שהוא. בסוף המדריך, תדעו לבצע זיהוי קצה בזמן אמת בסרטונים, ולהפיק משהו בסגנון:

זיהוי אדג 'קני

מהי שיטת קאני? זה מורכב מארבע פעולות נפרדות:

  • החלקה גאוסית
  • מעברי מחשוב
  • דיכוי לא מקס
  • סף היסטרזיס

החלקה גאוסית משמש כשלב ראשון ל"גיהוץ" של תמונת הקלט, ולרכך את הרעש, מה שהופך את הפלט הסופי להרבה יותר נקי.

מעברי תמונה היו בשימוש ביישומים קודמים לזיהוי קצה. במיוחד, מסנני Sobel ו-Scharr מסתמכים על מעברי תמונה. מסנן סובל מסתכם לשני גרעינים (Gx ו Gy), איפה Gx מזהה שינויים אופקיים, בעוד Gy מזהה שינויים אנכיים:

G

x

=

[

-
1

0

+
1

-
2

0

+
2

-
1

0

+
1

]

G

y

=

[

-
1

-
2

-
1

0

0

0

+
1

+
2

+
1

]

כאשר אתה מחליק אותם על תמונה, כל אחד מהם "יקלוט" (ידגיש) את הקווים בכיוון שלו. גרעיני Scharr פועלים באותו אופן, עם ערכים שונים:

G

x

=

[

+
3

0

-
3

+
10

0

-
10

+
3

0

-
3

]

G

y

=

[

+
3

+
10

+
3

0

0

0

-
3

-
10

-
3

]

מסננים אלה, ברגע שהם מסובבים על התמונה, יפיקו מפות תכונה:

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

קרדיט תמונה: Davidwkennedy

עבור מפות תכונה אלה, אתה יכול לחשב את גודל שיפוע ו כיוון שיפוע – כלומר כמה אינטנסיבי השינוי (כמה סביר שמשהו הוא קצה) ולאיזה כיוון השינוי מצביע. מכיוון ש-Gy מציין את השינוי האנכי (Y-gradient), ו-Gx מציין את השינוי האופקי (X-gradient) - אתה יכול לחשב את הגודל על ידי יישום פשוט של משפט פיתגורס, כדי לקבל את ההיפותנוזה של המשולש שנוצר על ידי "שמאל" ו כיוונים "נכונים":

$$
{G} ={sqrt {{{G} _{x}}^{2}+{{G} _{y}}^{2}}}
$$

באמצעות הגודל והכיוון, אתה יכול להפיק תמונה עם הקצוות שלה מודגשים:

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

קרדיט תמונה: Davidwkennedy

עם זאת - אתה יכול לראות כמה רעש נתפס גם מהטקטורה של הלבנים! מעברי תמונה רגישים מאוד לרעש. זו הסיבה שמסנני Sobel ו- Scharr שימשו כמרכיב, אך לא הגישה היחידה בשיטת קאני. החלקה גאוסית עוזרת גם כאן.

דיכוי לא מקס

בעיה בולטת עם מסנן Sobel היא שהקצוות לא ממש ברורים. זה לא כאילו מישהו לקח עיפרון וצייר קו כדי ליצור ליניארט של התמונה. הקצוות בדרך כלל לא כל כך ברורים בתמונות, שכן האור מתפזר בהדרגה. עם זאת, אנו יכולים למצוא את הקו המשותף בקצוות, ולהדחיק את שאר הפיקסלים סביבו, ולגרום לקו הפרדה נקי ודק במקום זאת. זה ידוע בשם Non-Max Supression! הפיקסלים הלא-מקסימליים (אלה הקטנים מזה שאנו משווים אותם אליו בשדה מקומי קטן, כגון ליבה של 3×3) נדחקים. הקונספט ישים ליותר משימות מזה, אבל בואו נקשר אותו להקשר הזה לעת עתה.

סף היסטרזיס

רבים שאינם קצוות יכולים וככל הנראה יוערכו כקצוות, עקב תנאי תאורה, החומרים בתמונה וכו'. בגלל הסיבות השונות שחישובים מוטעים אלו מתרחשים - קשה לבצע הערכה אוטומטית של מה זה קצה בוודאי ומהו לא. אתה יכול להגדיר מעברי סף, ולכלול רק את החזקים יותר, בהנחה שהקצוות "אמיתיים" חזקים יותר מקצוות "מזויפים".

סימון סף עובד כמעט כמו רגיל - אם השיפוע נמצא מתחת לסף נמוך יותר, הסר אותו (אפס אותו), ואם הוא מעל סף עליון נתון, שמור אותו. כל מה שבין הגבול התחתון לגבול העליון נמצא ב"אזור האפור". אם קצה כלשהו בין הספים מחובר ל- a יתרון סופי (כאלה שמעל הסף) - הם גם נחשבים לקצוות. אם הם לא מחוברים, סביר להניח שהם מייצגים יתרון שגוי.

זה סף היסטרזיס! למעשה, זה עוזר לנקות את הפלט הסופי ולהסיר קצוות שקריים, בהתאם למה שאתה מסווג כקצה שקרי. כדי למצוא ערכי סף טובים, בדרך כלל תתנסו עם גבולות תחתונים ועליונים שונים עבור הסף, או תשתמשו בשיטה אוטומטית כמו השיטה של ​​Otsu או שיטת המשולש.

בואו נטען תמונה ונטען אותה בגווני אפור (קאני, בדיוק כפי שסובל/שר דורשת שתמונות יהיו בגווני אפור):

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('finger.jpg', cv2.IMREAD_GRAYSCALE)
img_blur = cv2.GaussianBlur(img, (3,3), 0)

plt.imshow(img_blur, cmap='gray')

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

תמונת תקריב של אצבע תשמש כר בדיקה טוב לזיהוי קצוות - לא קל להבחין בטביעת אצבע מהתמונה, אבל אנחנו יכולים להעריך אחת.

זיהוי קצה בתמונות עם cv2.Canny()

ניתן ליישם את האלגוריתם של Canny באמצעות OpenCV's Canny() שיטה:

cv2.Canny(input_img, lower_bound, upper_bound)

עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!

למצוא את האיזון הנכון בין הגבול התחתון לגבול העליון יכול להיות מסובך. אם שניהם נמוכים - יהיו לך מעט קצוות. אם הגבול התחתון נמוך והעליון גבוה - יהיה לך רעש. אם שניהם גבוהים וקרובים זה לזה - יהיו לך מעט קצוות. לנקודה הנכונה יש מספיק פער בין הגבולות, ויש להם אותם בקנה מידה הנכון. לְנַסוֹת!

תמונת הקלט תטושטש בשיטת Canny, אך לעתים קרובות, תפיק תועלת מטשטוש שלה לפני זה נכנס גם כן. השיטה מחילה טשטוש גאוסי בגודל 5×5 על הקלט לפני מעבר לשאר הפעולות, אבל אפילו עם הטשטוש הזה, רעש מסוים עדיין יכול לחלחל, אז טשטשנו את התמונה לפני הזנתה לאלגוריתם:


edge = cv2.Canny(img_blur, 20, 30)

fig, ax = plt.subplots(1, 2, figsize=(18, 6), dpi=150)
ax[0].imshow(img, cmap='gray')
ax[1].imshow(edge, cmap='gray')

זו התוצאה:

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

הערכים של 20 ו 30 כאן הם לא שרירותיים - בדקתי את השיטה על פרמטרים שונים, ובחרתי בסט שנראה שהניב תוצאה ראויה. האם נוכל לנסות להפוך את זה לאוטומטי?

סף אוטומטי עבור cv2.Canny()?

האם אתה יכול למצוא קבוצה אופטימלית של ערכי סף? כן, אבל זה לא תמיד עובד. אתה יכול לעשות חישוב משלך עבור איזה ערך טוב, ולאחר מכן להתאים את הטווח באמצעות a sigma סביב הסף הזה:

lower_bound = (1-sigma)*threshold
upper_bound = (1+sigma)*threshold

מתי sigma, זה אומר, 0.33 – הגבולות יהיו 0.66*threshold ו 1.33*threshold, המאפשר טווח של ~1/3 סביבו. עם זאת, למצוא את threshold זה מה שקשה יותר. OpenCV מספקת לנו את השיטה של ​​Otsu (עובדת מצוין לתמונות דו-מודאליות) ואת שיטת המשולש. בואו ננסה את שניהם, כמו גם ניקח חציון פשוט של ערכי הפיקסלים כאפשרות השלישית:

otsu_thresh, _ = cv2.threshold(img_blur, 0, 255, cv2.THRESH_OTSU)
triangle_thresh, _ = cv2.threshold(img_blur, 0, 255, cv2.THRESH_TRIANGLE)
manual_thresh = np.median(img_blur)

def get_range(threshold, sigma=0.33):
    return (1-sigma) * threshold, (1+sigma) * threshold

otsu_thresh = get_range(otsu_thresh)
triangle_thresh = get_range(triangle_thresh)
manual_thresh = get_range(manual_thresh)

print(f"Otsu's Threshold: {otsu_thresh} nTriangle Threshold: {triangle_thresh} nManual Threshold: {manual_thresh}")

זו התוצאה:

Otsu's Threshold: (70.35, 139.65) 
Triangle Threshold: (17.419999999999998, 34.58) 
Manual Threshold: (105.18999999999998, 208.81)

אלה די שונים! מהערכים שראינו בעבר, אנו יכולים לצפות ששיטת המשולש פועלת בצורה הטובה ביותר כאן. הסף הידני אינו מושכל במיוחד, מכיוון שהוא רק לוקח את ערך הפיקסלים החציוני, ובסופו של דבר יש לו סף בסיס גבוה שמוכפל עוד יותר לטווח רחב עבור תמונה זו. השיטה של ​​אוטסו סובלת מכך פחות, אך סובלת בכל זאת.

אם נריץ את Canny() שיטה עם טווחי הסף האלה:

edge_otsu = cv2.Canny(img_blur, *otsu_thresh)
edge_triangle = cv2.Canny(img_blur, *triangle_thresh)
edge_manual = cv2.Canny(img_blur, *manual_thresh)

fig, ax = plt.subplots(1, 3, figsize=(18, 6), dpi=150)
ax[0].imshow(edge_otsu, cmap='gray')
ax[1].imshow(edge_triangle, cmap='gray')
ax[2].imshow(edge_manual, cmap='gray')

הערה: הפונקציה מצפה למספר ארגומנטים, והסף שלנו הוא tuple בודד. אנחנו יכולים לפרק את הטפול לתוך ארגומנטים מרובים על ידי הקדמת זה עם *. זה עובד גם על רשימות וקבוצות, וזו דרך מצוינת לספק ארגומנטים מרובים לאחר השגתם באמצעים פרוגרמטיים.

זו התוצאה:

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

שיטת המשולש עבדה די טוב כאן! זה לא ערובה שזה יעבוד טוב גם במקרים אחרים.

זיהוי קצה בזמן אמת בסרטונים עם cv2.Canny()

לבסוף, בואו נחיל זיהוי קצוות של Canny על סרטון בזמן אמת! נציג את הסרטון המעובד (כל פריים כפי שהוא נעשה) באמצעות cv2.imshow() שמציג חלון עם המסגרת שברצוננו להציג. עם זאת, אנו גם נשמור את הסרטון בקובץ MP4 שניתן לבדוק ולשתף מאוחר יותר.

כדי לטעון סרטון באמצעות OpenCV, אנו משתמשים ב- VideoCapture() שיטה. אם נעבור פנימה 0 - הוא יקליט ממצלמת האינטרנט הנוכחית, כך שתוכל להפעיל את הקוד גם במצלמת האינטרנט שלך! אם תעביר שם קובץ, זה יטען את הקובץ:

def edge_detection_video(filename):
    cap = cv2.VideoCapture(filename)
    
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    out = cv2.VideoWriter('output.mp4', fourcc, 30.0, (int(cap.get(3)), int(cap.get(4))), isColor=False)
    
    while cap.isOpened():
        (ret, frame) = cap.read()
        if ret == True:
            frame = cv2.GaussianBlur(frame, (3, 3), 0)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            edge = cv2.Canny(frame, 50, 100)
            out.write(edge)
            cv2.imshow('Edge detection', edge)
        else:
            break

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()

edge_detection_video('secret_video.mp4')

השמיים VideoWriter מקבל מספר פרמטרים - שם קובץ הפלט, FourCC (ארבעה קודי קודקים, המציינים את ה-codec המשמש לקידוד הווידאו), קצב הפריימים והרזולוציה כ-tuple. כדי לא לנחש או לשנות את גודל הסרטון - השתמשנו ברוחב ובגובה של הסרטון המקורי, שהושגו באמצעות VideoCapture מופע שמכיל נתונים על הסרטון עצמו, כגון הרוחב, הגובה, המספר הכולל של פריימים וכו'.

בזמן שהלכידה נפתחת, אנחנו מנסים לקרוא את הפריים הבא איתו cap.read(), אשר מחזיר קוד תוצאה ואת המסגרת הבאה. קוד התוצאה הוא True or False, המציין את נוכחות הפריים הבא או היעדר שלו. רק כשיש מסגרת, ננסה לעבד אותה הלאה, אחרת נשבור את הלולאה. עבור כל מסגרת חוקית, אנו מעבירים אותו דרך טשטוש גאוסי, ממירים אותו לגווני אפור, מפעילים cv2.Canny() עליו וכתוב אותו באמצעות ה VideoWriter לדיסק, והצג באמצעות cv2.imshow() לצפייה חיה.

לבסוף, אנו משחררים את הלכידה וכותב הווידאו, מכיוון ששניהם עובדים עם קבצים בדיסק, ומשמידים את כל החלונות הקיימים.

כאשר אתה מפעיל את השיטה עם א secret_video.mp4 קלט - תראה חלון קופץ ולאחר שזה יסתיים, קובץ בספריית העבודה שלך:

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

סיכום

במדריך זה, בדקנו כיצד פועל זיהוי הקצוות של Canny, והחלקים המרכיבים אותו - החלקה גאוסית, מסנני Sobel ושיפוע תמונה, Non-Max Supression ו-Hysteresis Thresholding. לבסוף, בדקנו שיטות לחיפוש טווח סף אוטומטי עבור זיהוי קצוות של Canny עם cv2.Canny(), והשתמשו בטכניקה בסרטון, מתן זיהוי קצה בזמן אמת ושמר את התוצאות בקובץ וידאו.

הולך רחוק יותר - למידה עמוקה מעשית לראייה ממוחשבת

האופי הסקרן שלך גורם לך לרצות ללכת רחוק יותר? אנו ממליצים לבדוק את שלנו קורס: "למידה עמוקה מעשית עבור ראייה ממוחשבת עם Python".

OpenCV Edge Detection ב-Python עם cv2.Canny() PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

עוד קורס ראיית מחשב?

לא נעשה סיווג של ספרות MNIST או אופנת MNIST. הם שירתו את תפקידם מזמן. משאבי למידה רבים מדי מתמקדים במערך נתונים בסיסיים ובארכיטקטורות בסיסיות לפני שהם מאפשרים לארכיטקטורות מתקדמות של קופסאות שחורות לשאת בנטל הביצועים.

אנחנו רוצים להתמקד דה-מיסטיפיקציה, מעשיות, הבנה, אינטואיציה ו פרויקטים אמיתיים. רוצה ללמוד אֵיך אתה יכול לעשות שינוי? ניקח אותך לסיבוב מהאופן שבו המוח שלנו מעבד תמונות לכתיבת סיווג למידה עמוקה לסרטן השד בדרגת מחקר לרשתות למידה עמוקה ש"הזויה", מלמדת אותך את העקרונות והתיאוריה באמצעות עבודה מעשית, ומציידה אותך ב ידע וכלים כדי להפוך למומחה ביישום למידה עמוקה לפתרון ראייה ממוחשבת.

מה יש בפנים?

  • העקרונות הראשונים של חזון וכיצד ניתן ללמד מחשבים "לראות"
  • משימות ויישומים שונים של ראייה ממוחשבת
  • כלי המקצוע שיקלו עליכם את העבודה
  • מציאת, יצירה וניצול של מערכי נתונים עבור ראייה ממוחשבת
  • התיאוריה והיישום של רשתות עצביות קונבולוציונליות
  • טיפול בהסטת תחום, התרחשות משותפת והטיות אחרות במערך נתונים
  • העבר למידה וניצול זמן ההדרכה ומשאבי החישוב של אחרים לטובתך
  • בנייה והדרכה של סיווג סרטן שד חדיש
  • כיצד ליישם מנה בריאה של ספקנות על רעיונות מיינסטרים ולהבין את ההשלכות של טכניקות מאומצות באופן נרחב
  • הדמיית "מרחב הקונספט" של ConvNet באמצעות t-SNE ו-PCA
  • תיאורי מקרה של האופן שבו חברות משתמשות בטכניקות ראייה ממוחשבת כדי להשיג תוצאות טובות יותר
  • הערכת מודל נכונה, הדמיית מרחב סמוי וזיהוי תשומת הלב של המודל
  • ביצוע מחקר תחום, עיבוד מערכי נתונים משלך והקמת בדיקות מודל
  • ארכיטקטורות חדשניות, התקדמות רעיונות, מה מייחד אותם וכיצד ליישם אותם
  • KerasCV – ספריית WIP ליצירת צינורות ודגמים מתקדמים
  • כיצד לנתח ולקרוא מאמרים וליישם אותם בעצמך
  • בחירת דגמים בהתאם ליישום שלך
  • יצירת צינור למידת מכונה מקצה לקצה
  • נוף ואינטואיציה על זיהוי אובייקטים עם R-CNN מהירים יותר, RetinaNets, SSDs ו-YOLO
  • מופע ופילוח סמנטי
  • זיהוי אובייקטים בזמן אמת עם YOLOv5
  • הכשרת גלאי אובייקטים של YOLOv5
  • עבודה עם רובוטריקים באמצעות KerasNLP (ספריית WIP בעלת חוזק בתעשייה)
  • שילוב רובוטריקים עם ConvNets ליצירת כיתובים של תמונות
  • חלום עמוק
  • אופטימיזציה של מודל Deep Learning לראייה ממוחשבת

בול זמן:

עוד מ Stackabuse