2. מימוש אלגוריתם ה

‫נספח א'‬
‫מימוש אלגוריתמי השחזור‬
‫נספח א'‬
‫שחזור בסופר‪-‬רזולוציה‬
‫תוכן עניינים‬
‫‪ 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‫א‬