छवि को पैच करें


114

एक लोकप्रिय छवि संपादन सॉफ्टवेयर में एक विशेषता यह है कि पैच (अवधि छवि प्रसंस्करण में इस्तेमाल किया जाता है, inpainting जानकारी के आधार पर एक छवि के एक चयनित क्षेत्र के रूप में @ mınxomaτ ने बताया।), बाहर है कि पैच की। और यह काफी अच्छा काम करता है, इस पर विचार करना सिर्फ एक कार्यक्रम है। एक इंसान के रूप में, आप कभी-कभी देख सकते हैं कि कुछ गड़बड़ है, लेकिन अगर आप अपनी आँखें निचोड़ लेते हैं या बस एक छोटी सी नज़र रखते हैं, तो पैच अंतराल में काफी अच्छी तरह से भर जाता है ।

लोकप्रिय छवि संपादन सॉफ्टवेयर द्वारा उदाहरण

चुनौती

एक छवि और एक मुखौटा को देखते हुए जो छवि के आयताकार क्षेत्र को निर्दिष्ट करता है, उसे पैच किया जाना चाहिए (छवि या किसी अन्य पसंदीदा प्रारूप के रूप में भी), आपके प्रोग्राम को निर्दिष्ट क्षेत्र को एक पैच के साथ भरने की कोशिश करनी चाहिए जो बाकी हिस्सों के साथ मिश्रण करने की कोशिश करता है छवि। कार्यक्रम उस मूल छवि की जानकारी का उपयोग नहीं कर सकता है जो निर्दिष्ट क्षेत्र के भीतर थी।

आप मान सकते हैं कि पैच हमेशा कम से कम चौड़ाई से दूर होता है, और यह छवि के ऊपर और नीचे से ऊंचाई से दूर होता है। इसका मतलब है कि एक पैच का अधिकतम क्षेत्र पूरी छवि का 1/9 है।

कृपया एक संक्षिप्त विवरण जोड़ें कि आपका एल्गोरिदम कैसे काम करता है।

मतदान

मतदाताओं को यह बताने के लिए कहा जाता है कि एल्गोरिदम कितना अच्छा प्रदर्शन करते हैं और तदनुसार मतदान करते हैं।

न्याय करने के तरीके पर कुछ सुझाव: (फिर, धन्यवाद @ mınxoma the कुछ और मानदंडों के लिए।)

  • यदि आप अपनी आँखें निचोड़ते हैं और चित्र ठीक दिखता है?
  • क्या आप वास्तव में बता सकते हैं कि पैच कहाँ है?
  • छवि पृष्ठभूमि और आसपास के क्षेत्र से संरचनाएं और बनावट कितनी अच्छी हैं?
  • संपादित क्षेत्र में कितने आवारा झूठे रंगीन पिक्सेल हैं?
  • क्या क्षेत्र में कोई समान रूप से रंगीन बूँदें / ब्लॉक हैं जो वहां नहीं लगते हैं?
  • क्या संपादित क्षेत्र में शेष छवि की तुलना में कोई कठोर रंग / विपरीत या चमक बदलाव है?

वैधता मानदंड

प्रस्तुत करने के लिए मान्य होने के लिए, आउटपुट छवि को निर्दिष्ट क्षेत्र के बाहर इनपुट छवि से बिल्कुल मेल खाना चाहिए।

परीक्षण का मामला

बाईं ओर स्रोत छवि, दाईं ओर इसी नकाब पर:


1
क्या हम मुखौटा इनपुट को पाठ तर्क (जैसे। inpaint.exe left top width height img.jpg) के रूप में स्वीकार कर सकते हैं ?
mınxomaτ

1
निश्चित रूप से, इनपुट / आउटपुट प्रारूप वास्तव में उतना महत्वपूर्ण नहीं है, क्योंकि यह एक लोकप्रियता प्रतियोगिता है जहां सबसे पहले आपके एल्गोरिथ्म का प्रदर्शन महत्वपूर्ण है।
दोष

24
यह एक बहुत ही व्यावहारिक चुनौती है। यह संभव है कि परिणाम जीआईएमपी और अन्य ओपन सोर्स इमेज एडिटिंग सॉफ्टवेयर में इस्तेमाल किए गए मौजूदा एल्गोरिदम से बेहतर होंगे। भाग्य, प्रसिद्धि और महिमा आपकी हो सकती है!
23

6
@ शेपर और अंत में बदसूरत वॉटरमार्क को डाउनलोड मीडिया से हटाया जा सकता है;)
एंड्रास डीक

2
बिल्‍ड बिल्‍कुल ठीक हैं, मुझे संदेह है कि उनका जाना बहुत लोकप्रिय है।
दोष

जवाबों:


142

ऑटो इट , वीबी

परिचय

यह ए क्रिमिसी, पी। पेरेज (कैम्ब्रिज माइक्रोसॉफ्ट रिसर्च लिमिटेड) और के। टोयामा (माइक्रोसॉफ्ट) [एक्स] द्वारा विकसित एक्समप्लर-आधारित इनपैनटिंग एल्गोरिदम द्वारा ऑब्जेक्ट रिमूवल का एक कार्यान्वयन है । यह एल्गोरिदम उच्च-सूचना छवियों (और वीडियो फ़्रेम) पर लक्षित है और इसका उद्देश्य संरचनात्मक पुनर्निर्माण और कार्बनिक पुनर्निर्माण के बीच संतुलन होना है। इस उत्तर के पैराग्राफ में मूल उत्तर से पूर्ण पाठ उद्धरण होते हैं (क्योंकि अब यह आधिकारिक रूप से उपलब्ध नहीं है) इस उत्तर को अधिक स्व-निहित बनाने के लिए।

एल्गोरिथ्म

लक्ष्य : नेत्रहीन प्रशंसनीय पृष्ठभूमि के साथ एक चयनित ( नकाबपोश ) क्षेत्र (अधिमानतः एक नेत्रहीन अलग अग्रभूमि वस्तु) को बदलें ।

