נספח א'
מימוש אלגוריתמי השחזור
נספח א'
שחזור בסופר-רזולוציה
תוכן עניינים
1.כללי 1 .......................................................................................
.2מימוש אלגוריתם ה2 ..................................... (VERSION_1_2) SD-
.2.1
.2.2
.2.3
.2.4
תיאור השגרות2............................................................................................
החלפת מקומות בין טשטוש והזזה )4...........................................(VERSION_1_3
שימוש בהזזת NEAREST NEIGHBORבשחזור )5............................... (VERSION_1_4
חישוב מקדים של R0ו6....................................................... (VERSION_2_1) P-0
.3מימוש אלגוריתם 7 ........................................(VERSION_2_2) NSD
.4מימוש אלגוריתם רגולריזציה )7 ............................... (VERSION_2_3
.4.1
.4.2
קביעת רגולריזציה לא תלויית מקום אופטימלית )8...................... (VERSION_3_1
רגולריזציה תלויית מקום )9....................................................... (VERSION_3_2
.5בעיה ריבועית 10......................................... SQUARE_PROBLEM
.6אלגוריתם ה10...............................................(VERSION_CG) CG-
.7שערוך תנועה )10...................................... (MOTION_ESTIMATION
.8ניסוי מעשי )12.....................................................(EXPERIMENT
9.קטעי הקוד 13.............................................................................
13............................................................................................ VERSION_1_2 .9.1
17............................................................................................ VESRION_1_3 .9.2
18............................................................................................ VERSION_1_4 .9.3
20............................................................................................ VERSION_2_1 .9.4
21............................................................................................ VERSION_2_2 .9.5
22............................................................................................ VERSION_2_3 .9.6
23............................................................................................ VERSION_3_1 .9.7
26............................................................................................ VERSION_3_2 .9.8
27.............................................................................................VERSION_CG .9.9
29.....................................................................................SQUARE_PROBLEM .9.10
30................................................................................. MOTION_ESTIMATION .9.11
31......................................................................................... EXPERIMENT .9.12
א-b
שחזור בסופר-רזולוציה
.1
נספח א'
כללי
לאחר הצגת הפתרון לבעיית ה) SRR-אשר מומש במסגרת הפרוייקט( והסבר
קצר ועקרוני על מימושו ,נפרט עתה את כל קטעי הקוד והסברים מדויקים
על מנת לאפשר הבנה ברורה של כל תוכנית.
כפי שתואר בפרקים הקודמים ,תכנית המימוש של אלגוריתם השחזור
מורכבת משני חלקים עיקריים :מידול יצירת התמונות ,והשחזור עצמו.
קטע קוד הראשון מיועד ליצירת סידרת תמונות )מתמונת מקור באיכות
טובה וברזולוציה מוגדלת( והעברת כל הפרמטרים הדרושים לשחזור )נתוני
הזזת התמונות ,גודל תמונת היעד והתמונות עצמן( למעטפת החיצונית.
במהלך בדיקת מנגנון השחזור קטע קוד זה יכול להתבצע פעם אחת בלבד,
כאשר כל פעם שמנגנון השחזור מופעל -הוא מדלג על קטע יצירת התמונות
ומשתמש בתמונות הקיימות .כך נוצרת אפשרות להשוות בצורה ויזואלית
את תוצאות השחזור במימושים שונים .כמובן שבשימוש במנגנון השחזור
בפועל ,קטע הקוד הראשון לא יהיה קיים כלל והמנגנון יקבל סדרת תמונות
אמיתיות ולא כאלה שנוצרו באופן מלאכותי מתמונת מקור כלשהי.
בנוסף לשני קטעי קוד הנ"ל ,הממומשים בשגרות נפרדות ,נעשה שימוש
במספר שגרות נוספות ,הרי שכל אופרטור המתואר ע"י כפל במטריצה
בתיאור מתמטי של השחזור ממומש כשגרה נפרדת אשר מקבלת את
האופרנד שלה כפרמטר ומחזירה את תוצאת הפעולה.
כל שינוי במנגנון השחזור ,החל מהמימוש הפשוט של אלגוריתם ה,SD-
נשמר בגרסה נפרדת של תכנית השחזור ,תחת שם מתאים .להלן רשימה
מפורטת של כל השגרות בכל אחת מגרסאות התכנית ,קטעי הקוד המלאים
והסברים לרעיונות עיקריים של מימושים שונים.
א-1
שחזור בסופר-רזולוציה
.2
נספח א'
מימוש אלגוריתם ה(version_1_2) SD -
הגרסה version_1_2מהווה מימוש פשוט ומדויק של אלגוריתם ה,SD-
ונוצרה כדי לאמת את ערכו המעשי של הפיתוח התיאורטי .רק לאחר קבלת
תוצאות אמינות מאלגוריתם ה SD-אפשר לדון בשיפורים אפשריים למנגנון
השחזור.
רשימת השגרות וקטעי קוד:
main
create_data
restore
blur
sample
warp
interpolate
initial_interpolate
.2.1
תיאור השגרות
.I
main
קטע קוד המהווה מעטפת חיצונית ,אשר קורא לשגרות העיקריות.
לאחר תהליך יצירת התמונות )קריאה לשגרה (create_dataוקליטת כל
הפרמטרים הדרושים לשחזור ,מתבצע תהליך שחזור ,באופן איטרטיבי
אשר מומש בלולאה ,כאשר כל איטרציה ממודלת ע"י קריאה לשגרת
.restoreתמונת ההתחלה של התהליך האיטרטיבי נוצרת ע"י שגרת
,initial_interpolateמתוך אחת התמונות "הדגומות".
:create_data .IIשגרת יצור התמונות
מקבלת כפרמטרים או קולטת מהמשתמש נתוני יצירת התמונות ,כגון
גרעין הטשטוש ,יחס דילול ,גודל התמונות הנוצרות ,תמונת היעד ועוד.
השגרה מחזירה את גודל תמונת היעד )תמונת ה .(SRR-בנוסף שומרת
השגרה כל תמונה שנוצרה בקובץ נפרד ,יחד עם נתוני ההזזה של אותה
תמונה .השגרה מציגה על המסך את התמונה המקורית ומאפשרת
לבחור על פניה אזור המיועד ליצירת סידרת התמונות.
השגרה מבצעת פעולות הממדלות את מגבלות הצילום :הזזה ,טשטוש,
דילול והוספת רעש .פרמטרי הזזת התמונות נבחרים באופן אקראי
א-2
נספח א'
שחזור בסופר-רזולוציה
כאשר טווח הזזה מרבי נקבע ע"י המשתמש .עבור כל תמונה שנוצרת,
תמונת המקור מוזזת כל פעם מחדש לכיוון הנבחר.
פעולת הטשטוש ,כפי שהוסבר בפרקים קודמים ,ממומשת ע"י
קונבולוציה ומהווה לפיכך פעולה יקרה מבחינת זמן ריצה .לכן ,על מנת
לחסוך בזמני ריצה ,לא מטשטשים את כל תמונת המקור )שרק חלק
ממנה ישמש ליצירת תמונה( אלא קודם חותכים מתמונת המקור את
האזור הרצוי עם מספר שורות ועמודות יתרות מכל צד )כדי להבטיח
טשטוש נכון( ,מטשטשים ורק אח"כ חותכים את השורות והעמודות
היתרות .הרעש שנוסף לכל תמונה הוא רעש אקראי גאוסי ונורמלי ,ללא
כל קורלציה .כל תמונה שנוצרת ,כאמור ,נשמרת בקובץ נפרד יחד עם
נתוני ההזזה שלה.
:restore .IIIשגרה המבצעת איטרציה בודדת
מקבלת כפרמטרים תמונת כניסה )תוצאה של איטרציה קודמת(
ונתונים הדרושים לשחזור .השגרה מהווה מימוש מדויק של אלגוריתם
ה ,SD-אשר מוסבר בסעיף 4.2בדו"ח ומתואר סכימתית בציור .9
במהלך האיטרציה ,השגרה טוענת את התמונות Ykמקבצי *.mat
שנשמרו במהלך ביצוע שגרת .create_dataהשגרה מחזירה את התמונה
החדשה – תוצאת האיטרציה.
:blur .IVשגרת טשטוש
כאמור ,פעולת הטשטוש ממומשת ע"י קונבולוציה של התמונה עם גרעין
הטשטוש; שניהם נכנסים לשגרה כפרמטרים .תוצאת הפעולה מעוגלת
כדי לקבל רמות אפור שלמות בטווח ]. [0..255
:sample .Vשגרת דילול
מקבלת את תמונת הכניסה ויחס הדילול כפרמטרים .מבצעת בחירה
מחזורית של פיקסלים מתמונת הכניסה ,לפי יחס הדילול בכל ציר.
מחזירה את התמונה המדוללת.
א-3
נספח א'
שחזור בסופר-רזולוציה
:interpolate .VIשגרת אינטרפולציה
כפי שהוסבר בפיתות אלגוריתם ה ,SD-אינטרפולציה מייצגת את הכפל
במטריצה (Dk)Tומהווה פעולה הפוכה לדילול .מבחינה מתמטית,
המשמעות היא הרחבה מחזורית של התמונה לממדיה לפני הדילול ,תוך
מילוי הפיקסלים המתפנים ברמת אפור ,0כלומר צבע שחור.
:warp .VIIשגרת הזזה
לפי אחת ההנחות העיקריות ,התכנית צריכה לתמוך בהזזה בחלקי
פיקסל ,בנוסף להזזה רגילה במספר שלם של פיקסלים .השגרה מממשת
את שתי ההזזות ,כאשר תחילה מתבצעת הזזה בחלק שלם של שיעור
ההזזה בכל כיוון .ההזזה בחלקי פיקסל ממודלת בשיטת ההתמרה
הבילינארית .כאמור ,השיטה מסתכמת בחישוב ממוצע משוקלל של
ערכי ארבע פיקסלים סמוכים עבור כל פיקסל בתמונה המוזזת .כדי
ליעל את הפעולה ,ההתמרה הבילינארית מחושבת על כל התמונה ולא
עבור כל פיקסל בנפרד.
תמונת הכניסה מוזזת לכל הכיוונים בפיקסל אחד ונשמרת במטריצות
שונות .התמונה המוזזת בחלקי פיקסל (כלומר ,תוצאת ההזזה) היא
תוצאה של ממוצע משוקלל )לפי שיעור ההזזה( של 4המטריצות הנ"ל,
המייצגות ,כאמור ,הזזות בפיקסל אחד של תמונת הכניסה.
initial_interpolate .VIII
שגרה המיועדת ליצירת תמונת התחלה X0לתהליך האיטרטיבי.
המטרה היא ליצור תמונה בגודל של תמונת היעד )תמונת ה,(SRR-
הקרובה ככל האפשר לתמונת המקור .השגרה מבצעת את פעולת
האינטרפולציה הרגילה ,כאשר במקום הכנסת אפסים משוכפל כל
פיקסל מספר פעמים דרוש כדי למלא את הפיקסלים המתפנים.
.2.2
החלפת מקומות בין טשטוש והזזה )(version_1_3
הגרסה version_1_3נועדה לאמת את הטענה התיאורטית הקובעת כי
החלפת סדר הפעולות טשטוש והזזה לא גורמת כל נזק לתמונת התוצאה,
ולמעשה לא מביאה כלל לשינוי מבחינת איכות התוצאה ,וזאת על מנת
לאפשר שיפור בזמן ריצה של האלגוריתם .השינוי היחיד ביחס לגרסה
א-4
נספח א'
שחזור בסופר-רזולוציה
version_1_2הנו בשגרת ,restoreבה בוצע החלפת סדר פעולות ההזזה
והטשטוש בלולאת הסיכום של התמונות "הדגומות" בכל איטרצית השחזור,
וכך הוצאת פעולת הטשטוש מחוץ ללולאה )כיוון שפעולת הטשטוש
מתבצעת עם אותו גרעין טשטוש ולכן זהה לכל התמונות "הדגומות"( .
רשימת השגרות וקטעי קוד:
main
create_data
restore
blur
sample
warp
interpolate
initial_interpolate
השגרות הנן כפי המתואר בסעיף ,2.1להוציא שגרת השינוי בשגרת restore
כאמור לעיל.
.2.3
שימוש בהזזת Nearest Neighborבשחזור )(version_1_4
הגרסה version_1_4נועדה לבדוק את ההשפעה של שימוש בשיטת ההזזה
Nearest Neighborבתהליך השחזור במקום ההזזה הבילינארית .כפי שמוסבר
בסעיף 4.3בדו"ח ,שימוש בהזזת Nearest Neighborמאפשר את המשך
הפיתוח של אלגוריתם השחזור אך פוגע באיכות השחזור ,כיוון שמהווה
קירוב להזזה בחלקי הפיקסל )ההזזה הבילינארית מהווה מידול מדויק
להזזה בחלקי הפיקסל( .כמובן שאפשר להמשיך בפיתוח האלגוריתם רק
במידה והנזק הנגרם ע"י Nearest Neighborהוא מזערי וניתן להזנחה.
רשימת השגרות וקטעי קוד:
main
create_data
restore
blur
sample
warp
warp_nn
interpolate
initial_interpolate
א-5
נספח א'
שחזור בסופר-רזולוציה
כאמור ,השינוי היחיד ביחס לגרסה הקודמת הוא שימוש בהזזת Nearest
Neighborבמקום ההזזה הרגילה בשגרת .restoreלעומת זאת ,בשגרת
create_dataנעשה השימוש בהזזה רגילה ,כיוון שמידול תהליך יצירת
התמונות נשאר ללא שינוי ולא מושפע משנויים בשיטת השחזור.
.2.4
חישוב מקדים של R0ו(version_2_1) P0-
בגרסא version_2_1מיושמת השיטה הבאה :המטריצות R0ו P0-מחושבות
פעם אחת בלבד במהלך תהליך השחזור ,מחוץ ללולאת האיטרציה )כמתואר
בפרקים קודמים( .המטריצות מחושבות על ידי שגרת ,maskעל פי נוסחאות
מתאימות .לאחר היישום הנ"ל התקבל מימוש מאוד פשוט של איטרציה,
וניתן היה לוותר על שגרת .restore
רשימת השגרות וקטעי קוד:
main
create_data
mask
blur
sample
warp
warp_nn
interpolate
initial_interpolate
בשגרת maskמבוצע חישוב המטריצות P0ו R0-על פי הנוסחאות שהוצגו
בפרקים קודמים .המטריצות R0ו P0-הן מטריצות קבועות הניתנות לחישוב
מקדים .המטריצה R0חושבה בצורת ,maskכיוון שלא ניתן לממש את
הפעולה )המיוצגת ע"י (R0על ידי כפל מטריצי רגיל .המטריצה R0נבנתה
באופן הבא :כל הפעולות )אשר מופעלות במקור על התמונה ,(Xמופעלות על
מטריצת אחדים onesבגודל התמונה ,Xולאחר מכן מוכפלת המטריצה R0
בתמונת Xאיבר-איבר.
כאמור ,החל מהגרסה הזאת ,אין יותר שימוש בשגרת restoreומימוש
האיטרציה נעשה בתוך שגרת .main
א-6
שחזור בסופר-רזולוציה
.3
נספח א'
מימוש אלגוריתם (version_2_2) NSD
בגרסה version_2_2נעשה לראשונה שימוש באלגוריתם ה .NSD-פרמטר
ההתכנסות μלא נקלט עתה מהמשתמש ,אלא מחושב באופן דינאמי בכל
איטרציה )לפי נוסחת ה ,NSD-המתוארת בפרק 4.4בדו"ח( ,ע"י השגרה .nsd
רשימת השגרות וקטעי קוד:
main
create_data
mask
nsd
blur
sample
warp
warp_nn
interpolate
initial_interpolate
שגרת nsdמהווה מימוש מדוייק של נוסחת אלגוריתם ה.NSD-
.4
מימוש אלגוריתם רגולריזציה )(version_2_3
בגרסה version_2_3מיושם השימוש ברגולריזציה לא תלויית מקום,
האמורה לתת פתרון לבעית ה .ringing-תאור מפורט של הרגולריזציה הוצג
בפרק .5על מנת לממש את הרגולריזציה ,אנו זקוקים לחישוב נגזרת של
התמונה ,כדי לבטא את איבר החלקות .החישוב נעשה ע"י שמוש בשגרת blur
שהופעלה על התמונה עם גרעין ה .laplasian-ביצוע הנגזרת מומש למעשה ע"י
טשטוש עם גרעין הגזירה .הוספת איבר החלקות מכניסה שינויים בחישוב
מקדם הטיב ,נוסחת האיטרציה ונוסחת ה.NSD-
רשימת השגרות וקטעי קוד:
main
create_data
mask
new_nsd
blur
sample
warp
א-7
שחזור בסופר-רזולוציה
warp_nn
interpolate
initial_interpolate
נספח א'
השגרה new_nsdמחליפה את השגרה nsdמהגרסה הקודמת כאשר השינוי
הוא ,כאמור ,הוספת איבר החלקות.
.4.1
קביעת רגולריזציה לא תלויית מקום אופטימלית )(version_3_1
הגרסה version_3_1נוצרה על מנת לבחור את פרמטר ההחלקה האופטימלי
.λלשם כך מעל למימוש הקודם נבנתה לולאה חיצונית ,בה נקבע כל פעם
מחדש ערך .λבתום ביצוע תהליך השחזור במלואו וקבלת תמונה סופית,
עבור כל ערך של ,λנערכת השוואה של התוצאה לתמונת המקור ,כלומר
מחושב ריבוע הנורמה של ההפרש בין התמונה המקורית לבין תמונת
התוצאה .ככל שהמספר הזה נמוך יותר ,כך התמונה שהתקבלה קרובה יותר
לתמונת המקור .ערך של λעבורו תמונת התוצאה קרובה ביותר לתמונת
המקור נחשב לאופטימלי.
רשימת השגרות וקטעי קוד:
graph
main
create_data
mask
new_nsd
blur
sample
warp
warp_nn
interpolate
initial_interpolate
המעטפת החיצונית הוא קטע קוד .graphקטע קוד ,mainאשר מייצג את
תהליך השחזור עצמו ,מומש כשגרה המקבלת כפרמטרים מהמעטפת
החיצונית את פרמטר הרגולריזציה λואת מספר האיטרציות בכל איטרציה.
א-8
שחזור בסופר-רזולוציה
.4.2
נספח א'
רגולריזציה תלויית מקום )(version_3_2
בגרסה version_3_2נעשה שימוש ברגולריזציה תלויית מקום ,על פי העקרון
המוצג בפרק .5השינוי הוא ,הכפלת איבר החלקות במטריצה .Wפעולה זו
גורמת לשינויים בחישוב מקדם הטיב ,εנוסחת האיטרציה ונוסחת ה.NSD-
רשימת השגרות וקטעי קוד:
main
create_data
mask
wls_mask
w_nsd
blur
sample
warp
warp_nn
interpolate
initial_interpolate
המטריצה Wמחושבת בשגרה .wls_maskהשגרה מקבלת כפרמטר את
התמונה )לאחר טשטוש מקדים או בלעדיו( ממנה רוצים ליצור את מפת
השפות ,Wופרמטרים נוספים לבניית פונקצית הסף .השגרה מכילה קוד
לבניית שלוש פונקציות סף שונות :מדרגה ,פונקציה לינארית ופונקציה
ריבועית )ראה הסבר בפרק .(5
מכיוון שמכפלה במטריצה Wנכנסת לחישוב נוסחת ה ,NSD-השגרה
המתאימה הוחלפה בשגרה w_nsdאשר מקבלת את המטריצה Wכפרמטר
לחישוב נוסחת ה NSD-החדשה.
א-9
שחזור בסופר-רזולוציה
.5
נספח א'
בעיה ריבועית
Square_Problem
קטע קוד זה מממש בעיה ריבועית קטנה ופשוטה ,ומחשב את פתרונה
האנליטי על ידי הפיכת המטריצה המתאימה .התכנית מריצה את שני
האלגוריתמים NSD ,ו ,CG-כפי שהם מתוארים בפרק ,3ומייצרת תצוגה
גרפית של פרמטרים הבאים :פרמטר טיב התוצאה הרגיל ε2והנורמה אשר
מתקבלת מהשוואה של תוצאת הריצה עם הפתרון האנליטי.
.6
אלגוריתם ה(version_CG) CG-
קטעי קוד הבאים מהווים מימוש של אלגוריתם ה ,CG-כפי שהוא מוסבר
בפרק ,3כפתרון איטרטיבי לבעיית הסופרזולוציה ,בדומה לפתרונות
המבוססים על אלגוריתמי SDו .NSD-מנגנון שחזור המבוסס CGמורכב
במקרה משגרות Matlabהבאות :
Main
Create_data
Sample
Interpolate
Blur
Mask
Initial_interpolate
Warp
CG
שגרת mainמהווה מעטפת בסיסית למנגנון השחזור .בלולאת האיטרציות
סדר השמת הערכים במשתנים נשמר על פי סדר הפעולות באלגוריתם ה.CG-
שגרת CGמממשת במדויק את חישוב הנוסחה של מקדם בהתכנסות μ
באלגוריתם ה.CG-
.7
שערוך תנועה )(Motion_Estimation
קטעי הקוד הבאים מהווים מימוש מעשי של מנגנון שערוך התנועה ,שהוא
חיוני ביותר להצלחת הפרויקט כולו .מימוש שערוך התנועה חייב להיות נוח
להפעלה )כדי לאפשר את שילובו בתוך מנגנון השחזור( ,אך יחד עם זאת
לתת תוצאה מדויקת ביותר כדי להבטיח שחזור איכותי וקבלת תמונת
הסופר-רזולוציה -מדובר ,כאמור ,בדיוק של חלקי פיקסלים .יש לציין
א-10
נספח א'
שחזור בסופר-רזולוציה
שהמנגנון הוא איטרטיבי ,ועובדה זו מכתיבה את המבנה של קטעי הקוד
המוצעים.
מימוש מנגנון השחזור מורכב משגרות Matlabהבאות :
Lme
Estimate
הסבר מפורט של קטעי הקוד:
שגרת Estimateמממשת את הרמה הבסיסית של תהליך שערוך התנועה על
פי המתואר בחלק התיאורטי .השגרה מקבלת ככניסה שתי תמונות ומוציאה
כפלט את שעורי התזוזה היחסית ביניהן בשני הצירים .כמו כן מקבלת
השגרה מהמעטפת החיצונית את גרעין הטשטוש הגאוסיאני לצורך טשטוש
מקדים של התמונות .במהלך הריצה מבצעת השגרה גזירה של אחת
התמונות בעזרת גרעיני גזירה .כתוצאה מכך נהרסות שפות התמונה לעומק
התלוי בגודל של גרעין הגזירה .כדי לא לקחת בחשבון את האזורים
המקולקלים במהלך השערוך ,מבצעת השגרה חיתוך של אזורים אלו
מהתמונות.
השגרה מהווה למעשה איטרציה בודדת בתהליך שערוך התנועה
האיטרטיבי.
שגרת Lmeמהווה רמה עליונה של מנגנון שערוך התנועה ,כאשר היא
קוראת לשגרה Estimateבכל פעם שיש צורך לבצע איטרציה נוספת של
המנגנון .התהליך האיטרטיבי נמשך כל עוד התוצאה לא מגיעה לרמת הדיוק
הנדרשת.
לאחר ביצוע כל איטרציה מקבלת השגרה תוצאת ביניים – שיעורי התזוזה
היחסית בין שתי התמונות .לצורך ביצוע האיטרציה הבאה מזיזה השגרה
את אחת התמונות באותם שיעורי התזוזה )בכיוון ההפוך כמובן( כדי
לאפשר את הכנסת שתי התמונות שוב כפרמטרים לשגרת .Estimate
כתוצאה מהזזה הנ"ל מתקלקלות הקצוות של התמונה המוזזת .עקב כך
חותכת השגרה את הקצוות המתאימות בשתי התמונות לפני הכנסתן לשגרת
,Estimateכדי לא לקחת בחשבון את הקצוות המקולקלים במהלך
החישובים.
א-11
שחזור בסופר-רזולוציה
.8
נספח א'
ניסוי מעשי )(Experiment
קטעי קוד הבאים מממשים את בעיית סופר-רזולוציה מעשית ומיישמים
אלגוריתם איטרטיבי מבוסס גרדיאנט כפתרון.תכניות Matlabהבאות
מאפשרות :
טעינת התמונות המצולמות )בפורמט (bmp
בחירת אזור רצוי בתמונה
שמירת התמונות כמטריצות Matlab
הצגת תמונות ההפרש לבחירת התמונות הטובות
הרצת התמונות הנבחרות במנגנון השחזור
מנגנון השחזור הנוכחי מכיל את כל אותן השגרות אשר נעשה בהן שימוש
באלגוריתם ה ,NSD-בתוספת שתי שגרות חדשות prepare ,ו.show_diffs-
כאמור ,האלגוריתם הנוכחי מבצע הפרדה של תמונות לשורות זוגיות ואי
זוגיות ,ולכן השגרות המתאימות שונו בקצת על מנת שתוכלנה לטפל
בתמונות שלא ריבועיות.
שגרת prepareמבצעת טעינת התמונות המצולמות )בפורמט ,(bmpושמירתן
כמטריצות Matlabתוך חיתוך איזור מסויים בתמונה בגודל ].[200x200
שגרת show_diffsטוענת את התמונות שנשמרו על ידי שגרת ,prepareמבצעת
לכל אחת מהן שערוך תנועה יחסית לתמונה הראשונה ,ומציגה על המסך
את תמונות ההפרש ,על מנת לאפשר בחירת תמונות בעלות תמונת הפרש
אופטימלית מבחינה הויזואלית.
שגרת mainבגרסה הנוכחית מכילה השגרה גם את קטע המבצע חלוקה של
תמונות לשורות זוגיות ואי זוגיות ,ביצוע שערוך התנועה ושמירת התמונות
יחד עם פרמטרי ההזזה .בתחילת הביצוע משתמשת השגרה בחלק
מהתמונות אשר נשמרו על ידי שגרת .prepare
א-12
'נספח א
רזולוציה-שחזור בסופר
קטעי הקוד
.9
כל חלק, כפי שהוסבר.Matlab אלגוריתם השחזור מומש כולו בתכנת
אשר נעשה, משום כך קטעי קוד של שגרות.בפרויקט מומש בורסיה שונה
. יופיעו פעם אחת בלבד,בהן שימוש ביותר מורסיה אחת
version_1_2
main שגרת
.I
% MAIN
% ====
% Load original picture :
load text;
% Bluring KERNEL :
kernel=ones(3)./9;
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA )
N=input(' => Enter number of images :');
ratio=input(' => Enter sampling ratio :');
ImSize=create_data(A,N,kernel,ratio);
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial guess of SuperResolution image
load Y1
X0=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
K=input(' => Enter number of iterations :');
Mu=input(' => Enter initial Mu :');
EPS = [];
count=[];
% Performong the iteration(s) :
for j=1:K
[X0,eps]=restore(N,kernel,ratio,Mu,X0);
% X0 must be DOUBLE !!!!
fprintf('***> iteration No. %d . Eps = %d\n',j,eps);
EPS=[EPS,eps];
count=[count,j];
end
figure;
plot(count,EPS);
xlabel('Iterations');
ylabel('Epsilon^2');
%figure;
% Show the LAST image - the result
%imshow(X0,[0,255]);
create_data שגרת.II
function [ImSize] = create_data(INPUT,N,kernel,ratio);
% Receives UINT8 image , converts to DOUBLE :
IN=double(INPUT);
% Function : created warped , blured , sub-sampled and noisy images from a given image.
% Receives the next parameters :
% original image , number of processed images , blur kernel , sample ratio .
% Receives interactive inputs :
% Pinch point coordinates , maximal warping interval , target image size .
-13א
.9.1
'נספח א
רזולוציה-שחזור בסופר
% Returns : the target (SuperResolution) image size .
% Saves in separated *.mat files (Y1.mat , Y2.mat , .... ) :
% - the output images for each loop ( TEMP )
% - warping coefficients for each loop ( a , b )
% Original image size
[maxY,maxX]=size(IN);
% Receive Inputs from the user
imshow(IN,[0,255]);
fprintf(' => Click a pinch point\n\n');
[x,y]=ginput(1);
x=round(x); y=round(y);
Ysize = min(maxY-y,y); Xsize = min(maxX-x,x);
Delta = input(' => Enter maximal warping interval (pixels) [1..3] : ');
fprintf('\n => Enter Target image size [50..%d] : ',2*min(Xsize,Ysize));
ImSize = input('');
% Check if input is valid
while(ImSize>2*min(Xsize,Ysize))
fprintf(' => ERROR !!! Index exceeds matrix dimentions\n');
fprintf('\n => Enter Target image size [50..%d] : ',2*min(Xsize,Ysize));
ImSize = input('');
end
% Perform processing
for i=1:N
% The first processed image is not warped !!
if i==1
a=0; b=0;
else
a=Delta*(2*rand-1); b=Delta*(2*rand-1);
end
% Warp :
TEMP=warp(IN,a,b);
% Cut the target block with spare rows and columns for proper bluring :
spare=length(kernel);
if (mod(ImSize,2)==0)
TEMP=TEMP(y-floor(ImSize/2)+1-spare:y+floor(ImSize/2)+spare , x-floor(ImSize/2)+1spare:x+floor(ImSize/2)+spare);
else
TEMP=TEMP(y-(ImSize-1)/2-spare:y+(ImSize-1)/2+spare , x-(ImSize-1)/2-spare:x+(ImSize-1)/2+spare);
end
% Blur :
TEMP = blur(TEMP,kernel);
%Cut the spare rows and columns :
TEMP=TEMP(spare+1:end-spare ,spare+1:end-spare );
% Sample :
TEMP = sample(TEMP,ratio);
% Noise addition :
TEMP=TEMP+randn(size(TEMP)) ;
% Final result assignment :
str1='save Y';
str2='.mat TEMP a b';
eval([str1,num2str(i),str2]);
figure;
imshow(TEMP,[0,255]);
fprintf(' => Saving %d image to Y%d.mat\n',i,i);
end
return ;
-14א
'נספח א
רזולוציה-שחזור בסופר
restore שגרת.III
function [Xkk,epsilon2] = restore(N,kernel,ratio,Mu,Xk)
% Receives DOUBLE matrix (Xk) , returns DOUBLE matrix (Xkk)
% Function - one iteration of restoration process
% Receives as parameters :
% - number of images ;
% - blur kernel ;
% - input image ;
% - parametr Mu ;
% - sampling/interpolation ratio ;
% Returns :
% - the result image ;
% - square epsilon ;
% Assumes that files names are the same as in 'create_data' ( Y1.mat , Y2.mat .... )
% Load next file
|
% Warp the input image according to file's warping coefficients
|=> in the same loop .
Xkk = zeros(size(Xk)) ;
% preparing the result image
epsilon2=0;
for i=1:N
eval(['load Y',num2str(i),'.mat']); % Now we have variables : TEMP , a , b .
X=Xk;
X=warp(X,a,b);
% Warp
X=blur(X,kernel);
% Blur
X=sample(X,ratio);
% Sample
X=X-double(TEMP);
% Subtraction of Yk
% Up to this point : X contains the error ( Yk - D*H*Fk*Xk )
% Calculating the NORMA ( epsilon^2 ) :
epsilon2 = epsilon2 + sum(sum( double(X).^2 )) ;
% Square of each pixel
X=interpolate(X,ratio,size(Xk)); % Interpolation - inserting zeros
X=blur(X,kernel);
% Blur
X=warp(X,-a,-b);
% Inverse warping
Xkk = Xkk + X ;
% Add next image to the sum
end
Xkk = Mu.*Xkk;
Xkk = Xk - Xkk ;
% The final assignment of the result
epsilon2=epsilon2/N;
figure; imshow(Xkk,[0,255]);
% Show the result of CURRENT iteration
return;
blur שגרת.IV
function out = blur(A,kernel)
% Receives DOUBLE matrix
out = round( conv2(A,kernel, 'same' ) );
return ;
sample שגרת.V
function out = sample(A,ratio)
out = A(1:ratio:end,1:ratio:end);
return ;
-15א
'נספח א
רזולוציה-שחזור בסופר
interpolate שגרת.VI
function out=interpolate(A,ratio,OriginalSize)
% Receives parameters :
% - the input image (sampled)
% - sampling ratio
% - size of the original image (before sampling)
[a,b]=size(A);
out=zeros(a*ratio,b*ratio);
out(1:ratio:end,1:ratio:end) = A;
out=out( 1:OriginalSize(1) , 1:OriginalSize(2) );
return ;
warp שגרת
.VII
function [out]=warp(A,DeltaY,DeltaX)
% Reeives DOUBLE matrix
% Parameter image size :
[a,b]=size(A);
% Check of warping coefficients values :
% ---------------------------------------% Cases :
% - Positive/Negative
% - Integer/Fraction
% Splitting warping coefficients to integer and fractional values :
% --------------------------------------------------------------XX=floor(DeltaX); YY=floor(DeltaY);
% actual pre-warp coefficients
X=abs(XX);Y=abs(YY);
alpha=DeltaX-XX; beta=DeltaY-YY;
% Bi-Linear coefficients - ALWAYS POSITIVE
% Pre-Warping - integer values :
% ---------------------------if ( ( sign(XX)>=0 ) & ( sign(YY)>=0 ) )
% warp right-down
out=[zeros(Y,b) ; zeros(a-Y,X) , A(1:a-Y,1:b-X) ];
elseif ( ( sign(XX)<=0 ) & ( sign(YY)<=0 ) )
% warp left-up
out=[A(Y+1:a,X+1:b) , zeros(a-Y,X) ; zeros(Y,b)];
elseif ( ( sign(XX)==-1 ) & ( sign(YY)==1 ) )
% warp left-down
out=[zeros(Y,b) ; A(1:a-Y,X+1:b) , zeros(a-Y,X)];
elseif ( ( sign(XX)==1 ) & ( sign(YY)==-1 ) )
% warp right-up
out=[zeros(a-Y,X) , A(Y+1:a,1:b-X) ; zeros(Y,b) ];
end
% End of Pre-warping
% Bi-Linear Warping - fractional values :
% ------------------------------------A1=out;
A2=[ zeros(a,1) , out(1:a,1:b-1) ];
A3=[zeros(1,b) ; out(1:a-1,1:b) ];
A4=[zeros(1,b) ; zeros(a-1,1) , out(1:a-1,1:b-1) ];
out = round( ((1-alpha)*(1-beta)*A1 + alpha*(1-beta)*A2 + (1-alpha)*beta*A3 + alpha*beta*A4) );
clear A1;
clear A2;
clear A3;
clear A4;
% --------------% End of Function
return ;
% ---------------
-16א
'נספח א
רזולוציה-שחזור בסופר
initial_interpolate שגרת.VIII
function out=initial_interpolate(A,ratio,OriginalSize)
% INTERPOLATION WHICH COPIES EACH PIXEL AND DOESN'T INSERT ZEROS !!!!
% Receives parameters :
====================
% - the input image (sampled)
% - sampling ratio
% - size of the original image (before sampling)
[a,b]=size(A);
out=zeros(a*ratio,b*ratio);
% Option 1:
% out=kron(A,ones(ratio,ratio));
% Option 2:
for i=0:ratio-1
for j=0:ratio-1
out(1+i:ratio:end,1+j:ratio:end) = A;
end
end
out=out( 1:OriginalSize(1) , 1:OriginalSize(2) );
return ;
vesrion_1_3
main שגרת
.I
% MAIN
% ====
% Load original picture :
load text;
kernel=ones(3)./9;
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA )
N=input(' => Enter number of images :');
ratio=input(' => Enter sampling ratio :');
ImSize=create_data(A,N,kernel,ratio);
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial guess of SuperResolution image
load Y1
X0=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
K=input(' => Enter number of iterations :');
Mu=input(' => Enter initial Mu :');
EPS = [];
count=[];
% Performong the iteration(s) :
for j=1:K
[X0,eps]=restore(N,kernel,ratio,Mu,X0);
% X0 must be DOUBLE !!!!
fprintf('***> iteration No. %d . Eps = %d\n',j,eps);
EPS=[EPS,eps];
count=[count,j];
end
figure;
plot(count,EPS);
xlabel('Iterations');
ylabel('Epsilon^2');
%figure;
% Show the LAST image - the RESULT
%imshow(X0,[0,255]);
-17א
.9.2
'נספח א
רזולוציה-שחזור בסופר
restore שגרת.II
function [Xkk,epsilon2] = restore(N,kernel,ratio,Mu,Xk)
% Receives DOUBLE matrix (Xk) , returns DOUBLE matrix (Xkk)
% Function - one iteration of restoration process
% Receives as parameters :
% - number of images ;
% - blur kernel;
% - input image ;
% - parametr Mu ;
% - sampling/interpolation ratio ;
% Returns :
% - the result image ;
% - square epsilon ;
% Assumes that files names are the same as in 'create_data' ( Y1.mat , Y2.mat .... )
% Load next file
|
% Warp the input image according to file's warping coefficients
|=> in the same loop .
Xkk = zeros(size(Xk)) ;
% preparing the result image
epsilon2=0;
Xkblured=blur(Xk,kernel);
for i=1:N
eval(['load Y',num2str(i),'.mat']); % Now we have variables : TEMP , a , b .
X=Xkblured;
X=warp(X,a,b);
% Warp
X=sample(X,ratio);
% Sample
X=X-double(TEMP);
% Subtraction of Yk
% Up to this point : X contains the error ( Yk - D*Fk*H*Xk )
% Calculating the NORMA ( epsilon^2 ) :
epsilon2 = epsilon2 + sum(sum( double(X).^2 )) ;
% Square of each pixel
X=interpolate(X,ratio,size(Xk)); % Interpolation - inserting zeros
X=warp(X,-a,-b);
% Inverse warping
Xkk = Xkk + X ;
% Add next image to the sum
end
Xkk = blur(Xkk,kernel);
Xkk = Mu.*Xkk;
Xkk = Xk - Xkk ;
% The final assignment of the result
epsilon2=epsilon2/N;
figure; imshow(Xkk,[0,255]);
% Show the result of current iteration
return;
version_1_4
warp_nn שגרת
function [out]=warp_nn(A,DeltaY,DeltaX)
% Reeives DOUBLE matrix
% Parameter image size :
[a,b]=size(A);
% Nearest Neighbor Warp :
% --------------------------------------------------------------XX=round(DeltaX);
YY=round(DeltaY);
% actual pre-warp coefficients
X=abs(XX);
Y=abs(YY);
% Warping - integer values :
% ----------------------------
-18א
.I
.9.3
'נספח א
רזולוציה-שחזור בסופר
if ( ( sign(XX)>=0 ) & ( sign(YY)>=0 ) )
% warp right-down
out=[zeros(Y,b) ; zeros(a-Y,X) , A(1:a-Y,1:b-X) ];
elseif ( ( sign(XX)<=0 ) & ( sign(YY)<=0 ) )
% warp left-up
out=[A(Y+1:a,X+1:b) , zeros(a-Y,X) ; zeros(Y,b)];
elseif ( ( sign(XX)==-1 ) & ( sign(YY)==1 ) )
% warp left-down
out=[zeros(Y,b) ; A(1:a-Y,X+1:b) , zeros(a-Y,X)];
elseif ( ( sign(XX)==1 ) & ( sign(YY)==-1 ) )
% warp right-up
out=[zeros(a-Y,X) , A(Y+1:a,1:b-X) ; zeros(Y,b) ];
end
% End of Pre-warping
% --------------% End of Function
return ;
% ---------------
restore שגרת.II
function [Xkk,epsilon2] = restore(N,kernel,ratio,Mu,Xk)
% Receives DOUBLE matrix (Xk) , returns DOUBLE matrix (Xkk)
% Function - one iteration of restoration process
% Receives as parameters :
% - number of images ;
% - blur kernel;
% - input image ;
% - parametr Mu ;
% - sampling/interpolation ratio ;
% Returns :
% - the result image ;
% - square epsilon ;
% Assumes that files names are the same as in 'create_data' ( Y1.mat , Y2.mat .... )
% Load next file
|
% Warp the input image according to file's warping coefficients
|=> in the same loop .
Xkk = zeros(size(Xk)) ;
% preparing the result image
epsilon2=0;
Xkblured=blur(Xk,kernel);
for i=1:N
eval(['load Y',num2str(i),'.mat']); % Now we have variables : TEMP , a , b .
X=Xkblured;
X=warp_nn(X,a,b);
% Warp
X=sample(X,ratio);
% Sample
X=X-double(TEMP);
% Subtraction of Yk
% Up to this point : X contains the error ( Yk - D*Fk*H*Xk )
% Calculating the NORMA ( epsilon^2 ) :
epsilon2 = epsilon2 + sum(sum( double(X).^2 )) ;
% Square of each pixel
X=interpolate(X,ratio,size(Xk));
% Interpolation - inserting zeros
X=warp_nn(X,-a,-b);
% Inverse warping
Xkk = Xkk + X ;
% Add next image to the sum
end
Xkk = blur(Xkk,kernel);
Xkk = Mu.*Xkk;
Xkk = Xk - Xkk ;
% The final assignment of the result
epsilon2=epsilon2/N;
figure; imshow(Xkk,[0,255]);
% Show the result of current iteration
return;
-19א
'נספח א
רזולוציה-שחזור בסופר
version_2_1
main שגרת
.I
% MAIN
% ====
% Load original picture :
load text;
% Bluring KERNEL :
kernel=ones(3)./9;
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA )
% N=input(' => Enter number of images :');
% ratio=input(' => Enter sampling ratio :');
% ImSize=create_data(A,N,kernel,ratio);
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial guess of SuperResolution image
load Y1
X0=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
K=input(' => Enter number of iterations :');
Mu=input(' => Enter initial Mu :');
EPS = [];
count=[];
% Performong the Restoration procedure :
% -----------------------------------[P0,R0]=mask( N,ratio,size(X0) );
for j=1:K
Xtemp=blur(X0,kernel); % Now Xtemp is blured X0
eps = Xtemp;
Xtemp=Xtemp.*R0 - P0 ;
Xtemp=blur(Xtemp,kernel); % Now Xtemp = H'*( R0*H*X0 - P0 )
% Old and WRONG eps:
% eps=norm(Xtemp,1);
eps = (-2)*sum(sum(eps.*P0)) + sum(sum( (eps.^2).*R0 )) ;
X0=X0-Mu.*Xtemp;
figure;
imshow(X0,[0,255]);
fprintf(' ==> Iteration No %d :> eps= %d\n',j,eps);
EPS=[EPS,eps];
count=[count,j];
end
figure;
plot(count,EPS);
xlabel('Iterations');
ylabel('Epsilon^2');
%figure;
% Show the LAST image - the RESULT
%imshow(X0,[0,255]);
mask שגרת.II
function [P0,R0]=mask(N,ratio,Size);
% Receives :
% - Number of images
% - sampling/interpolate ratio
% - Target image size ( before samling )
P0 = 0;
-20א
.9.4
'נספח א
R0=0;
for i=1:N
eval(['load Y',num2str(i),'.mat']);
X=interpolate(TEMP,ratio,Size);
X=warp_nn(X,-a,-b);
P0=P0+X;
Y=warp_nn(ones(Size),a,b);
Y=sample(Y,ratio);
Y=interpolate(Y,ratio,Size);
Y=warp_nn(Y,-a,-b);
R0=R0+Y;
end
return ;
רזולוציה-שחזור בסופר
% We load : TEMP , a , b
%|
%|> Calculating P0
%|
%|
%|
%|> Calculating R0 mask
%|
%|
version_2_2
main שגרת
.I
% MAIN
% ====
% Load original picture :
load text;
% Bluring KERNEL :
kernel=ones(3)./9;
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA )
% N=input(' => Enter number of images :');
% ratio=input(' => Enter sampling ratio :');
% ImSize=create_data(A,N,kernel,ratio);
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial (guess) SuperResolution image ( 2 options )
load Y1
% X0=interpolate(TEMP,ratio,[ImSize,ImSize]);
X0=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
% X0=zeros(ImSize);
K=input(' => Enter number of iterations :');
EPS = [];
count=[];
% Performong the Restoration procedure :
% -----------------------------------[P0,R0]=mask( N,ratio,size(X0) );
for j=1:K
Xtemp=blur(X0,kernel); % Now Xtemp is blured X0
eps = Xtemp;
Xtemp=Xtemp.*R0 - P0 ;
Xtemp=blur(Xtemp,kernel); % Now Xtemp = H'*( R0*H*X0 - P0 )
% Calculating new Mu :
Mu=nsd(R0,Xtemp,kernel);
fprintf(' => ||Ek||^2 = %d\n',sum(sum(Xtemp.^2)) );
% Old and wrong Epsilon^2 :
% eps=norm(Xtemp,1);
eps = (-2)*sum(sum(eps.*P0)) + sum(sum( (eps.^2).*R0 ));
X0=X0-Mu.*Xtemp;
% Show the current result ( of the current iteration )
% figure;
% imshow(X0,[0,255]);
-21א
.9.5
'נספח א
רזולוציה-שחזור בסופר
fprintf(' ==> Iteration No %d :> eps= %d Mu= %d\n',j,eps,Mu);
EPS=[EPS,eps];
count=[count,j];
end
figure;
plot(count,EPS);
xlabel('Iterations');
ylabel('Epsilon^2');
figure;
% Show the LAST image - the RESULT
imshow(X0,[0,255]);
NSD שגרת.II
function [Mu]=nsd(R0,E,kernel);
% Receives :
% R0 , Error matrix (R*Xj - P), bluring kernel .
HE=blur(E,kernel);
Mu=( sum(sum(E.^2) ) / sum(sum( (HE.^2).*R0 )) );
return;
version_2_3
main שגרת
.I
% MAIN
% ====
% Load original picture :
load text;
% Bluring KERNEL :
kernel=ones(3)./9;
% Regularization kernel LAPLASIAN :
laplasian=[0 -.25 0 ; -.25 1 -.25 ; 0 -.25 0 ];
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA )
N=input(' => Enter number of images :');
ratio=input(' => Enter sampling ratio :');
ImSize=create_data(A,N,kernel,ratio);
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial guess of SuperResolution image
load Y1
X0=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
K=input(' => Enter number of iterations :');
Lambda=input(' => Enter Regularization coeffitient (LAMBDA) :');
EPS = [];
count=[];
% Performong the Restoration procedure :
% -----------------------------------[P0,R0]=mask( N,ratio,size(X0) );
for j=1:K
Xtemp=blur(X0,kernel); % Now Xtemp is blured X0
eps = Xtemp;
Xtemp=Xtemp.*R0 - P0 ;
Xtemp=blur(Xtemp,kernel); % Now Xtemp = H'*( R0*H*X0 - P0 )
Xtemp=Xtemp + Lambda*( blur( blur(X0,laplasian),laplasian) );
% Calculating new Mu :
Mu=new_nsd(R0,Xtemp,kernel,Lambda,laplasian);
% Old and Wrong Epsilon :
-22א
.9.6
'נספח א
רזולוציה-שחזור בסופר
%eps=norm(Xtemp,1)+ Lambda*norm( blur( blur(X0,laplasian),laplasian),1);
eps=(-2)*sum(sum(eps.*P0))+sum(sum( (eps.^2).*R0))+Lambda*sum(sum( blur( blur(X0,laplasian),laplasian)
));
X0=X0-Mu.*Xtemp;
% Another Old and WRONG eps :
% eps = epsilon_calc(X0,N,kernel,ratio,Lambda,laplasian);
% Show the current result ( of the current iteration )
figure;
imshow(X0,[0,255]);
fprintf(' ==> Iteration No %d :> eps= %d Mu= %d\n',j,eps,Mu);
EPS=[EPS,eps];
count=[count,j];
end
%figure;
plot(count,EPS);
xlabel('Iterations');
ylabel('Epsilon^2');
%figure;
% Show the LAST image - the RESULT
%imshow(X0,[0,255]);
new_nsd שגרת.II
function [Mu]=new_nsd(R0,E,kernel,Lambda,laplasian);
% Receives :
% R0 , Error matrix , bluring kernel .
HE=blur(E,kernel);
temp = blur(E,laplasian);
temp=Lambda * sum(sum(temp.^2));
Mu=( sum(sum(E.^2) ) / ( sum(sum( (HE.^2).*R0 )) + temp ) );
return;
version_3_1
main שגרת
.I
% MAIN - version 3.1
% ==================
function [X0] = main(Lambda,K,kernel,ratio,ImSize,N,laplasian);
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial guess of SuperResolution image
eval('load Y1');
X0=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
% Now Lambda and K are received as parameters
% K=input(' => Enter number of iterations :');
% Lambda=input(' => Enter Regularization coeffitient (LAMBDA) :');
EPS = [];
count=[];
% Performong the Restoration procedure :
% -----------------------------------[P0,R0]=mask( N,ratio,size(X0) );
for j=1:K
Xtemp=blur(X0,kernel); % Now Xtemp is blured X0
eps = Xtemp;
Xtemp=Xtemp.*R0 - P0 ;
Xtemp=blur(Xtemp,kernel); % Now Xtemp = H'*( R0*H*X0 - P0 )
Xtemp=Xtemp + Lambda*( blur( blur(X0,laplasian),laplasian) );
-23א
.9.7
'נספח א
רזולוציה-שחזור בסופר
% Calculating new Mu :
Mu=new_nsd(R0,Xtemp,kernel,Lambda,laplasian);
eps=(-2)*sum(sum(eps.*P0))+sum(sum( (eps.^2).*R0))+Lambda*sum(sum( blur( blur(X0,laplasian),laplasian)
));
X0=X0-Mu.*Xtemp;
% Show the current result ( of the current iteration )
% figure;
% imshow(X0,[0,255]);
fprintf(' ==> Iteration No %d :> eps= %d :> Mu= %d\n',j,eps,Mu);
EPS=[EPS,eps];
count=[count,j];
end
figure;
plot(count,EPS);
TITLE=['Lambda = ',num2str(Lambda)];
title(TITLE);
xlabel('Iterations');
ylabel('Epsilon^2');
figure;
% Show the LAST image - the RESULT
imshow(X0,[0,255]);
TITLE=['Regularization - Lambda = ',num2str(Lambda)];
title(TITLE);
return;
create_data שגרת.II
function [ImSize,Xoriginal] = create_data(INPUT,N,kernel,ratio);
% Receives UINT8 image , converts to DOUBLE :
IN=double(INPUT);
% Function : created warped , blured , sub-sampled and noisy images from a given image.
% Receives the next parameters :
% original image , number of processed images , blur kernel , sample ratio .
% Receives interactive inputs :
% Pinch point coordinates , maximal warping interval , target image size .
% Returns : the target (SuperResolution) image size .
% Saves in separated *.mat files (Y1.mat , Y2.mat , .... ) :
% - the output images for each loop ( TEMP )
% - warping coefficients for each loop ( a , b )
% Original image size
[maxY,maxX]=size(IN);
% Receive Inputs from the user
imshow(IN,[0,255]);
fprintf(' => Click a pinch point\n\n');
[x,y]=ginput(1);
x=round(x); y=round(y);
Ysize = min(maxY-y,y); Xsize = min(maxX-x,x);
Delta = input(' => Enter maximal warping interval (pixels) [1..3] : ');
fprintf('\n => Enter Target image size [50..%d] : ',2*min(Xsize,Ysize));
ImSize = input('');
% Check if input is valid
while(ImSize>2*min(Xsize,Ysize))
fprintf(' => ERROR !!! Index exceeds matrix dimentions\n');
fprintf('\n => Enter Target image size [50..%d] : ',2*min(Xsize,Ysize));
ImSize = input('');
end
% Perform processing
-24א
'נספח א
רזולוציה-שחזור בסופר
for i=1:N
% The first processed image is not warped !!
if i==1
a=0; b=0;
else
a=Delta*(2*rand-1); b=Delta*(2*rand-1);
end
% Warp :
TEMP=warp(IN,a,b);
% Cut the target block with spare rows and columns for proper bluring :
spare=length(kernel);
if (mod(ImSize,2)==0)
TEMP=TEMP(y-floor(ImSize/2)+1-spare:y+floor(ImSize/2)+spare , x-floor(ImSize/2)+1spare:x+floor(ImSize/2)+spare);
else
TEMP=TEMP(y-(ImSize-1)/2-spare:y+(ImSize-1)/2+spare , x-(ImSize-1)/2-spare:x+(ImSize-1)/2+spare);
end
if i==1
Xoriginal=TEMP; % The original image - TARGET image .
%Cut the spare rows and columns :
Xoriginal=Xoriginal(spare+1:end-spare ,spare+1:end-spare );
end
% Blur :
TEMP = blur(TEMP,kernel);
%Cut the spare rows and columns :
TEMP=TEMP(spare+1:end-spare ,spare+1:end-spare );
% Sample :
TEMP = sample(TEMP,ratio);
% Noise addition :
TEMP=TEMP+randn(size(TEMP)) ;
% Final result assignment :
str1='save Y';
str2='.mat TEMP a b';
eval([str1,num2str(i),str2]);
figure;
imshow(TEMP,[0,255]);
fprintf(' => Saving %d image to Y%d.mat\n',i,i);
end
return ;
graph שגרת.III
%
^
% GRAPH - || X - X || Vs. Lambda
% ==============================
% Load original picture :
load text;
% Bluring KERNEL :
kernel = ones(3)./9;
% Regularizatio kernel LAPLASIN :
laplasian = [0 -0.25 0 ; -0.25 1 -0.25 ; 0 -0.25 0];
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA)
%N=input(' => Enter number of images :');
-25א
'נספח א
רזולוציה-שחזור בסופר
%ratio=input(' => Enter sampling ratio :');
%[ImSize,Xoriginal]=create_data(A,N,kernel,ratio);
% By now we have N images and their warping coefficients ,
% saved in files ( Y1.mat , Y2.mat ....)
Lambda_array=[];
Lambda_results1=[];
Lambda_results2=[];
Lambda_results3=[];
%K=input(' => Enter number of iterations :');
%Lambda=input(' => Enter regularization coeficient LAMBDA :');
%while (Lambda ~= -1)
for Lambda=[5,10]
fprintf('====>Lambda = %d !!!\n',Lambda);
K=50;
X0=main(Lambda,K,kernel,ratio,ImSize,N,laplasian);
temp=sum(sum( (Xoriginal-X0).^2 ));
Lambda_results1=[Lambda_results1,temp];
% K=50;
% X0=main(Lambda,K,kernel,ratio,ImSize,N,laplasian);
% temp=sum(sum( (Xoriginal-X0).^2 ));
% Lambda_results2=[Lambda_results2,temp];
% K=100;
% X0=main(Lambda,K,kernel,ratio,ImSize,N,laplasian);
% temp=sum(sum( (Xoriginal-X0).^2 ));
% Lambda_results3=[Lambda_results3,temp];
% Updating Lambda array:
Lambda_array=[Lambda_array,Lambda];
%K=input(' => Enter number of iterations :');
%Lambda=input(' => Enter regularization coeficient LAMBDA :');
%if (Lambda == -1)
% fprintf('====>End !!!\n');
%end
end % End of for/while
%figure;
%plot(Lambda_array,Lambda_results1,Lambda_array,Lambda_results2,Lambda_array,Lambda_results3);
%title('|| X - Xr || ^2 ');
%xlabel('Lambda');
%figure;
%loglog(Lambda_array,Lambda_results1,Lambda_array,Lambda_results2,Lambda_array,Lambda_results3);
%title('LOG( || X - Xr || ^2 )');
%xlabel('Lambda');
version_3_2
wls_mask שגרת.IV
function [W] = wls_mask(X,a,b);
% Calculates the W matrix mask
% Receives as parameters :
%
Xblured - blured image
%
a,b - (2nd option)
% Regularization kernel LAPLASIAN :
laplasian=[0 -.25 0 ; -.25 1 -.25 ; 0 -.25 0 ];
-26א
.9.8
'נספח א
רזולוציה-שחזור בסופר
Xd = blur(X,laplasian);
Xd = abs(Xd);
% 1st option : constant threshold:
% -------------------------------saf = ( max(max(Xd)) + min(min(Xd)) )*(a);
W=( Xd < saf );
% When Xd[i,j] < saf then TRUE => W[i,j] = 1
%
Xd[i,j] > saf then FALSE => W[i,j] = 0
% 2nd option : linear function
% ---------------------------%W=( (Xd>a).*(Xd<=b).*(Xd-b)./(a-b) + (Xd<=a) );
% 3rd option : square function:
% ----------------------------%a=saf;
%W = 1./(1+(Xd.*a).^2);
return ;
w_nsd שגרת.V
function [Mu]=w_nsd(R0,E,kernel,Lambda,laplasian,W);
% Receives :
% R0 , Error matrix , bluring kernel .
HE=blur(E,kernel);
temp = W.*blur(E,laplasian);
temp = blur(temp,laplasian);
temp=Lambda * sum(sum( (temp.^2) ));
Mu=( sum(sum(E.^2) ) / ( sum(sum( (HE.^2).*R0 )) + temp ) );
return;
version_CG
main שגרת
.I
% MAIN - CG including Regularization
% ==========================
% Load original picture :
load text;
% Bluring KERNEL :
kernel=ones(3)./9;
% Regularization kernel LAPLASIAN :
laplasian = [0 -.25 0 ; -.25 1 -.25 ; 0 -.25 0];
% Create N warped , blured and undersampled images :
% ( Comment to skip CREATE_DATA )
% N=input(' => Enter number of images :');
% ratio=input(' => Enter sampling ratio :');
% [ImSize,Xoriginal]=create_data(A,N,kernel,ratio);
% temporal - load Xtrue (for checks)
load true;
% By now we have N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial (guess) SuperResolution image ( 2 options )
load Y1
K=input(' => Enter number of iterations :');
Lambda=input(' => Enter Regularization Coefficient ( LAMBDA ) :');
NORMA=[];
-27א
.9.9
'נספח א
רזולוציה-שחזור בסופר
EPS = [];
count=[];
% Performong the Restoration procedure :
% -----------------------------------Xk=initial_interpolate(TEMP,ratio,[ImSize,ImSize]);
[P0,R0,Eps_Const]=mask( N,ratio,size(Xk) );
Ek=[];
Vk=[];
for j=1:K
Xtemp=blur(Xk,kernel); % Now Xtemp is blured Xk
Xtemp=Xtemp.*R0 - P0 ;
Xtemp=blur(Xtemp,kernel); % Now Xtemp = H'*( R0*H*Xk - P0 )
Vkk=Vk;
Ek=Xtemp + Lambda*(blur(blur(Xk,laplasian),laplasian));
if(j==1)
Vk=Ek;
Muk=CG(R0,Ek,Vk,kernel,Lambda,laplasian);
else
HEk = blur(Ek,kernel);
HVkk = blur(Vkk,kernel);
DEk = blur(Ek,laplasian);
DVkk = blur(Vkk,laplasian);
Betakk=sum(sum( (HEk.*HVkk).*R0 + Lambda*DEk.*DVkk ))/sum(sum( (HVkk.^2).*R0 +
Lambda*(DVkk.^2) ));
Vk = Betakk*Vkk - Ek;
Muk = CG(R0,Ek,Vk,kernel,Lambda,laplasian);
end
% fprintf(' => ||Ek||^2 = %d\n',sum(sum(Xtemp.^2)) );
% ---------------Xk = Xk - Muk.*Vk;
% ---------------eps=blur(Xk,kernel);
eps = (-2)*sum(sum(eps.*P0)) + sum(sum( (eps.^2).*R0 ));
eps = eps + Eps_Const;
norma = sum(sum( (Xk-Xtrue).^2 ));
% Show the current result ( of the current iteration )
% figure;
% imshow(Xk,[0,255]);
fprintf(' ==> Iteration No %d :> eps= %d Mu= %d\n',j,eps,Muk);
NORMA=[NORMA,norma];
EPS=[EPS,eps];
count=[count,j];
end
figure;
subplot(2,1,1);
plot(count,EPS);
xlabel('Iterations');
ylabel('Epsilon^2');
subplot(2,1,2);
plot(count,NORMA);
xlabel('Iterations (log)');
ylabel('||Xk-Xtrue||^2 (log)');
figure;
% Show the LAST image - the RESULT
imshow(Xk,[0,255]);
-28א
'נספח א
רזולוציה-שחזור בסופר
CG שגרת.II
%Conjugate Gradient – CG function
==========================
function [Mu]=CG(R0,E,V,kernel,Lambda,laplasian);
% Receives :
% R0 , Error matrix (R*Xj - P + Lambda*D'*D*Xj), bluring kernel .
HV=blur(V,kernel);
DV=blur(V,laplasian);
Mu=( sum(sum(E.*V) ) / sum(sum( (HV.^2).*R0 + Lambda*(DV.^2) )) );
return;
Square_Problem
Square Problem Simulation :
% =========================
A=rand(50,80)*100;
Q=A*A';
P=rand(50,1)*100;
Xtrue=inv(Q)*P;
% X initial
Xinit=100*rand(50,1);
K=input(' -> Enter number of iterations :');
NORM_NSD=[]; NORM_CG=[];
EPS_NSD=[]; EPS_CG=[];
count=[];
eps_true=(0.5*Xtrue'*Q*Xtrue - P'*Xtrue);
X=Xinit;
% NSD loop :
for j=1:K
Ek=Q*X-P;
Mu=(Ek'*Ek)/(Ek'*Q*Ek);
X=X-Mu*Ek;
norm=sum(sum( (Xtrue-X).^2 ));
eps=(0.5*X'*Q*X - P'*X);
count=[count,j];
EPS_NSD=[EPS_NSD,eps-eps_true];
NORM_NSD=[NORM_NSD,norm];
end
X=Xinit;
Vk=[];
% CG loop :
for j=1:K
Ek=Q*X-P;
Vkk=Vk;
if (j==1)
Vk=Ek;
Mu=(Ek'*Vk)/(Vk'*Q*Vk);
else
Betakk=(Ek'*Q*Vkk)/(Vkk'*Q*Vkk);
-29א
.9.10
'נספח א
רזולוציה-שחזור בסופר
Vk=-Ek + Betakk*Vkk;
Mu=(Ek'*Vk)/(Vk'*Q*Vk);
end
X=X - Mu*Vk;
norm=sum(sum( (Xtrue-X).^2 ));
eps=(0.5*X'*Q*X - P'*X);
EPS_CG=[EPS_CG,eps-eps_true];
NORM_CG=[NORM_CG,norm];
end
subplot(2,1,1);
semilogy(count,abs(EPS_NSD),count,abs(EPS_CG));
title('Epsilon^2');
xlabel('iterations');
subplot(2,1,2);
semilogy(count,NORM_NSD,count,NORM_CG);
title('Norm - ||Xtrue-X||^2');
xlabel('iterations');
Motion_Estimation
lme שגרת
%Motion Estimation – lme function
==========================
function [dx,dy] = lme(I1,I2);
% Gaussian Bluring kernel :
for k=-2:2
for l=-2:2
G(k+3,l+3)=exp(-0.25*(k^2+l^2)/(2^2));
end
end
G=G/sum(G(:));
x=100;
y=100;
dx=0;dy=0;
while((abs(x)>0.1)|(abs(y)>0.1))
[x,y]=estimate(I1,I2,G);
dx=dx+x;
dy=dy+y;
fprintf('=> dx = %d dy = %d\n',dx,dy);
I2=warp(I2,y,x);
% Cut Zeros (optional):
if ((x>=0)&(y>=0))
I2=I2(ceil(y)+1:end,ceil(x)+1:end);
I1=I1(ceil(y)+1:end,ceil(x)+1:end);
elseif ((x<0)&(y>=0))
I2=I2(ceil(y)+1:end,1:floor(x)+end);
I1=I1(ceil(y)+1:end,1:floor(x)+end);
elseif ((x>=0)&(y<0))
I2=I2(1:floor(y)+end,ceil(x)+1:end);
I1=I1(1:floor(y)+end,ceil(x)+1:end);
elseif ((x<0)&(y<0))
I2=I2(1:floor(y)+end,1:floor(x)+end);
I1=I1(1:floor(y)+end,1:floor(x)+end);
end
% end of CUT Zeros (optional)
-30א
.I
.9.11
'נספח א
רזולוציה-שחזור בסופר
end %end of WHILE
return;
estimate שגרת.II
% Motion Estimation – estimate function
==============================
function [dx,dy]=estimate(I1,I2,G);
% Differentiating kernels :
Dx=[1 -8 0 8 -1]./12;
Dy=Dx';
% Pre-estimating blurring
I1=blur(I1,G);
I2=blur(I2,G);
% Differentiating :
I2x=blur(I2,Dx);
I2y=blur(I2,Dy);
% Cut The Edges : 4 pixels from each side
I2x=I2x(5:end-4,5:end-4);
I2y=I2y(5:end-4,5:end-4);
I1=I1(5:end-4,5:end-4);
I2=I2(5:end-4,5:end-4);
% Creating Column-Stacks :
Y=im2col(I1-I2,size(I1));
CI2x=im2col(I2x,size(I2x));
CI2y=im2col(I2y,size(I2y));
H=[CI2x,CI2y];
% Problem Solution :
z = (inv(H'*H))*(H'*Y);
dx=z(1,1);
dy=z(2,1);
return;
EXPERIMENT
preapare שגרת
% Creation of monochromatic images out of taken pictures
% Performs :
% - loads first input image
% - converts it to grayscale
% - lets to choose a pinch point
% - cuts a 200x200 image
% - loads each input image, cuts 200x200 and saves
% - deletes the original input file
% Name of input images : t0.bmp, t1.bmp, ...
% Name of output files : t0.mat, t1.mat, ...
N=input('=> Enter number of images (from 0 to N) :');
for i=0:N
string_save=['save Z',num2str(i),'.mat TEMP'];
string=['t',num2str(i),'.bmp'];
TEMP = imread(string,'bmp');
TEMP=rgb2gray(TEMP);
if (i==0)
-31א
.I
.9.12
'נספח א
רזולוציה-שחזור בסופר
imshow(TEMP,[0,255]);
[x,y]=ginput;
x=round(x);y=round(y);
end
TEMP=TEMP(y-100:y+99,x-100:x+99);
TEMP=double(TEMP);
eval(string_save);
delete(string);
figure;
imshow(TEMP,[0,255]);
end % of FOR
show_diff שגרת.II
% Performs MotionEstimation to the input images
% (relatively to the first)
% Shows the difference images
N=input('=> Enter number of images (from 0 to N) :');
load Z0;
A=TEMP;
for i=1:N
str=['load Z',num2str(i)];
eval(str);
[dx,dy]=lme(TEMP,A);
TEMP=warp(TEMP,-dy,-dx);
TEMP=abs(TEMP-A);
str_temp=['diff',num2str(i),'=TEMP;'];
eval(str_temp);
% Parameter of ImShow = 30
figure;
imshow(TEMP,[0,30]);
str=['Image Z',num2str(i),'.mat'];
title(str);
end % of FOR
save diffs
main שגרת.III
% MAIN
% ====
% Bluring KERNEL :
% kernel=ones(3)./9;
kernel=zeros(7,7);
sigma=3.5;
for k=-3:1:3,
for j=-3:1:3,
kernel(k+4,j+4)=exp(-(k^2+j^2)/(2*sigma^2));
end;
end;
kernel=kernel/sum(kernel(:));
% Regularization kernel LAPLASIAN :
laplasian=[0 -.25 0 ; -.25 1 -.25 ; 0 -.25 0 ];
N=input(' => Enter number of images :');
ratio=input(' => Enter sampling ratio :');
N=15; ratio = 2;
Creating Y1.mat, Y2.mat... files - images and motion
% ---------------------------------------------------% 1) Separating Odd and Even lines : creation of N*2 images
-32א
'נספח א
רזולוציה-שחזור בסופר
for i=1:N
str1='load Z';
str2='.mat';
eval([str1,num2str(i),str2]);
A=TEMP(1:2:end,1:end);
B=TEMP(2:2:end,1:end);
TEMP=A; % ODD LINES
str1='save Z';
str2='.mat TEMP';
eval([str1,num2str(i),str2]);
TEMP=B; % EVEN LINES
str1='save Z';
str2='.mat TEMP';
eval([str1,num2str(i+N),str2]);
end
% 2) Motion Estimation and Final Save :
for i=1:2*N
str1='load Z';
str2='.mat';
eval([str1,num2str(i),str2]);
if (i==1)
a=0;b=0;TEMP_Ref=TEMP; % Saves the 1st image
else
[b,a]=lme(TEMP,TEMP_Ref);
b=b*ratio;a=a*2*ratio;
end
str1='save Y';
str2='.mat TEMP a b';
eval([str1,num2str(i),str2]);
end
% End Of Creating Yx.mat files
% By now we have 2*N images and their warping coefficients, saved in files (Y1.mat , Y2.mat .... )
% Creating the initial (guess) SuperResolution image ( 2 options )
load Y1
X0=kron(TEMP,ones(ratio*2,ratio));
K=input(' => Enter number of iterations :');
Lambda=input(' => Enter Regularization coeffitient (LAMBDA) :');
% Performong the Restoration procedure :
% -----------------------------------[P0,R0,Eps_Const]=mask( N,ratio,size(X0) );
for j=1:K
Xtemp=blur(X0,kernel); % Now Xtemp is blured X0
Xtemp=Xtemp.*R0 - P0 ;
Xtemp=blur(Xtemp,kernel); % Now Xtemp = H'*( R0*H*X0 - P0 )
Xtemp=Xtemp + Lambda*( blur( blur(X0,laplasian),laplasian) );
% Calculating new Mu :
Mu=new_nsd(R0,Xtemp,kernel,Lambda,laplasian);
%--------------X0=X0-Mu.*Xtemp;
%--------------fprintf('==> Iteration # %d\n',j);
% Show the current result ( of the current iteration )
% figure;
% imshow(X0,[0,255]);
% fprintf(' ==> Iteration No %d :> eps= %d Mu= %d\n',j,eps,Mu);
-33א
'נספח א
רזולוציה-שחזור בסופר
end
% Show the LAST image - the RESULT
figure;
imshow(X0,[0,255]);
str=['Bluring kernel with SIGMA = ',num2str(sigma),' LAMBDA = ',num2str(Lambda)];
title(str);
zoom on;
mask שגרת.IV
function [P0,R0,Eps_Const]=mask(N,ratio,Size);
% Receives :
% - Number of images
% - sampling/interpolate ratio
% - Target image size ( before samling )
% Returnes :
% - P0 , R0
% - Constant component of Epsilon^2
Eps_Const = 0;
P0 = 0;
R0=0;
for i=1:2*N
eval(['load Y',num2str(i),'.mat']); % We load : TEMP , a , b
X=interpolate(TEMP,ratio,Size); %|
X=warp_nn(X,-a,-b);
%| > Calculating P0
P0=P0+X;
%|
Y=warp_nn(ones(Size),a,b);
%|
Y=sample(Y,ratio);
%|
Y=interpolate(Y,ratio,Size);
%|> Calculating R0 mask
Y=warp_nn(Y,-a,-b);
%|
R0=R0+Y;
%|
Eps_Const = Eps_Const + sum(sum(TEMP.^2));
end
return ;
intepolate שגרת.V
function out=interpolate(A,ratio,OriginalSize)
% Receives parameters :
% - the input image (sampled)
% - sampling ratio
% - size of the original image (before sampling)
%[a,b]=size(A);
%out=zeros(a*2*ratio,b*ratio);
%out(1:2*ratio:end,1:ratio:end) = A;
out=zeros(2*ratio,ratio);
out(1,1)=1;
out = kron(A,out);
out=out( 1:OriginalSize(1) , 1:OriginalSize(2) );
return ;
sample שגרת.VI
function out = sample(A,ratio)
out = A(1:2*ratio:end,1:ratio:end);
return ;
-34א
'נספח א
רזולוציה-שחזור בסופר
new_nsd שגרת.VII
function [Mu]=new_nsd(R0,E,kernel,Lambda,laplasian);
% Receives :
% R0 , Error matrix , bluring kernel .
HE=blur(E,kernel);
temp = blur(E,laplasian);
temp=Lambda * sum(sum(temp.^2));
Mu=( sum(sum(E.^2) ) / ( sum(sum( (HE.^2).*R0 )) + temp ) );
return;
-35א
© Copyright 2026 Paperzz