पिछले काम में, कई शोधकर्ताओं ने बनावट के संश्लेषण को "शुद्ध" बनावट के साथ बड़ी छवि वाले क्षेत्रों को भरने के तरीके के रूप में माना है - दोहराए गए दो आयामी पाठ पैटर्न के साथ मध्यम स्टोचैस्टिसिटी। यह बनावट-संश्लेषण अनुसंधान के एक बड़े निकाय पर आधारित है, जो बनावट बनावट को हटाने के लिए चाहता है, जिसे शुद्ध बनावट का एक छोटा स्रोत नमूना दिया गया है [1] [[] [९] [१०] [११] [१२] [१४] [१५] [१६] [१ ९] [२२]

चूंकि ये तकनीकें लगातार बनावट की नकल करने में प्रभावी हैं, उन्हें वास्तविक दुनिया के दृश्यों की तस्वीरों में छेद भरने में कठिनाई होती है, जिसमें अक्सर रैखिक संरचनाएं और समग्र बनावट शामिल होती हैं - कई बनावट स्थानिक रूप से बातचीत करते हुए [23] । मुख्य समस्या यह है कि छवि क्षेत्रों के बीच की सीमाएं विभिन्न बनावटों के बीच आपसी प्रभावों का एक जटिल उत्पाद हैं। शुद्ध बनावट की द्वि-आयामी प्रकृति के विपरीत, ये सीमाएँ ऐसी बनती हैं जिन्हें अधिक एक आयामी, या रैखिक, छवि संरचना माना जा सकता है।

छवि inpainting तकनीकों प्रसार के माध्यम से लक्ष्य क्षेत्र में रैखिक संरचनाओं ( inpainting साहित्य में isophotes कहा जाता है) के प्रसार द्वारा छवियों में छेद भरते हैं । वे भौतिक गर्मी प्रवाह के आंशिक अंतर समीकरणों से प्रेरित हैं, और पुनर्स्थापना एल्गोरिदम के रूप में पूरी तरह से काम करते हैं। उनकी कमी यह है कि प्रसार प्रक्रिया कुछ धब्बा का परिचय देती है, जो ध्यान देने योग्य है।

अंजीर।  2

भरा जाने वाला क्षेत्र, अर्थात, लक्ष्य क्षेत्र Ω द्वारा इंगित किया जाता है, और इसके समोच्च को, से चिह्नित किया जाता है। एल्गोरिथ्म आगे बढ़ने के साथ समोच्च आवक विकसित होता है, और इसलिए हम इसे "भरने के मोर्चे" के रूप में भी संदर्भित करते हैं। स्रोत क्षेत्र, source, जो पूरे एल्गोरिथ्म में तय रहता है, भरने की प्रक्रिया में उपयोग किए गए नमूने प्रदान करता है। अब हम यह दिखाने के लिए एल्गोरिथ्म के एक एकल पुनरावृत्ति पर ध्यान केंद्रित करते हैं कि कैसे संरचना और बनावट को अनुकरणीय-आधारित संश्लेषण द्वारा पर्याप्त रूप से नियंत्रित किया जाता है। मान लीजिए कि वर्ग टेम्पलेट ∈p ∈ p बिंदु p (अंजीर। 2 बी) पर केंद्रित है, भरना है। स्रोत क्षेत्र से सर्वश्रेष्ठ-मैच नमूना पैच ˆq∈ Φ from से आता है, जो उन हिस्सों के समान है जो पहले से ही partsp में भरे हुए हैं। चित्र में उदाहरण में। 2 बी, हम देखते हैं कि यदि ,p एक छवि बढ़त की निरंतरता पर स्थित है, सबसे अधिक संभावना है कि सबसे अच्छे मैच एक ही (या इसी तरह के रंग के) किनारे (जैसे,'q 'और' अंजीर '2c') में होंगे। आइसोफोट को अंदर की ओर फैलाने के लिए आवश्यक सभी को सर्वश्रेष्ठ-मैच सोर्स पैच (अंजीर। 2 डी) से पैटर्न का एक सरल स्थानांतरण है। सूचना है कि आइसोफोट अभिविन्यास स्वचालित रूप से संरक्षित है। आंकड़े में, इस तथ्य के बावजूद कि मूल किनारा लक्ष्य समोच्च og के लिए ऑर्थोगोनल नहीं है, प्रचारित संरचना ने स्रोत क्षेत्र के समान ही अभिविन्यास बनाए रखा है।

कार्यान्वयन और एल्गोरिथम विवरण

इस कार्यान्वयन की कार्यक्षमता ActiveX COM DLL में होस्ट की गई है, जिसे होस्ट प्रोग्राम से बाइनरी के रूप में हटा दिया जाता है और फिर IID द्वारा inpainter को कॉल करके फ्लाई पर इनवाइट किया जाता है। इस विशिष्ट मामले में, API VisualBasic में लिखा गया है और इसे किसी भी COM- सक्षम भाषा से कहा जा सकता है। कोड का निम्न खंड द्विआधारी छोड़ता है:

Func deflate($e=DllStructCreate,$f=@ScriptDir&"\inpaint.dll")
    If FileExists($f) Then Return
    !! BINARY CODE OMITTED FOR SIZE REASONS !!
    $a=$e("byte a[13015]")
    DllCall("Crypt32.dll","bool","CryptStringToBinaryA","str",$_,"int",0,"int",1,"struct*",$a,"int*",13015,"ptr",0,"ptr",0)
    $_=$a.a
    $b=$e('byte a[13015]')
    $b.a=$_
    $c=$e("byte a[14848]")
    DllCall("ntdll.dll","int","RtlDecompressBuffer","int",2,"struct*",$c,"int",14848,"struct*",$b,"int",13015,"int*",0)
    $d=FileOpen(@ScriptDir&"\inpaint.dll",18)
    FileWrite($d,Binary($c.a))
    FileClose($d)
EndFunc

लाइब्रेरी को बाद में CLSID और IID का उपयोग करके तत्काल किया जाता है:

Local $hInpaintLib = DllOpen("inpaint.dll")
Local $oInpaintLib = ObjCreate("{3D0C8F8D-D246-41D6-BC18-3CF18F283429}", "{2B0D9752-15E8-4B52-9569-F64A0B12FFC5}", $hInpaintLib)

पुस्तकालय एक GDIOBJECT हैंडल को स्वीकार करता है, विशेष रूप से किसी भी GDI / + बिटमैप (फाइल, स्ट्रीम) का DIBSection। निर्दिष्ट छवि फ़ाइल भरी हुई है, और Scan0इनपुट छवि आयामों से निर्मित एक खाली बिटमैप पर खींची गई है ।

इस कार्यान्वयन के लिए इनपुट फ़ाइल किसी भी GDI / + संगत फ़ाइल स्वरूप है जिसमें नकाबपोश छवि डेटा है। मुखौटा (रों) इनपुट छवि में एक या अधिक समान रूप से रंगीन क्षेत्रों है। उपयोगकर्ता मुखौटा के लिए एक आरजीबी रंग मूल्य की आपूर्ति करता है, केवल पिक्सेल जो उस रंग मूल्य से मेल खाते हैं। डिफ़ॉल्ट मास्किंग का रंग हरा (0, 255, 0) है। सभी नकाबपोश क्षेत्र एक साथ लक्ष्य क्षेत्र का प्रतिनिधित्व करते हैं, filled, हटाए जाने और भरे जाने के लिए। स्रोत क्षेत्र, source, को लक्ष्य क्षेत्र (us = I Φ Φ) संपूर्ण छवि के रूप में परिभाषित किया गया है।

अगला, जैसा कि सभी उदाहरण-आधारित बनावट संश्लेषण [10] के साथ , टेम्प्लेट विंडो का आकार Ψ (उर्फ " स्कैन त्रिज्या ") निर्दिष्ट किया जाना चाहिए। यह कार्यान्वयन 6² पिक्सेल का एक डिफ़ॉल्ट विंडो आकार प्रदान करता है, लेकिन व्यवहार में उपयोगकर्ता को इसे स्रोत क्षेत्र में सबसे बड़े विशिष्ट बनावट तत्व, या "टेक्सल" से थोड़ा बड़ा होने की आवश्यकता होती है। मूल एल्गोरिथ्म के लिए एक अतिरिक्त संशोधन उपयोगकर्ता-निश्चित " ब्लॉक आकार " है जो पिक्सेल के क्षेत्र को एक नए समान रंग के साथ प्रतिस्थापित करने के लिए निर्धारित करता है। इससे गति बढ़ती है और गुणवत्ता घटती है। 1px से ब्लॉक आकार के ग्राफर का उपयोग अत्यंत समान क्षेत्रों (पानी, रेत, फर आदि) के साथ किया जाना है, हालांकि, at को अधिकतम रखा जाना चाहिए। .5x ब्लॉक आकार (जो मुखौटा के आधार पर असंभव हो सकता है)।

1bit छवियों पर एल्गोरिथ्म को स्टाल नहीं करने के लिए, हर बार 5 रंगों से कम की छवि प्राप्त होती है, विंडो का आकार 10x से बढ़ जाता है।

एक बार ये पैरामीटर निर्धारित हो जाने के बाद, शेष क्षेत्र-भरने की प्रक्रिया पूरी तरह से स्वचालित है। हमारे एल्गोरिथ्म में, प्रत्येक पिक्सेल एक रंग मान (या "खाली", यदि पिक्सेल अपूर्ण है) और एक विश्वास मूल्य रखता है, जो पिक्सेल मूल्य में हमारे आत्मविश्वास को दर्शाता है, और जो एक पिक्सेल भर जाने के बाद जमे हुए है। एल्गोरिथ्म के दौरान, भरण मोर्चे के साथ पैच को भी एक अस्थायी प्राथमिकता मूल्य दिया जाता है, जो उस क्रम को निर्धारित करता है जिसमें वे भरे हुए हैं। फिर, हमारा एल्गोरिदम निम्नलिखित तीन चरणों को पुनरावृत्त करता है जब तक कि सभी पिक्सेल भर नहीं गए।

चरण 1: कम्प्यूटिंग पैच प्राथमिकताएं

गैर-पैरामीट्रिक बनावट संश्लेषण [1] [6] [१०] [१३] के लिए भरना आदेश महत्वपूर्ण है । इस प्रकार अब तक, डिफ़ॉल्ट पसंदीदा "प्याज छील" विधि रही है, जहां लक्ष्य क्षेत्र को बाहर की ओर से संकेंद्रित परतों में संश्लेषित किया जाता है। हमारा एल्गोरिथम इस कार्य को सबसे पहले भरने वाले एल्गोरिथ्म के माध्यम से करता है जो पूरी तरह से प्राथमिकता मानों पर निर्भर करता है जो कि भरने वाले मोर्चे पर प्रत्येक पैच को सौंपा जाता है। प्राथमिकता की गणना उन पैचों के प्रति पक्षपाती है जो मजबूत किनारों की निरंतरता पर हैं और जो उच्च-आत्मविश्वास वाले पिक्सल से घिरे हैं, ये पिक्सेल सीमा हैं, जो मान -2 द्वारा चिह्नित हैं। निम्नलिखित कोड प्राथमिकताओं को फिर से बताता है:

For j = m_top To m_bottom: Y = j * m_width: For i = m_left To m_right
    If m_mark(Y + i) = -2 Then m_pri(Y + i) = ComputeConfidence(i, j) * ComputeData(i, j)
Next i: Next j

कुछ p δΩ 3 (अंजीर देखें 3) के लिए बिंदु p पर केंद्रित एक पैच ap को देखते हुए, इसकी प्राथमिकता P (p) को गणना आत्मविश्वास ( ComputeConfidenceया, C) (पी ) और डेटा शब्द ( ComputeData, ) के उत्पाद के रूप में परिभाषित किया गया है । या डी (पी ), जहां

, कहाँ पे

| Ψp | thep का क्षेत्र है, α एक सामान्यीकरण कारक है (उदाहरण के लिए, एक विशिष्ट ग्रे-स्तरीय छवि के लिए α = 255), और np बिंदु पी में सामने δΩ के लिए एक इकाई वेक्टर ओर्थोगोनल है। प्रत्येक सीमा पैच के लिए प्राथमिकता की गणना लक्ष्य क्षेत्र की सीमा पर प्रत्येक पिक्सेल के लिए अलग पैच के साथ की जाती है।

के रूप में लागू किया गया

Private Function ComputeConfidence(ByVal i As Long, ByVal j As Long) As Double
    Dim confidence As Double
    Dim X, Y As Long

    For Y = IIf(j - Winsize > 0, j - Winsize, 0) To IIf(j + Winsize < m_height - 1, j + Winsize, m_height - 1): For X = IIf(i - Winsize > 0, i - Winsize, 0) To IIf(i + Winsize < m_width - 1, i + Winsize, m_width - 1)
        confidence = confidence + m_confid(Y * m_width + X)
    Next X: Next Y

    ComputeConfidence = confidence / ((Winsize * 2 + 1) * (Winsize * 2 + 1))
End Function

Private Function ComputeData(ByVal i As Long, ByVal j As Long) As Double
    Dim grad As CPOINT
    Dim temp As CPOINT
    Dim grad_T As CPOINT
    Dim result As Double
    Dim magnitude As Double
    Dim max As Double
    Dim X As Long
    Dim Y As Long
    Dim nn As CPOINT
    Dim Found As Boolean
    Dim Count, num As Long
    Dim neighbor_x(8) As Long
    Dim neighbor_y(8) As Long
    Dim record(8) As Long
    Dim n_x As Long
    Dim n_y As Long
    Dim tempL As Long
    Dim square As Double

    For Y = IIf(j - Winsize > 0, j - Winsize, 0) To IIf(j + Winsize < m_height - 1, j + Winsize, m_height - 1): For X = IIf(i - Winsize > 0, i - Winsize, 0) To IIf(i + Winsize < m_width - 1, i + Winsize, m_width - 1)
        If m_mark(Y * m_width + X) >= 0 Then
            Found = False
            Found = m_mark(Y * m_width + X + 1) < 0 Or m_mark(Y * m_width + X - 1) < 0 Or m_mark((Y + 1) * m_width + X) < 0 Or m_mark((Y - 1) * m_width + X) < 0
            If Found = False Then
                temp.X = IIf(X = 0, m_gray(Y * m_width + X + 1) - m_gray(Y * m_width + X), IIf(X = m_width - 1, m_gray(Y * m_width + X) - m_gray(Y * m_width + X - 1), (m_gray(Y * m_width + X + 1) - m_gray(Y * m_width + X - 1)) / 2#))
                temp.Y = IIf(Y = 0, m_gray((Y + 1) * m_width + X) - m_gray(Y * m_width + X), IIf(Y = m_height - 1, m_gray(Y * m_width + X) - m_gray((Y - 1) * m_width + X), (m_gray((Y + 1) * m_width + X) - m_gray((Y - 1) * m_width + X)) / 2#))
                magnitude = temp.X ^ 2 + temp.Y ^ 2
                If magnitude > max Then
                    grad.X = temp.X
                    grad.Y = temp.Y
                    max = magnitude
                End If
            End If
        End If
    Next X: Next Y

    grad_T.X = grad.Y
    grad_T.Y = -grad.X

    For Y = IIf(j - 1 > 0, j - 1, 0) To IIf(j + 1 < m_height - 1, j + 1, m_height - 1): For X = IIf(i - 1 > 0, i - 1, 0) To IIf(i + 1 < m_width - 1, i + 1, m_width - 1): Count = Count + 1
        If X <> i Or Y <> j Then
            If m_mark(Y * m_width + X) = -2 Then
                num = num + 1
                neighbor_x(num) = X
                neighbor_y(num) = Y
                record(num) = Count
            End If
        End If
    Next X: Next Y

    If num = 0 Or num = 1 Then
        ComputeData = Abs((0.6 * grad_T.X + 0.8 * grad_T.Y) / 255)
    Else
        n_x = neighbor_y(2) - neighbor_y(1)
        n_y = neighbor_x(2) - neighbor_x(1)
        square = CDbl(n_x ^ 2 + n_y ^ 2) ^ 0.5
        ComputeData = Abs((IIf(n_x = 0, 0, n_x / square) * grad_T.X + IIf(n_y = 0, 0, n_y / square) * grad_T.Y) / 255)
    End If
End Function

विश्वास अवधि सी (पी) को पिक्सेल पी के आसपास की विश्वसनीय जानकारी की मात्रा के माप के रूप में सोचा जा सकता है। इरादा पहले उन पैच को भरने का है जिनके पास पहले से ही अधिक पिक्सेल भरे हुए हैं, पिक्सल को दी गई अतिरिक्त वरीयता के साथ जो जल्दी भरे गए थे (या जो लक्ष्य क्षेत्र का हिस्सा कभी नहीं थे)।

यह स्वचालित रूप से भरण मोर्चे के साथ कुछ आकृतियों के लिए वरीयता को शामिल करता है। उदाहरण के लिए, पैच जिनमें लक्ष्य क्षेत्र के कोनों और पतली निविदाएं शामिल हैं, पहले भरे जाएंगे, क्योंकि वे मूल छवि से अधिक पिक्सेल से घिरे हुए हैं। ये पैच मैच के लिए अधिक विश्वसनीय जानकारी प्रदान करते हैं। इसके विपरीत, टारगेट क्षेत्र में जूटिंग से भरे हुए पिक्सल्स के "पेनिनसुलेस" के सिरे पर पैच तब तक अलग-अलग सेट होंगे जब तक कि आसपास के पिक्सल्स में से ज्यादा न भर जाए। मोटे स्तर पर, (1) का C (p) शब्द लगभग होता है। वांछनीय गाढ़ा भरने के क्रम को लागू करता है।

आय को भरने के रूप में, लक्ष्य क्षेत्र की बाहरी परतों में पिक्सल अधिक से अधिक आत्मविश्वास मूल्यों की विशेषता होगी, और इसलिए पहले से भरे जा सकते हैं; लक्ष्य क्षेत्र के केंद्र में पिक्सेल में कम आत्मविश्वास मूल्य होंगे। डेटा शब्द डी (पी) आइसोफेट्स की ताकत का एक कार्य है जो प्रत्येक पुनरावृत्ति पर सामने D को मारता है। यह शब्द एक पैच की प्राथमिकता को बढ़ाता है जो एक आइसोफोट "में बहता है"। यह कारक हमारे एल्गोरिथ्म में मौलिक महत्व का है क्योंकि यह रैखिक संरचनाओं को पहले संश्लेषित करने के लिए प्रोत्साहित करता है, और इसलिए लक्ष्य क्षेत्र में सुरक्षित रूप से प्रचारित किया जाता है। टूटी हुई रेखाएँ जुड़ती हैं, इस प्रकार दृष्टि मनोविज्ञान के "कनेक्टिविटी सिद्धांत" का एहसास होता है [7] [१ connect ]

भरण आदेश छवि गुणों पर निर्भर करता है, जिसके परिणामस्वरूप एक कार्बनिक संश्लेषण प्रक्रिया होती है जो "टूटी-संरचना" कलाकृतियों के जोखिम को समाप्त करती है और एक महंगी पैच-कटिंग चरण [9] या धब्बा-उत्प्रेरण सम्मिश्रण चरण के बिना अवरुद्ध कलाकृतियों को कम करती है [19] ] हो गया

चरण 2: बनावट और संरचना की जानकारी का प्रचार करना

भरने के मोर्चे ( सीमा ) पर सभी प्राथमिकताओं की गणना की जाने के बाद, सर्वोच्च प्राथमिकता वाला पैच ˆpities पाया जाता है। हम फिर इसे स्रोत क्षेत्र then से निकाले गए डेटा से भरते हैं। हम स्रोत क्षेत्र के प्रत्यक्ष नमूने द्वारा छवि बनावट का प्रचार करते हैं। [१०] के समान , हम उस पैच के स्रोत क्षेत्र में खोज करते हैं जो ,pˆ के समान है। औपचारिक रूप से,

, कहाँ पे

दो जेनेरिक पैच thea और generb के बीच की दूरी d (Ψa, db) को बस दो पैच में पहले से भरे पिक्सेल के वर्ग अंतर (SSD) के योग के रूप में परिभाषित किया गया है। इस चरण में कोई और विश्लेषण या हेरफेर ( विशेष रूप से कोई धुंधला नहीं ) किया जाता है। यह गणना मुख्य चक्र लूप में चलती है और इसे निम्नानुसार लागू किया जाता है:

अधिकतम प्राथमिकता प्राप्त करना:

For j = m_top To m_bottom: Jidx = j * m_width: For i = m_left To m_right
    If m_mark(Jidx + i) = -2 And m_pri(Jidx + i) > max_pri Then
        pri_x = i
        pri_y = j
        max_pri = m_pri(Jidx + i)
    End If
Next i: Next j

सबसे समान पैच ढूँढना:

min = 99999999

For j = PatchT To PatchB: Jidx = j * m_width: For i = PatchL To PatchR
    If m_source(Jidx + i) Then
        sum = 0
        For iter_y = -Winsize To Winsize: target_y = pri_y + iter_y
            If target_y > 0 And target_y < m_height Then
                target_y = target_y * m_width: For iter_x = -Winsize To Winsize: target_x = pri_x + iter_x
                    If target_x > 0 And target_x < m_width Then
                        Tidx = target_y + target_x
                        If m_mark(Tidx) >= 0 Then
                            source_x = i + iter_x
                            source_y = j + iter_y
                            Sidx = source_y * m_width + source_x
                            temp_r = m_r(Tidx) - m_r(Sidx)
                            temp_g = m_g(Tidx) - m_g(Sidx)
                            temp_b = m_b(Tidx) - m_b(Sidx)
                            sum = sum + temp_r * temp_r + temp_g * temp_g + temp_b * temp_b
                        End If
                    End If
                Next iter_x
            End If
        Next iter_y

        If sum < min Then: min = sum: patch_x = i: patch_y = j
    End If
Next i: Next j

चरण 3: आत्मविश्वास मूल्यों को अद्यतन करना

पैच के बाद ˆpˆ को नए पिक्सेल मानों से भर दिया गया है, आत्मविश्वास C (p) followsp the द्वारा सीमांकित क्षेत्र में अद्यतन किया गया है:

यह सरल अद्यतन नियम हमें छवि-विशिष्ट मापदंडों के बिना, भरने के मोर्चे पर पैच के सापेक्ष आत्मविश्वास को मापने की अनुमति देता है। आय को भरने के रूप में, आत्मविश्वास मूल्यों का क्षय होता है, यह दर्शाता है कि हम लक्ष्य क्षेत्र के केंद्र के पास पिक्सेल के रंग मूल्यों से कम सुनिश्चित हैं। यहां लागू किया गया (अन्य सभी आवश्यक अपडेट के साथ):

x0 = -Winsize
For iter_y = -Winsize To Winsize: For iter_x = -Winsize To Winsize
    x0 = patch_x + iter_x
    y0 = patch_y + iter_y
    x1 = pri_x + iter_x
    y1 = pri_y + iter_y
    X1idx = y1 * m_width + x1
    If m_mark(X1idx) < 0 Then
        X0idx = y0 * m_width + x0
        PicAr1(x1, y1) = m_color(X0idx)
        m_color(X1idx) = m_color(X0idx)
        m_r(X1idx) = m_r(X0idx)
        m_g(X1idx) = m_g(X0idx)
        m_b(X1idx) = m_b(X0idx)
        m_gray(X1idx) = CDbl((m_r(X0idx) * 3735 + m_g(X0idx) * 19267 + m_b(X0idx) * 9765) / 32767)
        m_confid(X1idx) = ComputeConfidence(pri_x, pri_y)
    End If
Next iter_x: Next iter_y

For Y = IIf(pri_y - Winsize - 2 > 0, pri_y - Winsize - 2, 0) To IIf(pri_y + Winsize + 2 < m_height - 1, pri_y + Winsize + 2, m_height - 1): Yidx = Y * m_width: For X = IIf(pri_x - Winsize - 2 > 0, pri_x - Winsize - 2, 0) To IIf(pri_x + Winsize + 2 < m_width - 1, pri_x + Winsize + 2, m_width - 1)
    m_mark(Yidx + X) = IIf(PicAr1(X, Y).rgbRed = MaskRed And PicAr1(X, Y).rgbgreen = MaskGreen And PicAr1(X, Y).rgbBlue = MaskBlue, -1, Source)
Next X: Next Y

For Y = IIf(pri_y - Winsize - 2 > 0, pri_y - Winsize - 2, 0) To IIf(pri_y + Winsize + 2 < m_height - 1, pri_y + Winsize + 2, m_height - 1): Yidx = Y * m_width: For X = IIf(pri_x - Winsize - 2 > 0, pri_x - Winsize - 2, 0) To IIf(pri_x + Winsize + 2 < m_width - 1, pri_x + Winsize + 2, m_width - 1)
    If m_mark(Yidx + X) = -1 Then
        Found = (Y = m_height - 1 Or Y = 0 Or X = 0 Or X = m_width - 1) Or m_mark(Yidx + X - 1) = Source Or m_mark(Yidx + X + 1) = Source Or m_mark((Y - 1) * m_width + X) = Source Or m_mark((Y + 1) * m_width + X) = Source
        If Found Then: Found = False: m_mark(Yidx + X) = -2
    End If
Next X: Next Y

For i = IIf(pri_y - Winsize - 3 > 0, pri_y - Winsize - 3, 0) To IIf(pri_y + Winsize + 3 < m_height - 1, pri_y + Winsize + 3, m_height - 1): Yidx = i * m_width: For j = IIf(pri_x - Winsize - 3 > 0, pri_x - Winsize - 3, 0) To IIf(pri_x + Winsize + 3 < m_width - 1, pri_x + Winsize + 3, m_width - 1)
    If m_mark(Yidx + j) = -2 Then m_pri(Yidx + j) = ComputeConfidence(j, i) * ComputeData(j, i)
Next j: Next i

पूरा कोड

यहां पुस्तकालयों के स्रोत कोड के साथ टिप्पणियों के रूप में रन-सक्षम कोड है।

कोड द्वारा लागू किया गया है

inpaint(infile, outfile, blocksize, windowsize, r, g, b)

उदाहरण के रूप में शामिल हैं

;~ inpaint("gothic_in.png", "gothic_out.png")
;~ inpaint("starry_in.png", "starry_out.png")
;~ inpaint("scream_in.png", "scream_out.png")
;~ inpaint("mona_in.png", "mona_out.png")
;~ inpaint("maze_in.png", "maze_out.png")
;~ inpaint("checker_in.png", "checker_out.png")

केवल उस उदाहरण को अनइंस्टॉल करें जिसे आप CTRL+ का उपयोग करके चलाना चाहते हैं Q

आधिकारिक टेस्ट फाइलें

इस एल्गोरिथ्म है बनाया प्रत्येक छवि के लिए समायोजित करने की। इसलिए, डिफ़ॉल्ट मान (और डिफ़ॉल्ट मास्क भी) पूरी तरह से सब-ऑप्टिमल हैं। डिफ़ॉल्ट मानों को चुना जाता है ताकि प्रत्येक नमूने को उचित समय में संसाधित किया जा सके। मैं अनियमित आकार के मुखौटे और बेहतर खिड़की के आकार के साथ खेलने की सलाह देता हूं। बड़ी करने के लिए इमेज़ पर क्लिक करें!

बिसात

अमेरिकन गोथिक

भूल भुलैया

मोना लीसा

(भयानक मुखौटा)

चीख

तारों से जड़ा

वास्तविक-विश्व उदाहरण

ये सभी कस्टम हाथ से तैयार मास्क का उपयोग करते हैं।

यदि आपके पास अन्य दिलचस्प छवियां हैं जिन्हें आप शामिल करना चाहते हैं, तो एक टिप्पणी छोड़ दें।

EBII सुधार

EBII के कई संस्करण हैं, जो विभिन्न शोधकर्ताओं द्वारा बनाए गए हैं। अंकुरकुमार पटेल ने विभिन्न ईबीआईआई सुधारों पर अपने पत्रों के संग्रह [24] के साथ मेरा ध्यान आकर्षित किया ।

विशेष रूप से कागज़ " बेहतर आधारित एल्गोरिथ्म फॉर एग्जम्पलर बेस्ड इमेज इनपैनटिंग " [२५] में प्राथमिकता के मूल्यों के वज़न पर दो सुधारों का उल्लेख है।

सुधार

प्रभावी संशोधन एल्गोरिथ्म के चरण 1 (ऊपर देखें) में है, और इस का उपयोग करके इस पिक्सेल के लिए प्राथमिकता रेटिंग पर सी (पी) और डी (पी) प्रभाव का विस्तार करता है :

सी और डी के लिए ऊपर दिए गए सूत्र में , और क्रमशः सामान्यीकरण कारक (जैसे, α = 255), आइसोफोट वेक्टर, और इकाई वेक्टर ऑर्थोगोनल बिंदु p में सामने की ओर हैं।

आगे की,

प्राथमिकता समारोह को नियमित आत्मविश्वास शब्द सी (पी) और नए डेटा शब्द डी (पी) के वजन योग के रूप में परिभाषित किया गया है । जहां α समायोजन गुणांक है, संतोषजनक 0 आरपी (पी) को परिभाषित किया गया है:

जहां α और the क्रमशः विश्वास और डेटा शर्तों के घटक भार हैं। ध्यान दें कि α + β = 1

उद्देश्य स्कोरिंग

हालांकि यह वास्तव में दिलचस्प है कि इस पेपर में EBII एल्गोरिदम के प्रदर्शन को बढ़ाने के लिए एक प्रस्तावित (और सरल!) विधि है। नमक के एक दाने के साथ इसे लें, क्योंकि यह प्रस्तावित लेखकों के दृष्टिकोण और कई छवियों पर सुधार की प्रभावशीलता को सत्यापित करने के लिए खुद को कागज लेखकों द्वारा चुना गया एक तरीका है।

परिणाम का मूल्यांकन पुनश्च छवि और मूल छवि के बीच PSNR (पीक सिग्नल-टू-शोर अनुपात [26] ) की तुलना करके किया जाता है। आम तौर पर PSNR जितना अधिक होता है, उतनी ही बड़ी छवि की समानता मूल में होती है। PSNR की गणना करने के लिए समीकरण इस प्रकार है:

ये चौंका देने वाले 2 (दो!) वास्तविक-विश्व परीक्षण चित्र हैं जिनका उन्होंने उपयोग किया है:

निष्कर्ष कागज की गुणवत्ता के समान ही निराशाजनक है। यह बहुत कम सुधार दिखाता है। इस तरह की चुनौती (और अन्य छवि-मरम्मत की चुनौतियों) के लिए यहां मुख्य बात एक संभावित वस्तु स्कोरिंग विधि है:

+-------+---------------+----------+
| Image | EBII Original | Improved |
+-------+---------------+----------+
|     1 |       52.9556 |  53.7890 |
|     2 |       53.9098 |  53.8989 |
+-------+---------------+----------+

भावहीन।

अनुसंधान किया जाना है

(EBII के लिए विशिष्ट)

क) पूर्व प्रसंस्करण

सब कुछ "मैजिक इरेज़" सिद्धांत पर आता है कि एल्गोरिथ्म को हर चीज़ के लिए "बस काम" करना चाहिए। इसके लिए मेरा अनुभवहीन समाधान एक रंग-आधारित प्रवर्धन है (ऊपर देखें), लेकिन बेहतर तरीके हैं। मैं सभी ट्रेस करने योग्य टेक्सल्स के ज्यामितीय माध्य को विंडो आकार को ऑटो-एडजस्ट करने और स्टैम्प आकार (मेरा सुधार) को टेक्सल- और संपूर्ण-छवि रिज़ॉल्यूशन पर निर्भर बनाने के बारे में सोच रहा हूँ । यहां शोध किया जाना है।

बी) पोस्ट-प्रोसेसिंग

मूल लेखकों ने पहले से ही सभी पोस्ट प्रोसेसिंग फ़िल्टर को ध्यान में रखते हुए शानदार काम किया। आज, मैंने हमेशा अचेतन मोना लिसा (धन्यवाद भूमिगत) से प्रेरित होकर कुछ और करने की कोशिश की। यदि आप सिर्फ एक अभेद्य क्षेत्र लेते हैं और रंग के सभी अजीब ब्लॉकों में एक नया मुखौटा लागू करते हैं और इसे एक निराशाजनक एल्गोरिथ्म में खिलाते हैं, तो आपको लगभग पूर्ण परिणाम के साथ छोड़ दिया जाता है। मैं भविष्य में कुछ समय तक इसका पता लगा सकता हूं।


[X] - ए। क्रिमिनिसी, पी। पेरेज़, के। टोमामा
[1] - एम। एशिखमीन द्वारा एक्समप्लेयर-बेस्ड इनपैनटिंग द्वारा ऑब्जेक्ट रिमूवलप्राकृतिक बनावट का संश्लेषण करना। प्रोक में। ACM सिम्प। इंटरएक्टिव 3 डी ग्राफिक्स, पीपी 217–226, रिसर्च ट्राएंगल पार्क, नेकां, मार्च 2001।
[5] - एम। बर्टाल्मियो, एल। वेस, जी। सैपिरो, और एस। ओशर। एक साथ संरचना और बनावट छवि inpainting। दिखाई देने के लिए, 2002
[6] - आर। बॉर्नार्ड, ई। लेकन, एल। लेबरेली और जेएच। Chenot। अभी भी छवियों और छवि दृश्यों में डेटा सुधार गायब है। एसीएम मल्टीमीडिया, फ्रांस में, दिसंबर 2002.
[7] - टीएफ चान और जे। शेन। वक्रता-चालित विक्षेप (CDD) द्वारा गैर-बनावट की अशुद्धता। जे विजुअल कॉम। छवि प्रतिनिधि।, 4 (12), 2001।
[[] - जेएस डी बोनेट। बनावट चित्रों के विश्लेषण और संश्लेषण के लिए बहुक्रिया नमूनाकरण प्रक्रिया। प्रोक में। ACM आत्मविश्वास। अनि। ग्राफिक्स (SIGGRAPH), खंड 31, पीपी। 361-368, 1997.
[9] - ए। एफ्रोस और डब्ल्यूटी फ्रीमैन। बनावट संश्लेषण और हस्तांतरण के लिए छवि रजाई। प्रोक में। ACM आत्मविश्वास। अनि। ग्राफिक्स (SIGGRAPH), पीपी। 341-346, यूजीन फिमे, 2001 अगस्त।
[10] - ए। एफ्रोस और टी। लेउंग। गैर-पैरामीट्रिक नमूना द्वारा बनावट संश्लेषण। प्रोक में। ICCV, पीपी। 1033–1038, केर्किरा, ग्रीस, 1999 सितंबर।
[11] - डब्ल्यूटी फ्रीमैन, ईसी पासज़्टर, और ओटी कारमाइकल। निम्न स्तर की दृष्टि सीखना। इंट। जे। कंप्यूटर विजन, 40 (1): 25-47, 2000.
[12] - डी। गर्बर। बनावट विश्लेषण और बनावट संश्लेषण के लिए कम्प्यूटेशनल मॉडल। पीएचडी थीसिस, यूनीव। दक्षिणी कैलिफोर्निया, संयुक्त राज्य अमेरिका, 1981।
[१३] - पी। हैरिसन जटिल बनावट के पुन: संश्लेषण के लिए एक गैर-पदानुक्रमित प्रक्रिया। प्रोक में। इंट। सम्मेलन। मध्य यूरोप COMP। ग्राफिक्स, विशुआ। और COMP। विज़न, प्लज़ेन, चेक रिपब्लिक, फरवरी 2001।
[14] - डीजे हीगर और जेआर बर्गन। पिरामिड-आधारित बनावट विश्लेषण / संश्लेषण। प्रोक में। ACM आत्मविश्वास। अनि। ग्राफिक्स (SIGGRAPH), खंड 29, पीपी। 229–233, लॉस एंजिल्स, CA, 1995.
[15] - ए। हर्ट्ज़मैन, सी। जैकब्स, एन। ओलिवर, बी। कर्ललेस, और डी। सेल्सिन। छवि उपमाएँ। प्रोक में। ACM आत्मविश्वास। अनि। ग्राफिक्स (SIGGRAPH), यूजीन
फिमे , 2001 अगस्त। [16] - एच। इगेही और एल। परेरा। बनावट संश्लेषण के माध्यम से छवि प्रतिस्थापन। प्रोक में। इंट। सम्मेलन। इमेज प्रोसेसिंग, पीपी। III: 186-190, 1997.
[17] - जी कनीज़सा। दृष्टि में संगठन। प्रेगर, न्यूयॉर्क, 1979।
[१ ९] - एल। लिआंग, सी। लिउ, वाई.- क्यू। जू, बी। गुओ, और एच। वाई। शुम। पैच-आधारित नमूने द्वारा वास्तविक समय बनावट संश्लेषण। ग्राफिक्स पर ACM लेनदेन में, 2001.
[22] - एल.डब्ल्यू। वी और एम। लेवोय। वृक्ष-संरचित वेक्टर परिमाणीकरण का उपयोग करके तेज बनावट संश्लेषण। प्रोक में। ACM आत्मविश्वास। अनि। ग्राफिक्स (SIGGRAPH), 2000.
[23] - ए। ज़लेसनी, वी। फेरारी, जी। केन और एल। वैन गूल। समानांतर समग्र बनावट संश्लेषण। बनावट में 2002 कार्यशाला -, कोपेनहेगन, डेनमार्क (ECCV02 के साथ) का जून 2002
[24] - AkurKumar पटेल, गुजरात प्रौद्योगिकी विश्वविद्यालय, कंप्यूटर विज्ञान और इंजीनियरिंग
[25] - कापी आधारित छवि Inpainting के लिए बेहतर मजबूत एल्गोरिथ्म
[26] - विकिपीडिया, पीक-सिग्नल-टू-शोर-अनुपात


30
यह कमाल है । तारों वाली रात कितनी अच्छी है। फिर भी, कि मोना लिसा ...
हेंस कारपिला

8
पहले मुझे कहने दो "हे भगवान यह अविश्वसनीय है"। दूसरा: मैंने पहले ही टिप्पणी की है कि "मोना लिसा कुछ एससीपी बकवास है" यहां एक और सवाल है, लेकिन यह उल्लू वास्तव में कुछ ऐसा दिखता है जो एससीपी विकी पर दिखाई दे सकता है।
अंडरग्राउंडोरैल

3
आपके द्वारा उल्लेखित उद्धरण पैराग्राफ को उद्धरण ब्लॉक बनाया जा सकता है?
ट्राइकोप्लाक्स

1
@trichoplax लगभग हर वाक्य में मामूली संशोधन हैं, वे सटीक उद्धरण नहीं हैं। एल्गोरिथ्म विवरण पर विचार करें कि ओआरजी के समान ही है। जब यह संशोधन या कोड कहता है तो सिवाय कागज के। मैं किसी भी अधिक स्वरूपण को अव्यवस्थित नहीं करना चाहता हूं :)
mnnxoma

2
जब मैंने अपने सपनों में बहुत ध्यान से कुछ देखने की कोशिश की, तो कभी-कभी चीजें बिल्कुल ऐसी ही हो जाती हैं।
jimmy23013

45

Matlab

यह एक सरल प्रक्षेप दृष्टिकोण है। विचार पहली बार यह दिखा रहा है कि पैच के प्रत्येक पक्ष पर क्या है। फिर उन दर्पण छवि पिक्सेल को इस बात से प्रक्षेपित किया जाता है कि वे किनारे के कितने करीब हैं:

मुश्किल हिस्सा एक अच्छा प्रक्षेप वजन मिल रहा था। चारों ओर कुछ खेलने के बाद मैं एक तर्कसंगत फ़ंक्शन के साथ आया जो सभी किनारों पर शून्य है, जहां हम उस पर प्रतिबिंबित करते हैं। यह तब कुछ चौरसाई के लिए एक तीसरी डिग्री बहुपद द्वारा बदल दिया जाता है:

यह सरल दृष्टिकोण "प्राकृतिक" छवियों पर आश्चर्यजनक रूप से अच्छा करता है, लेकिन जैसे ही आप तेज किनारों के साथ सामना करते हैं, खेल खत्म हो जाता है। में अमेरिकी गॉथिक उदाहरण घास कांटा लाइन अप अच्छी तरह से पिक्सेल ग्रिड, जो इसे काफी अच्छे लग रहे बनाता है के साथ की कीलें, लेकिन यह भी बदतर नहीं तो हो गया होता।

तो यहाँ परिणाम:

और अंत में, कोड:

imgfile= 'filename.png';
maskfile = [imgfile(1:end-4),'_mask.png'];
img = double(imread(imgfile));
mask = rgb2gray(imread(maskfile));
%% read mask
xmin = find(sum(mask,1),1,'first');
xmax = find(sum(mask,1),1,'last');
ymin = find(sum(mask,2),1,'first');
ymax = find(sum(mask,2),1,'last');
%% weight transformation functiosn
third = @(x)-2* x.^3 + 3* x.^2;
f=@(x)third(x);
w=@(x,y)y.*(x-1).*(y-1)./( (x+y).*(x+1-y));

for x=xmin:xmax
    for y=ymin:ymax
        %Left Right Up Down;
        P = [img(y,xmin-(x-xmin)-1,:);img(y,xmax+(xmax-x)+1,:);img(ymin-(y-ymin)-1,x,:);img(ymax+(ymax-y)+1,x,:)];
        % normalize coordinates
        rx = (x-xmin)/(xmax-xmin); 
        ry = (y-ymin)/(ymax-ymin);
        % calculate the weights
        W = [w(rx,ry),w(1-rx,ry),w(ry,rx),w(1-ry,rx)]';
        W = f(W);
        W(isnan(W))=1;
        img(y,x,:) = sum(bsxfun(@times,P,W),1)/sum(W); 
    end
end
imshow(img/255);
imwrite(img/255,[imgfile(1:end-4),'_out.png']);

10
मोना लिसा ने मुझे बाहर कर दिया।
एंड्रास डीक

46
Ḿ̳̜͇͓͠ơ̥͕̱͋͌aḾ̳̜͇͓͠ ̣̖̠̮̘̹̠̾̇ͣL͉̻̭͌iḾ̳̜͇͓͠ş m
mınxoma

8
वह मोना लिसा कुछ SCP बकवास है
भूमिगत

1
चेकर की छवि वास्तव में शांत IMHO लगती है।
ETHproductions

1
मुझे आश्चर्य नहीं होगा अगर आपने इसके साथ अपनी चुनौती जीती। यह एक बहुत अच्छा समाधान है।
एलेक्स ए।

25

मेथेमेटिका

यह Mathematica के Inpaintफ़ंक्शन का उपयोग करता है । क्योंकि गणितज्ञ ही सभी भारी उठाने का काम करता है, यह एक सामुदायिक विकी है।

inPaint(नीचे) का एक सरल अनुकूलन है Inpaint। रंगीन चित्रों / तस्वीरों के लिए, यह डिफ़ॉल्ट, "टेक्सचरसिंथेसिस", सेटिंग का उपयोग करता है। यदि यह पता लगाता है कि चित्र काला और सफेद है (क्योंकि चित्र का छवि डेटा चित्र के द्विआधारी रूप की छवि डेटा के समान है), तो यह छवि को दूर करता है और "TotalVariation" पैच को लागू करता है। Ifखंड या तो लागू होता है Binarizeया Identityतस्वीर के लिए। ( Identityफ़ंक्शन अपने तर्क को अपरिवर्तित लौटाता है।)

inPaint[picture_, mask_] :=  
 If[bw = ImageData@Rasterize[Binarize[picture]] == ImageData[picture], Binarize, Identity]@
  Inpaint[picture, mask, Method -> If[bw, "TotalVariation", "TextureSynthesis"]]

छवि और मुखौटा को तर्क के रूप में दर्ज किया जाता है inPaintPartitionऔर Gridकेवल स्वरूपण प्रयोजनों के लिए हैं।

इनपुट

आउटपुट को पैच किया गया है। के बाद छवियों का कोई पुन: चयन नहीं किया गया था inPaint

उत्पादन


4
यह एक संयोग हो सकता है, लेकिन मैं भूलभुलैया के प्रदर्शन के बारे में चकित हूं!
दोष

1
@flawr मैं कुछ इस तरह से इस समाधान के साथ खिलवाड़ करने के लिए फेंक दूंगा ;) (कौन जानता है? वे काले-गोरे वास्तव में चकरा रहे हैं।)
एंड्रास डीक

17
मुझे नहीं लगता कि यह एक सामुदायिक विकि होना चाहिए।
डेनिस

लॉर, हाँ, Inpaintपूरे काले और सफेद छवि में समरूपता की तलाश करता है। - DavidC 9 घंटे पहले
DavidC

क्या आप सुनिश्चित हैं कि ब्लैक-एंड-व्हाइट एल्गोरिदम में कहीं भी बकरों की बलि नहीं दी जाती है? कैसे --- पृथ्वी पर --- यह छवि की केंद्रीय संरचना का अनुमान लगाता है, अगर यह सब नकाबपोश है ??
एंड्रास डीक

18

अजगर 2 और पीआईएल

यह कार्यक्रम स्थानीय छवि क्षेत्र से रंग, बनावट और छायांकन का उपयोग करने वाले प्रतिस्थापन पिक्सेल बनाने के लिए उत्तर, दक्षिण, पूर्व और पश्चिम के क्षेत्रों की प्रतियों को मिश्रित करता है।

उदाहरण आउटपुट:

कोड पहले पैच के लिए बाउंडिंग बॉक्स पाता है। फिर प्रत्येक पिक्सेल को उत्पन्न करने के लिए, यह 4 चैनल के आसपास के क्षेत्रों के भारित योग के आधार पर प्रत्येक चैनल (RGB) के रंग की गणना करता है।

import sys
from PIL import Image

infile, maskfile, outfile = sys.argv[1:4]
imageobj = Image.open(infile)
maskobj = Image.open(maskfile)
image = imageobj.load()
mask = maskobj.load()

assert imageobj.size == maskobj.size
W, H = imageobj.size
pixels = [(x,y) for x in range(W) for y in range(H)]
whitepart = [xy for xy in pixels if sum(mask[xy]) > 230*3]
xmin = min(x for x,y in whitepart)
xmax = max(x for x,y in whitepart)
ymin = min(y for x,y in whitepart)
ymax = max(y for x,y in whitepart)
xspan = xmax - xmin + 1
yspan = ymax - ymin + 1

def mkcolor(channel):
    value = image[(xmin-dx, y)][channel] * 0.5*(xspan - dx)/xspan
    value += image[(xmax+1 + xspan - dx, y)][channel] * 0.5*dx/xspan
    value += image[(x, ymin-dy)][channel] * 0.5*(yspan - dy)/yspan
    value += image[(x, ymax+1 + yspan - dy)][channel] * 0.5*dy/yspan
    return int(value)

for dx in range(xspan):
    for dy in range(yspan):
        x = xmin + dx
        y = ymin + dy
        image[(x, y)] = (mkcolor(0), mkcolor(1), mkcolor(2))

imageobj.save(outfile)

3
यह मोना लिसा भी भयानक है! क्या इस चुनौती में सभी मोना लिसा डरावना हैं?
अंडरग्राउंडोरेल

@undergroundmonorail मुझे लगता है कि कंप्यूटर से उत्पन्न होने वाले आकस्मिक चेहरे अनजान घाटी की गहराई से सही आते हैं ।
एंड्रास डेक

आपको पीआईएल कहां से मिलेगा?
इलियट ए।

@ElliotA। मेरी समझ यह है कि पीआईएल उचित मृत है, लेकिन यह खुला स्रोत था और इसलिए यह "तकिया" नाम पर रहता है। यदि आप "पाइथन तकिया" Google करते हैं, तो आपको इसे ढूंढना चाहिए।
अंडरग्राउंडोरैल

13

अजगर 3, पीआईएल

यह प्रोग्राम sobel ऑपरेटर का उपयोग करता है, और उस पर आधारित चित्र पर रेखाएँ खींचता है।

सोबेल ऑपरेटर प्रत्येक किनारे के कोण का पता लगाता है, इसलिए किसी भी क्षेत्र को अज्ञात क्षेत्र में बाहर निकालना जारी रखना चाहिए।

from PIL import Image, ImageFilter, ImageDraw
import time
im=Image.open('2.png')
im1=Image.open('2 map.png')
a=list(im.getdata())
b=list(im1.getdata())
size=list(im.size)
'''
def dist(a,b):
    d=0
    for x in range(0,3):
        d+=(a[x]-b[x])**2
    return(d**0.5)
#'''
C=[]
d=[]
y=[]
for x in range(0,len(a)):
    if(b[x][0]==255):
        C.append((0,0,0))
    else:
        y=(a[x][0],a[x][1],a[x][2])
        C.append(y)
im1.putdata(C)
k=(-1,0,1,-2,0,2,-1,0,1)
k1=(-1,-2,-1,0,0,0,1,2,1)
ix=im.filter(ImageFilter.Kernel((3,3),k,1,128))
iy=im.filter(ImageFilter.Kernel((3,3),k1,1,128))
ix1=list(ix.getdata())
iy1=list(iy.getdata())
d=[]
im2=Image.new('RGB',size)
draw=ImageDraw.Draw(im2)
c=list(C)
Length=0
for L in range(100,0,-10):
    for x in range(0,size[0]):
        for y in range(0,size[1]):
            n=x+(size[0]*y)
            if(c[n]!=(0,0,0)):
                w=(((iy1[n][0]+iy1[n][1]+iy1[n][2])//3)-128)
                z=(((ix1[n][0]+ix1[n][1]+ix1[n][2])//3)-128)
                Length=(w**2+z**2)**0.5
                if Length==0:
                    w+=1
                    z+=1
                Length=(w**2+z**2)**0.5
                w/=(Length/L)
                z/=(Length/L)
                w=int(w)
                z=int(z)
                draw.line(((x,y,w+x,z+y)),c[n])

d=list(im2.getdata())
S=[]
d1=[]
A=d[0]
for x in range(0,size[0]):
    for y in range(0,size[1]):
        n=y+(size[1]*x)
        nx=y+(size[1]*x)-1
        ny=y+(size[1]*x)-size[0]
        if d[n]==(0,0,0):
            S=[0,0,0]
            for z in range(0,3):
                S[z]=(d[nx][z]+d[ny][z])//2
            #print(S)
            d1.append(tuple(S))
        else:
            d1.append(tuple(d[n]))
d=list(d1)
im2.putdata(d)
#im2=im2.filter(ImageFilter.GaussianBlur(radius=0.5))
d=im2.getdata()
f=[]
#'''
for v in range(0,len(a)):
    if(b[v][0]*b[v][1]*b[v][2]!=0):
        f.append(d[v])
    else:
        f.append(C[v])
#'''
im1.putdata(f)
im1.save('pic.png')

इस बीच, यहाँ नमूना चित्र हैं।

यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें

मोना लिसा मोना लिसा ǹ̰͎̣o La isaLisa ̢̎̓̀ǹ̰͎̣oͧ̈ͤaisa ̣̖̠̮̘̹̠̾̇ͣLisa ̤̩̖̞̝ͧ̈ͤͤọ̖̠̮̘̹̠̾̇ͣaḾ̳̜͇͓͠ ̢̎̓̀ǹ̰͎̣͙L͉̻̭͌i̛̥͕̱͋͌şa

यहां छवि विवरण दर्ज करें उपरोक्त छवि का क्षेत्र कैक्टस जितना चिकना है

यह लगातार रंग के साथ बहुत अच्छा नहीं है।

यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें


1
ओह, और क्या आप बी / डब्ल्यू परीक्षण मामलों को जोड़ सकते हैं?
दोष

2
स्टार्स नाइट वन पर वास्तव में अच्छा लग रहा है।
SuperJedi224

1
वाह, यह अब अविश्वसनीय लग रहा है! पैच अभी भी ध्यान देने योग्य हैं लेकिन एक महान नए विचार हैं! मेरा पसंदीदा अब तक =)
दोष

8
+1 के लिए "मोना लिसा मोना लिसा ̾̇o̾̇a isaLisa ̢̎̓̀ǹ̰͎̣o̢̎̓̀ǹ̰͎̣aͧ̈ͤ ̢̎̓̀ǹ̰͎̣͙Lisa isaoisaa̤̩̖̞̝ͧ̈ͤͤ ̣̖̠̮̘̹̠̾̇ͣL͉̻̭͌i̛̥͕̱͋͌ş̠͔̏̋̀ạ̫͕͎ͨͮͪ̐͡ͅ"
mbomb007

2
आप "स्केरेस्ट मोना लिसा" प्रतियोगिता, आईएमओ जीतते हैं। 0_o
DLosc

8

अजगर २

सिंपल पाइथन स्क्रिप्ट जो केवल बाहरी गैप से पिक्सल से वैल्यू का उपयोग करके पैच बनाता है। यह पिक्सेल की पंक्ति और स्तंभ के अंत से रंग मान लेता है और उन पिक्सेल से दूरी का उपयोग करके भारित औसत की गणना करता है।

आउटपुट इतना सुंदर नहीं है, लेकिन यह कला है

img1 img2 img3 img4 img5 img6

और फिर, कोड:

IMGN = "6"

IMGFILE = "images/img%s.png" % (IMGN,)
MASKFILE = "images/img%s_mask.png" % (IMGN,)

BLUR = 5


def getp(img,pos):
    return img.get_at(pos)[:3]
def setp(img,pos,color):
    img.set_at(pos, map(int, color))

def pixelavg(L):
    return map(int, [sum([i[q] for i in L])/float(len(L)) for q in [0,1,2]])
def pixelavg_weighted(L, WL):   # note: "inverse" weights. More weight => less weight
    # colors [sum, max]
    color_data = [[0, 0], [0, 0], [0, 0]]
    for color,weight in zip(L, WL):
        for i in [0, 1, 2]: # r,g,b
            color_data[i][0] += inv_w_approx(weight) * color[i]
            color_data[i][1] += inv_w_approx(weight) * 255
    return [255*(float(s)/m) for s,m in color_data]
def inv_w_approx(x):
    return (1.0/(x+1e-10))

import pygame
image = pygame.image.load(IMGFILE)
mask = pygame.image.load(MASKFILE)

size = image.get_size()
assert(size == mask.get_size())

# get square from mask
min_pos = None
max_pos = [0, 0]
for x in range(size[0]):
    for y in range(size[1]):
        if getp(mask, [x, y]) == (255, 255, 255):
            if min_pos == None:
                min_pos = [x, y]
            max_pos = [x, y]
if not min_pos:
    exit("Error: no mask found.")
# patch area info
patch_position = min_pos[:]
patch_size = [max_pos[0]-min_pos[0], max_pos[1]-min_pos[1]]

# remove pixels from orginal image (fill black)
for dx in range(patch_size[0]):
    for dy in range(patch_size[1]):
        setp(image, [patch_position[0]+dx, patch_position[1]+dy], [0, 0, 0])

# create patch
patch = pygame.Surface(patch_size)

# take pixels around the patch
top = [getp(image, [patch_position[0]+dx, patch_position[1]-1]) for dx in range(patch_size[0])]
bottom = [getp(image, [patch_position[0]+dx, patch_position[1]+patch_size[1]+1]) for dx in range(patch_size[0])]
left = [getp(image, [patch_position[0]-1, patch_position[1]+dy]) for dy in range(patch_size[1])]
right = [getp(image, [patch_position[0]+patch_size[0]+1, patch_position[1]+dy]) for dy in range(patch_size[1])]

cpixels = top+left+right+bottom

# set area to average color around it
average = [sum([q[i] for q in cpixels])/float(len(cpixels)) for i in [0, 1, 2]]

for dx in range(patch_size[0]):
    for dy in range(patch_size[1]):
        setp(patch, [dx, dy], average)

# create new pixels
for dx in range(patch_size[0]):
    for dy in range(patch_size[1]):
        setp(patch, [dx, dy], pixelavg_weighted([top[dx], bottom[dx], left[dy], right[dy]], [dy, patch_size[1]-dy, dx, patch_size[0]-dx]))

# apply patch
for dx in range(patch_size[0]):
    for dy in range(patch_size[1]):
        setp(image, [patch_position[0]+dx, patch_position[1]+dy], getp(patch, [dx, dy]))

# blur patch?
for r in range(BLUR):
    for dx in range(patch_size[0]):
        for dy in range(patch_size[1]):
            around = []
            for ddx in [-1,0,1]:
                for ddy in [-1,0,1]:
                    around.append(getp(image, [patch_position[0]+dx+ddx, patch_position[1]+dy+ddy]))
            setp(patch, [dx, dy], pixelavg(around))

    # apply blurred patch
    for dx in range(patch_size[0]):
        for dy in range(patch_size[1]):
            setp(image, [patch_position[0]+dx, patch_position[1]+dy], getp(patch, [dx, dy]))

# save result
pygame.image.save(image, "result.png")

फिलहाल आप उन क्षैतिज / ऊर्ध्वाधर धारियों को देखते हैं, शायद आप अन्य दिशाओं को शामिल करके इसे सुधार सकते हैं!
23

मैंने वास्तव में इसकी कोशिश की थी, लेकिन मैं अच्छे परिणाम प्राप्त करने में असमर्थ था, इसलिए मैंने सिर्फ छवि को धुंधला करने का फैसला किया: डी
हैनेस करपिला

19
अंत में, एक मोना लिसा जो मुझे मौत से नहीं डराती है, बल्कि एक गिरफ्तार हत्यारे की तरह दिखती है।
एंड्रास डीक

6

मेथेमेटिका

Inpaint

यह सिर्फ इतना होता है कि मैथेमेटिका में एक अंतर्निहित कार्य होता है जो वास्तव में इस कार्य को करता है, और मेरा वास्तव में मतलब है :

Inpaint[image, region]

  • imageउस के कुछ हिस्सों को गैर-तत्वों के अनुरूप करता है region

डिफ़ॉल्ट रूप से यह "बेसिक-फिट टेक्सटाइल सिंथेसिस मेथड का उपयोग करके रैंडम सैंपलिंग" का उपयोग करता है, जो चित्रों पर अच्छे परिणाम देता है, लेकिन भूलभुलैया और बिसात के लिए खराब परिणाम देता है:

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

सेटिंग्स के साथ खेलने से मुझे सभी चित्रों में गुणवत्ता में वृद्धि नहीं हुई, इसलिए मैंने सिर्फ डिफॉल्ट्स (बाइट्स बचाने के लिए - यह codegolf.seसब के बाद है!) का इस्तेमाल किया।


23
" यह सिर्फ इतना होता है कि गणितज्ञ का एक अंतर्निहित कार्य होता है " ... आश्चर्य, आश्चर्य;)
एंड्रास डीक

भूलभुलैया और चेकर बोर्ड के लिए "टोटल वेरिएशन" विधि का उपयोग करना बेहतर है Binarize(ग्रे स्मूदी को खत्म करने के लिए)। इसे methods = {"TextureSynthesis", "Diffusion", "FastMarching", "NavierStokes", "TotalVariation"};g[pic_, mask_] := Join[{Labeled[Framed@pic, "Original"]}, Labeled[ Binarize@Inpaint[pic, mask, Method -> #], #] & /@ methods]
आजमाइए

@ डेविड मैंने अन्य तरीकों की कोशिश की, लेकिन केवल TextureSynthesisचित्रों पर अच्छा लग रहा है; और मुझे नहीं लगता कि हमें प्रत्येक व्यक्तिगत परीक्षण मामले के लिए हमारी सेटिंग्स को ट्यून करने की अनुमति है। (यदि हम कर सकते हैं, तो हम '' सेटिंग '' के रूप में लापता हिस्से की तुच्छ आपूर्ति कर सकते हैं।)
2012rcampion

भूलभुलैया और चेकरबोर्ड परिणाम वास्तव में मेरे लिए हैरान करने वाले हैं। क्यों Mathematica लापता क्षेत्र के पुनर्निर्माण इतना अनियमित और असममित है?
डेविड झांग

यह स्वचालित रूप से पता लगाएगा कि क्या एक छवि काली और सफेद है और उचित समायोजन (बायनेरिज़ और "टोटल वेरिएशन" विधि) करें। inPaint[picture_, mask_] := If[bw = ImageData@Rasterize[Binarize[picture]] == ImageData[picture], Binarize, Identity]@ Inpaint[picture, mask, Method -> If[bw, "TotalVariation", "TextureSynthesis"]]
डेविड जेन्स

5

python3

यह उत्तर "डीप इमेज प्रायर" पेपर में विचार को लागू करता है Ulyanov एट अल द्वारा । (सीवीपीआर 2018) इस पत्र में उन्होंने इस विचार का पता लगाया कि जिस तरह से छवि प्रसंस्करण के लिए तंत्रिका जाल का अच्छा प्रदर्शन किया गया है वह हमारे विचार को दर्शाता है कि प्राकृतिक छवि को क्या देखना चाहिए ("पूर्व" वितरण)।

उन्होंने एक ऐसी विधि का प्रस्ताव किया जिसका उपयोग अशुद्धि के साथ-साथ शोर और विरूपण साक्ष्य हटाने के लिए भी किया जा सकता है जो किसी अन्य डेटा पर बिना किसी प्रशिक्षण के दिए गए चित्र का उपयोग करता है। वास्तविक अवधारणा काफी सरल है: नेट को कुछ दिए गए मुखौटे के बाहर केवल इरोस को दंडित करके वांछित छवि (इनपुट के रूप में कुछ निश्चित यादृच्छिक शोर के लिए) आउटपुट के लिए प्रशिक्षित किया जाता है। यदि आप शोर को दूर करना चाहते हैं, तो आपको कुछ भी करने की आवश्यकता नहीं है, लेकिन प्रशिक्षण के दौरान बस रुक जाएं।

Inpainting के लिए आप उस हिस्से को मास्क करते हैं जिसे आप अभिसरण तक चाहते हैं और अभिसरण तक प्रशिक्षित करते हैं। यह निश्चित रूप से अत्याधुनिक नहीं है, लेकिन मैं अभी भी इसे आज़माना चाहता था और विचार की सरलता और अभी भी उल्लेखनीय प्रदर्शन के कारण इसे यहाँ पोस्ट करना चाहता था। मेरे प्रयोगों में बड़े पैचों की अशुद्धि को अच्छी तरह से नहीं निकला, लेकिन छोटे खंडों के लिए परिणाम बहुत अधिक आश्वस्त कर सकते हैं।

मैंने इसे लोकप्रिय यू-नेट आर्किटेक्चर का उपयोग करके जीथ्यूब पर जुक्सनी से लागू किया । छवियों के प्रशिक्षण और प्रसंस्करण के लिए कोड नीचे पाया जा सकता है।

प्रशिक्षण

यह प्रशिक्षण प्रक्रिया का एक दृश्य है। प्रत्येक फ्रेम एक पुनरावृत्तियों की एक निश्चित संख्या के राज्य है:

उदाहरण

कोड

ध्यान दें कि एक सीपीयू पर केवल एक छवि के लिए चलने में घंटों लग सकते हैं, जबकि एक अच्छा कोडा सक्षम जीपीयू बहुत कम समय ले सकता है।

import torch
import numpy as np
unet = __import__('unet-pytorch')
import PIL.ImageOps
#specify device (cpu/cuda)
device = "cpu"
#specify file and size
file = 'mona'
size = 512 #pad to this size (no smaller than original image), must be divisible by 2^5
img_pil = PIL.Image.open(file +'.png').convert('RGB')
mask_pil = PIL.Image.open(file +'-mask.png').convert('RGB')

net = unet.UNet(num_classes=3, in_channels=32, depth=6, start_filts=64).to(device)
h,w = img_pil.size
pad = (0, 0, size - h, size - w)
img = PIL.ImageOps.expand(img_pil, border=pad)
img = torch.Tensor(np.array(img).transpose([2, 0, 1])[None, :, :, :].astype(np.double)).to(device)
mask = PIL.ImageOps.expand(mask_pil, border=pad)
mask = torch.Tensor((np.array(mask)==0).transpose([2, 0, 1])[None, 0:3, :, :].astype(np.double)).to(device)
mean = img.mean()
std = img.std()
img = (img - mean)/std
optimizer = torch.optim.Adam(net.parameters(), lr=0.0001)
criterion = torch.nn.MSELoss()
input = torch.rand((1, 32, size, size)).to(device)
for it in range(5000):
    if it == 1000:
        optimizer.param_groups[0]['lr'] = 0.00003
    out = net(input)
    loss = criterion(out * mask, img * mask)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
out = out.detach().cpu().numpy()[0].transpose([1,2,0])*std.item() + mean.item()
out = np.clip(out, 0, 255).astype(np.uint8)[0:w, 0:h, :]
mask_np = (np.array(mask_pil) > 0).astype(np.uint8)
img_np = np.array(img_pil)
inpaint = (img_np * (1-mask_np) + mask_np * out).astype(np.uint8)
PIL.Image.fromarray(inpaint).save('./{}_inpainted.png'.format(file))

क्या डीप इमेज प्रायर यू-नेट्स से कुछ अलग है? ऐसा लगता है कि वे बेहतर परिणाम प्राप्त करेंगे
ASCII- केवल

इसके अलावा, क्या आपने डीप इमेज प्रायर के कोड
एएससीआईआई-केवल

@ ASCII- केवल वे कागज में बताते हैं कि वे वास्तव में मुख्य रूप से यू-नेट का उपयोग करते हैं, लेकिन मुझे उनके द्वारा उपयोग किए जाने वाले सटीक पैरामीटर नहीं मिल सकते हैं। उन्होंने अधिक क्षमता वाले जाल का उपयोग किया होगा। मेरे पास केवल बहुत सीमित मात्रा में एक कंप्यूटर था। इसलिए मुझे उन मापदंडों को चुनना पड़ा जो अभी भी स्मृति में फिट हैं और जिन्हें प्रशिक्षित करने में बहुत समय नहीं लगा। मुझे यकीन नहीं है कि वास्तव में इसे कितना समय लगा लेकिन मैंने जो कंप्यूटर का उपयोग किया (केवल एक सीपीयू के साथ) इन छवियों को कई दिन लगते हैं। (यदि आपके पास एक अतिरिक्त CUDA सक्षम GPU मुझे पता है :)
flawr

मुझे यह भी संदेह है कि नेटवर्क के डिजाइन के कारण आयताकार मुखौटे भी आदर्श नहीं हैं (और छोटे मुखौटे भी शायद बेहतर दिखेंगे), यदि आप उदाहरण के लिए पहले कुछ छवियों की तुलना पिछले दो से करते हैं (जो आयताकार मास्क का उपयोग नहीं करते हैं) ।
दोपहर

4

OpenCV के साथ अजगर

OpenCV में एक फ़ंक्शन है जिसे इनपेंट कहा जाता है। दो प्रकार के इनपेंटिंग का उपयोग किया जाता है, मैं फास्ट मार्चिंग विधि का उपयोग करूंगा। प्रलेखन के अनुसार, एल्गोरिथ्म इस तरह काम करता है:

छवि में एक क्षेत्र को अयोग्य मानें। एल्गोरिदम इस क्षेत्र की सीमा से शुरू होता है और क्षेत्र के अंदर जाता है और धीरे-धीरे सब कुछ सीमा में भर जाता है। यह पिगलों के चारों ओर एक छोटा सा पड़ोस लेता है, ताकि निगबॉर्नहुड पर अयोग्य हो। इस पिक्सेल को सामान्य तौर पर सभी ज्ञात पिक्सल के सामान्यीकृत भारित योग द्वारा बदल दिया जाता है। वजन का चयन एक महत्वपूर्ण मामला है। सीमा के पास स्थित उन पिक्सेल को अधिक वेटेज दिया जाता है, जो सीमा के सामान्य के पास और सीमा के समतल पर स्थित हैं। एक पिक्सेल के अयोग्य होने के बाद, यह फास्ट मार्चिंग विधि का उपयोग करके अगले निकटतम पिक्सेल में चला जाता है। एफएमएम यह सुनिश्चित करता है कि पहले ज्ञात पिक्सल के पास वाले पिक्सल पहले से ही निष्क्रिय हों, इसलिए यह सिर्फ मैनुअल ह्यूरिस्टिक ऑपरेशन की तरह काम करता है।

यहाँ कोड है:

import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('gothic.jpg')
b,g,r = cv2.split(img)
img2 = cv2.merge([r,g,b])
mask = cv2.imread('mask.jpg',0)
dst = cv2.inpaint(img2,mask,3,cv2.INPAINT_TELEA)
(h, w) = dst.shape[:2]
center = (w / 2, h / 2)
# rotate the image by 180 degrees
M = cv2.getRotationMatrix2D(center, 180, 1.0)
rotated = cv2.warpAffine(dst, M, (w, h))
plt.imshow(rotated)

ध्यान दें कि मैं साजिश रचने के कारणों के लिए BGR को RGB में कैसे परिवर्तित करता हूँ। इसके अलावा, मैं इसे घुमाएगी। यहाँ परिणाम हैं:

गोथिक

तारों भरी रात चिल्लाना एक और डरावना मोना लिसा!

मोना लिसा की वापसी!

पंक्ति 1

चेकर

जैसा कि आप देख सकते हैं, यह दो रंगों के साथ सबसे अच्छा नहीं है।


मोना लिसा को एक नया रूप मिला
कॉनर ओ'ब्रायन

3

जावा

एक रंग औसत दृष्टिकोण। शायद सुधारा जा सकता है।

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Scanner;

import javax.imageio.ImageIO;


public class ImagePatcher{
    public static void main(String[]args) throws Exception{
        Scanner in=new Scanner(System.in);
        int white=Color.WHITE.getRGB();
        int black=Color.BLACK.getRGB();
        BufferedImage image=ImageIO.read(new File(in.nextLine())),mask=ImageIO.read(new File(in.nextLine()));
        assert(image.getWidth()==mask.getWidth()&&image.getHeight()==mask.getHeight());
        boolean bool=true;
        while(bool){
            bool=false;
        for(int x=0;x<image.getWidth();x+=2){
            for(int y=0;y<image.getHeight();y+=2){
                if(mask.getRGB(x,y)!=white)continue;
                int r=0,g=0,b=0,n=0;
                for(int dx=-1;dx<=1;dx++){
                    if(x+dx<0)continue;
                    if(x+dx>=image.getWidth())continue;
                    for(int dy=-1;dy<=1;dy++){
                        if(y+dy<0)continue;
                        if(y+dy>=image.getHeight())continue;
                        if(mask.getRGB(x+dx,y+dy)==white)continue;
                        Color c=new Color(image.getRGB(x+dx,y+dy));
                        r+=c.getRed();
                        g+=c.getGreen();
                        b+=c.getBlue();
                        n++;
                    }
                }
                if(n==0){bool=true;continue;}
                Color c=n>0?new Color(r/n,g/n,b/n):new Color(100,100,100);
                image.setRGB(x,y,c.getRGB());
                mask.setRGB(x, y, black);
            }           
        }
        for(int x=0;x<image.getWidth();x+=2){
            for(int y=1;y<image.getHeight();y+=2){
                if(mask.getRGB(x,y)!=white)continue;
                int r=0,g=0,b=0,n=0;
                for(int dx=-1;dx<=1;dx++){
                    if(x+dx<0)continue;
                    if(x+dx>=image.getWidth())continue;
                    for(int dy=-1;dy<=1;dy++){
                        if(y+dy<0)continue;
                        if(y+dy>=image.getHeight())continue;
                        if(mask.getRGB(x+dx,y+dy)==white)continue;
                        Color c=new Color(image.getRGB(x+dx,y+dy));
                        r+=c.getRed();
                        g+=c.getGreen();
                        b+=c.getBlue();
                        n++;
                    }
                }
                if(n==0){bool=true;continue;}
                Color c=n>0?new Color(r/n,g/n,b/n):new Color(100,100,100);
                image.setRGB(x,y,c.getRGB());
                mask.setRGB(x, y, black);
            }
        }
        for(int x=1;x<image.getWidth();x+=2){
            for(int y=0;y<image.getHeight();y+=2){
                if(mask.getRGB(x,y)!=white)continue;
                int r=0,g=0,b=0,n=0;
                for(int dx=-1;dx<=1;dx++){
                    if(x+dx<0)continue;
                    if(x+dx>=image.getWidth())continue;
                    for(int dy=-1;dy<=1;dy++){
                        if(y+dy<0)continue;
                        if(y+dy>=image.getHeight())continue;
                        if(mask.getRGB(x+dx,y+dy)==white)continue;
                        Color c=new Color(image.getRGB(x+dx,y+dy));
                        r+=c.getRed();
                        g+=c.getGreen();
                        b+=c.getBlue();
                        n++;
                    }
                }
                if(n==0){bool=true;continue;}
                Color c=n>0?new Color(r/n,g/n,b/n):new Color(100,100,100);
                image.setRGB(x,y,c.getRGB());
                mask.setRGB(x, y, black);
            }           
        }
        for(int x=1;x<image.getWidth();x+=2){
            for(int y=1;y<image.getHeight();y+=2){
                if(mask.getRGB(x,y)!=white)continue;
                int r=0,g=0,b=0,n=0;
                for(int dx=-1;dx<=1;dx++){
                    if(x+dx<0)continue;
                    if(x+dx>=image.getWidth())continue;
                    for(int dy=-1;dy<=1;dy++){
                        if(y+dy<0)continue;
                        if(y+dy>=image.getHeight())continue;
                        if(mask.getRGB(x+dx,y+dy)==white)continue;
                        Color c=new Color(image.getRGB(x+dx,y+dy));
                        r+=c.getRed();
                        g+=c.getGreen();
                        b+=c.getBlue();
                        n++;
                    }
                }
                if(n==0){bool=true;continue;}
                Color c=n>0?new Color(r/n,g/n,b/n):new Color(100,100,100);
                image.setRGB(x,y,c.getRGB());
                mask.setRGB(x, y, black);
            }
        }
        };
        ImageIO.write(image, "png", new File("output.png"));
    }
}

परिणाम:

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें


2
आपको हमेशा इस विशेष कोण में लाइनें क्यों मिलती हैं? ऊपरी बाएं कोने अपेक्षाकृत अच्छे से मेल खाते हैं, जबकि नीचे का दायां भाग बिल्कुल भी मेल नहीं खाता है।
दोष

मुझे लगता है कि इसका उस क्षेत्र से जुड़ाव करने के तरीके से करना है। मैं शायद उसे बदल दूंगा।
SuperJedi224 12

हमेशा ऐसा लगता है जैसे ट्रेपोज़िड्स हैं।
ericw31415

@ ericw31415 यह पुनरावृत्ति क्रम की एक कलाकृति है।
SuperJedi224
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.