Tuesday, 12 December 2017

Glidande medelvärde as faltning


Suddning för nybörjare Inledning Detta är en kort handledning om oskärpa tekniker för nybörjare. När jag lärde mig dessa saker var det väldigt lite tillgängligt material som var användbart. Det var inte sant självklart - det fanns massor av material, men hälften av det var alltför enkelt och den andra halvan började. Låt T vara en vektorfunktion utvärderad över det halvöppna intervallet. och var full av väldigt läskiga multilinj ekvationer med de stora sigmasymbolerna och sakerna. Denna artikel är avsedd att åtgärda det. Jag talar om olika typer av suddighet och effekterna du kan använda dem för, med källkod i Java. En ansvarsfriskrivning När suddning nämns är det alltid någon som säger Hey Thats inte en riktig rörelseoskärpa eller skriver arga brev i grönt bläck som klagar på att matematiken är tveksam eller att det är en mycket snabbare sätt att göra detta med hjälp av sponglerizer-registren på HAL -9000. Ignorera dessa människor. Detta är ett stort ämne, och den här artikeln är bara för nybörjare (som jag stolt kan säga att jag är en). Vad som är viktigt är att du får de resultat du siktar på, och om resultaten du syftar till kräver tvivelaktig matematik, så var det så. Om resultaten du siktar på ser hemskt ut för mig, så är det bra, så länge de ser bra ut för dig. En annan ansvarsfriskrivning Theres källkod i Java för ganska bra allt jag pratar om här. Jag gör inga påståenden att dessa optimeras på något sätt - Ive valt för enkelhet över hastighet överallt och du kommer förmodligen att kunna göra de flesta av dessa saker gå snabbare med lite ansträngning. Du kan använda källkoden för allt du vill, inklusive kommersiella ändamål, men det finns inget ansvar. Om ditt kärnkraftverk eller missilsystem misslyckas på grund av felaktig suddighet, är det inte mitt fel. Vad är suddning Vi vet alla vad suddning är, inte vi Det är det som händer när din kamera är ute av fokus eller hunden stjäl dina glasögon. Vad händer är att det som ska ses som en skarp punkt blir utsmält, vanligtvis i en skivform. I bildvillkor betyder det att varje pixel i källbilden sprids över och blandas i omgivande bildpunkter. Ett annat sätt att titta på detta är att varje pixel i destinationsbilden består av en blandning av omgivande pixlar från källbilden. Operationen vi behöver för detta kallas convolution. Det här låter komplicerat men det är bara för att matematiker gillar att få saker att låta komplicerade för att behålla den magiska luften och hålla finansieringen rullande in. Tja, jag är på dem och jag kan avslöja att konvolution är inte så komplicerad (på min nivå ändå) . Hur det fungerar är det här: vi tänker oss att glida en rektangulär mängd siffror över vår bild. Denna array kallas fältekärnan. För varje pixel i bilden tar vi motsvarande nummer från kärnan och pixlarna är över, multiplicerar dem tillsammans och lägger alla resultat tillsammans för att skapa den nya pixeln. Tänk oss att vi vill göra en riktigt enkel oskärpa där vi bara genomsnittligen sammanfogar varje pixel och dess åtta omedelbara grannar. Kärnan vi behöver är: Observera att dessa alla lägger till 1, vilket innebär att vår resulterande bild blir lika ljus som originalet. Utan ytterligare ado kan vi oskärpa en bild i Java. Allt det där föllet är svårt att implementera, men lyckligtvis kommer Java med en inbyggd och färdig att använda operatör för att göra exakt det. Jag pratar ConvolveOp här. Häri koden: Fantastiskt En suddig bild Det är dock inte så suddigt. Låt oss göra en riktigt stor suddighet så här: Hmmmmmm. Jo det är inte så bra. Inte bara tog det lång tid, men resultatet är lite konstigt - allt ser bra ut, en slags kvadrat och vad som på jorden har hänt runt kanterna. Första kanterna: ConvolveOp är en blygsam namby-pamby sak som är rädd av att falla utanför bildens kant. Om kärnan skulle överlappa kanten på bilden, ger den bara upp och lämnar bara pixeln oförändrad. Du kan ändra detta genom att passera EDGEZEROFILL istället för EDGENOOP, men det är ännu värre - pixlarna runt kanten blir bara inställda på noll och försvinner effektivt. Vad ska vi göra Nåväl, vi kan kasta ut bilden runt kanterna innan den suddas och skörda resultatet, men det ger bara in och förutom att vi inte skulle lära oss något. Istället skriver du en riktig, orädd, ingen-nonsensoperatör som inte är rädd för kanterna. Tja, kalla det ConvolveFilter för att skilja det från ConvolveOp. Jag kommer inte att göra med källaens detaljer i den här artikeln - det finns inte tillräckligt med tid eller utrymme och vi har mycket fler filter att skriva ännu, men du kan ladda ner eller visa källan och det borde vara ganska självförklarande. Nu är problemet med kvittring: Orsaken till att allt ser ut är att det som händer här kallas en boxaskärpa. Vår kärna är formad som en fyrkant, som om det var en kamera med en kvadratisk bländare. Förresten, låt inte någon berätta för dig att boxens oskärpa är värdelös - faktiskt om du simulerar skuggan som kastas av ett fyrkantigt ljus, är det exakt vad du vill ha. Hur som helst kommer de komma till nytta vidare. En annan sak: bli inte förvirrad - jag använder termen rutaskärpa för att referera till formen på kärnan, inte dess profil, som jag kommer att ringa ett lådfilter. Mer om detta senare. För att få en mer realistisk suddighet, vad vi borde ha gjort används en cirkelformad kärna. Detta simulerar mycket bättre vad en riktig kamera gör. Det är mycket bättre. Tja kom tillbaka till det här senare, men först en avledning tillbaka till lådans oskärpa. Weve löst problemet med kantpunkten, men vår oskärpa går fortfarande riktigt långsamt, och sakerna kommer bara att bli värre. Problemet är att antalet multiplikationer i fällningen går upp som kvadraten av kärnradien. Med en 100x100-kärna skulle man göra 10000 multiplikationer och lägger till per pixel (ca). Hur kan vi komma runt detta Det visar sig att det finns fler sätt att gå om detta än att jag kanske har tid att skriva om, eller till och med bry sig om att titta på. Ett sätt som jag kommer att nämna snabbt innan du sveper det under mattan är det här: Du kan göra en lådans oskärpa genom att krympa ner din bild, suddas upp och skalar upp den igen. Det kan vara bra för dina ändamål, och du bör komma ihåg det. Ett problem är att det inte animerar mycket bra, men kanske inte är ett problem för dig. Låt oss titta på rutan oskarpa igen: Det visar sig att det finns ett par väldigt enkla sätt att påskynda detta. För det första visar det sig att boxens oskärpa är separerbar. Det betyder att vi kan göra en 2D-oskärpa genom att göra två 1D-försvinnningar, en gång i horisontell riktning och en gång i vertikal riktning. Detta är mycket snabbare än att göra 2D-oskärpa, eftersom tiden som går upp går i proportion till kärnstorleken, inte som dess fyrkant. För det andra, Tänk på fönstret som glider över bilden. När vi flyttar den från vänster till höger kommer pixlar in i den högra kanten och läggs till i totalsumman samtidigt som pixlar lämnar vänstra kanten och subtraheras från summan. Allt vi behöver göra är att bara lägga till och subtrahera för att gå in och lämna pixlar vid varje steg istället för att lägga samman alla pixlar i fönstret. Vi behöver bara lagra en uppsättning löpande totaler som är kärnans bredd eller höjd. Detta ger en enorm hastighetsförbättring till kostnaden för att behöva skriva en kod. Lyckligtvis skrev Ive koden för dig, så du vinner hela tiden. Vi behöver två pass, en gång för att suddas horisontellt och en gång vertikalt. Koden för dessa är givetvis helt annorlunda. Men vänta Theres ett lur vi kan göra som tillåter oss att bara skriva koden en gång. Om vi ​​skriver en suddfunktion som gör det horisontella suddigt men skriver dess utmatningsbild transposerad, så kan vi bara kalla det två gånger. Det första passet försvinner horisontellt och transponeras, det andra passet gör detsamma, men som bilden nu transponeras gör den verkligen en vertikal oskärpa. Det andra införlivandet gör bilden rätt väg upp igen och voila - en väldigt snabb lådans oskärpa. Prova det i den här appleten: Och här är källkoden. Du kanske har märkt att vi bara har använt en heltalstradie hittills vilket gör det enkelt att träna arrayindexen för suddning. Vi kan förlänga tekniken för att göra sub-pixel-suddning (dvs en icke-integrerad radie) helt enkelt genom linjär interpolering mellan matrisvärdena. Min källkod gör det inte, men det är lätt att lägga till. Gaussian Blur Nu är det dags att ta itu med hastighets - och fyrkantiga utseenden på samma gång. För att bli av med torget ser vi suddigt, vi behöver en cirkulärformad kärna. Tyvärr har tricket som vi använde för boxblurs inte fungerat med en cirkel men det finns ett smutthål: Om kärnan har rätt profil - Gauss-profilen - då kan vi göra en 2D-oskärpa genom att utföra två 1D-blurs, precis som vi gjorde med boxaskärpa. Det är inte så snabbt eftersom det glidande fönstret trick inte fungerar, men det är fortfarande mycket snabbare än att göra 2D-konvolutionen. Den profil vi behöver är den välkända klockformade eller gaussiska kurvan som du har hört talas om: Heres någon kod för att skapa en 1D Gaussisk kärna för en given radie. Allt vi behöver göra är att applicera detta två gånger, en gång horisontellt och en gång vertikalt. Som en bonus har Ive lindat upp det i en GaussianFilter för att göra det enkelt att använda. Det är därför som Gauss-suddning finns i varje grafikpaket - det är mycket snabbare än andra typer av suddighet. Det enda problemet är att det inte är så realistiskt när det gäller att simulera kameralinser, men mer om det senare. Om du vill göra saker som att simulera skuggor, då kan Gaussisk oskärpa, eller till och med lådans oskärpa, vara bra. Theres en plats för alla dessa effekter - bara för att de är realistiska menar inte att de inte är användbara. Gaussisk oskärpa är mycket snabbare, men det finns ingenstans lika snabbt som vår rutaskärpa vi gjorde tidigare på. Om det bara fanns något sätt att kombinera de två. Jag föreställer mig att du har gissat nu att det kan finnas en, så jag håller inte längre spänningen: Om du gör en massa lådor, ser resultatet mer och mer ut som en gaussisk suddighet. Faktum är att du kan bevisa det matematiskt om du har ett extra ögonblick (men berätta inte för mig hur - jag är inte intresserad). I praktiken ser 3 till 5 låda oskärpa ganska bra ut. Ta inte bara mitt ord för det: Boxens oskärpa applet ovan har en glidreglage, så du kan prova själv. Alfa-kanaler En snabb omledning här för att diskutera ett problem som ofta uppstår: Tänk dig att du vill suddas bort en form som är transparent. Du har en tom bild, och du ritar en form på den och slår sedan bilden. Hänga på - varför ser suddig ut för mörk? Orsaken är att vi har suddit varje kanal separat, men där alfakanalen är noll (de transparenta bitarna) är de röda, gröna och blåa kanalerna noll eller svarta. När du gör oskärpa, blir det svarta blandat med de ogenomskinliga bitarna och du får en mörk skugga. Lösningen är att premultiply bilden alfa innan den blur och unpremultiply den efteråt. Självklart, om dina bilder redan är förutbestämda, så är du upptagen. Motion Blur Time för en riktningsändring. Hittills har vi bara pratat om likformiga oskärpa, men det finns andra typer. Rörelsesläckning är suddigheten som du får när ett föremål (eller kameran) rör sig under exponeringen. Bilden blir suddig längs objektets uppenbara väg. Här skulle bara prata om att simulera rörelseoskärpa på en befintlig stillbild - gör rörelseslörhet i animationer ett helt annat område. Var också bara att bli suddig hela bilden - skulle inte försöka att suddas bort ett objekt i bilden. Den goda nyheten är att vi redan gjort enkla rörelseoskärpa. Gå tillbaka till boxen oskärpa applet ovan och sätt den horisontella radieen till, säga 10 och den vertikala radien till noll. Detta ger dig en fin horisontell rörelseoskärpa. För vissa ändamål kan det här vara allt du behöver. Ett sätt att producera en borstad metalltextur är till exempel att ta en bild som består av slumpmässigt brus och applicera en rörelsesläckning. Om vi ​​vill suddas i en annan riktning än horisontell eller vertikal, blir sakerna mer komplicerade. En teknik kan vara att rotera bilden, oskärpa och sedan rotera tillbaka. Men vad gör du här är att göra det på det svåra och långsamma sättet. Vad vi behöver göra är att slinga över bilden, och för varje pixel lägger du upp alla pixlar längs rörelsebanan. För en rak rörelseoskärpa betyder det bara att följa en rak linje från pixeln, men du kan följa en wiggly-väg om du ville simulera kameraskakningar med lång exponering, säger. Spin och Zoom Blur När vi har fått koden för rörelseoskärpa på plats, är det en enkel sak att ändra det för att göra zoom och snurrning, eller till och med en kombination av alla tre. Det är bara en fråga om att följa rätt väg för varje pixel. För radiella oskärpa, följ bara en väg som går från oskärpa centret. För en snurrning, följ en tangentiell väg. Prova det i den här appleten: Här är källkoden för att göra dessa tre typer av rörelsesläckning: Snabbare rörelsusläckning Du kanske har märkt att det går ganska långsamt att göra rörelsesläckningen - alla dessa sins och cosines gör det verkligen långsamt. Om vi ​​inte var så oroliga över kvaliteten kan vi påskynda detta. Allt vi behöver göra är att lägga samman många transformerade versioner av bilden på ett smart sätt. Den kloka delen är att vi kan göra en 1-pixel rörelseoskärpa genom att medelstora bilden och samma bild översatt av en pixel. Vi kan göra en oskärpa på 2 pixlar genom att upprepa detta med de 1 bildpunkterna suddiga bilder. Genom att upprepa detta kan vi göra en N-pixeloskärpa i log2 (N) - operationer, vilket är mycket bättre än att göra det på den svåra och långsamma vägen. Zoom och spin blurs kan göras genom att skala och rotera istället för att översätta. Ett filter kommer att göra alla tre med en AffineTransform. Prova det i den här appleten: Domänskiftande Theres ännu ett annat sätt att göra dessa rörelser oskärpa: Kom ihåg jag sa att du kunde göra linjär rörelseoskärpa genom att rotera bilden, göra en vågrät ludddosa och rotera tillbaka Jo, det samma gäller för zoom och snurrning, utom du behöver något mer komplicerat än rotation. Vad du behöver är den polära transformen. När du har förvandlat din bild, är en vågrät låssläckning en snurr när du omvandlar tillbaka, och en vertikal luddoskärpa ger dig en zoomsläckning. En detalj är att du behöver en speciell horisontell boxaskärpa som slingrar i kanterna annars får du en skarp vertikal linje i din suddiga bild där vridningsvinkeln ska vikas runt. Suddning av Fourier Transform Gaussisk suddighet är mycket bra när du vill ha den gaussiska suddningseffekten, men vad händer om du vill ha en riktig objektivoskärpa som simulerar en riktig kameraöppning Titta på film eller tv-program ett tag, speciellt något skott på natten med ljus i bakgrunden, och du kommer att se att saker som är out of focus bildar diskformar, eller kanske pentagons. Theres också ett fenomen som kallas blommande där ljusa delar av bilden tvättar ut bilden, blir jämnare ljusare jämfört med resten. Dessa former kallas Bokeh. Vissa människor älskar det och vissa människor hatar det. Vi bryr oss inte om folk älskar det eller hatar det, vi vill bara reproducera det. Du kommer inte få de skivformarna med Gaussisk oskärpa - det är bara för fuzzy runt kanterna. Vad du behöver göra det, använd en fin skarp kantkärna i form av kamerans bländare. Problemet kommer du hit här är att alla dessa knep med separerbara kärnor, itererade lådor och liknande, kommer inte att fungera här - det finns inga separerbara kärnor som ger dig en pentagon (väl, förmodligen - jag är ingen matematiker) - var tillbaka till Det gamla problemet med suddig tid går upp som torget i suddradien. Skräck inte, vi kan vända de tunga matematiska vapnen till problemet. Jag vet inte hur de tunga vapen fungerar, men jag kan rikta dem. De tunga pistolerna är Fourier Transforms. Jag vet inte hur de fungerar för att jag inte lyssnade på mina universitetsföreläsningar, men det finns en stor mängd om ämnet du kan hitta på Internet, även om det är praktiskt taget inget praktiskt (dvs med källkod) om ämnet för suddning. Med Fourier Transforms kan du göra en suddighet som tar en tid opåverkad av suddradien (i praktiken innebär det att det handlar om bildkanterna att detta inte är riktigt sant). Tyvärr betyder det att det för en liten radie är långsam, men du vinner verkligen med en stor radie. Ett sätt att hantera detta är att använda den enkla convolutionen för små radier och byta till Fourier Transforms när du når till crossover punkt i tid, förutsatt att du har gjort experimenten för att bestämma var det är. Men var försiktig, om du animerar en suddighet, måste du se till att du inte får några synliga artefakter vid den punkt där du byter algoritm - ögat är riktigt bra för att spotta dem. Av den anledningen kan du föredra att hålla fast vid en algoritm för hela animationen. För stillbilder kommer ingen att märka. Verkligen. Ser det verkligen annorlunda ut. Säkert kan vi komma undan med en gaussisk oskärpa. Nåväl, här är ett exempel som hjälper dig att klara dig. Principen bakom att bli suddig är inte för svår, även om det verkar som magi. Vad vi gör är att ta bilden och kärnan, och utför Fourier-transformen på dem båda. Vi multiplicerar sedan de två tillsammans och omvänt transformationen tillbaka. Detta är exakt detsamma som att utföra den långa konvolutionen ovan (bortsett från avrundningsfel). Du behöver inte faktiskt veta vad en Fourier-omvandling gör för att genomföra detta, men hur som helst är det att konvertera din bild till frekvensutrymme - den resulterande bilden är en konstig utseende av de rumsliga frekvenserna i bilden. Den omvända omvandlar naturligtvis tillbaka till rymden. er, utrymme Tänk på det som en grafisk equalizer för bilder. Du kan tänka på att suddas bort en bild som att ta bort högfrekvenser från det, så det är hur Fourier-transformer kommer in på bilden. Genomförandet av detta är faktiskt ganska enkelt, men det finns många otäcka detaljer att oroa sig för. Först och främst behöver vi några funktioner för att göra omvandlingen och dess inversa. Dessa finns i klass FFT. Detta är inte på något sätt en superoptimerad implementering - du kan hitta många av dem på andra ställen på Internet. Därefter måste vi konvertera kärnan till en bild i samma storlek som bilden var suddig (jag är säker på att det finns sätt att undvika detta, men jag vet inte tillräckligt med matematik - om bara Id har lyssnat i dessa föreläsningar). Vi behöver också kasta ut vår källbild med raden av suddning, duplicering av kanten pixlar eftersom det är svårt att få FFT att hantera kanter så här. Nu arbetar FFT på komplexa tal, så vi måste kopiera bilden och kärnan till float arrays. Vi kan göra ett knep här - våra bilder har fyra kanaler (alfa, rött, grönt och blått) så vi måste göra fyra transformer plus en för kärnan, vilket gör fem, men sedan vi använde komplexa tal kan vi göra två transformer på en gång genom att lägga en kanal i den reella delen av matrisen och en kanal i den imaginära delen. Nu blir det enkelt, bara förvandla bilden och kärnan, komplexa multiplicera dem tillsammans och inversa transformer och vi har vår bild tillbaka, men förknippad med kärnan. En sista liten detalj är att omvandlingsprocessen byter över kvadranterna på bilden så vi behöver göra omslaget. Endast en liten detalj kvarstår: FFT fungerar bara på bilder som är en kraft på 2 i varje riktning. Vad vi måste göra är att lägga till två gånger suddradien till bredden och höjden, hitta nästa högsta effekt på 2 och gör våra arrays den storleken. För stora bilder har detta ett par problem: En är som använde mycket minne. Kom ihåg att vi har våra bilder i float arrays och vi behöver 6 av dessa arrays, varav fyra gånger storleken på bilden när den har expanderats till en kraft av två. Din virtuella Java-maskin kanske väl klagar på dig om du försöker detta på en stor bild (jag vet, jag har försökt). Det andra problemet är relaterat: Saker går bara långsammare med de stora bilderna på grund av minnesproblem. Svaret är att dela upp bilden i plattor och sudda varje kakel separat. Att välja en bra kakelstorlek är ett alternativ för forskningsproblem (det vill säga jag har inte störtats experimentellt mycket) men det är svårt - vi måste överlappa kakorna med suddradien så om vi valde en kakelstorlek på 256 med en suddradie på 127 , bara släcka 4 pixlar med varje sida. Prova det i den här appleten: Tvärskärpa Blurning Det som ofta är önskat är en oskärpa som försvinner delar av bilden som är mycket lika men bevarar skarpa kanter. Det här är digital skrynkla grädde och du kan se detta i någon filmaffisch som någonsin skrivits ut - stjärnans ansikten har alla de otäcka fläckarna utstrykade utan att bilden blir suddig. Ofta är det så otroligt att aktörerna ser ut som vaxverk eller datorgenererade figurer. Hur vi gör detta är att göra en vanlig konvolvering, men bara räkna i omgivande bildpunkter som liknar målpixeln. Specifikt har vi ett tröskelvärde och inkluderar bara en pixel i konvolutionen om den skiljer sig från mittpunkten med mindre än tröskeln. Tyvärr brukar de korta nedskärningarna som vi har tagit ovan inte fungera här eftersom vi måste inkludera en annan uppsättning omgivande pixlar för varje målpixel, så var tillbaka till full convolution igen. Nu, även om det här är extremt tvivelaktigt, fungerar det faktiskt ganska bra för att fortfarande göra de två 1D-omvälvningarna för en Gaussisk oskärpa, vilket är snabbare än att göra den fulla 2D-konvolutionen, så det är vad jag gjort här. Känn dig fri att ändra källan för att göra det hela. Prova det i den här appleten: Variable Blurs Hittills har vi bara pratat om likformiga oskärpa - där suddradien är densamma vid varje punkt. För vissa ändamål är det trevligt att ha blurs som har en annan radie vid varje punkt i bilden. Ett exempel är att simulera skärpedjup: Du kan ta en bild som ligger i fokus överallt och tillämpa en variabel oskärpa för att göra delarna ute ur fokus. Verkligt skärpedjup är mer komplicerat än det här eftersom ett objekt som ligger bakom ett annat objekt inte får någon suddighet från föremålet framför, men ignorerar det och lämnar det till proffs. Nu kommer våra snygga tricks över arent att hjälpa oss mycket här, eftersom allt innebär att beräkna kärnor eller beror på att suddradien är densamma över bilden och vid första ögonkastet ser det ut som att vi inte har något annat alternativ än att falla tillbaka på den fulla convolutionen vid varje pixel, bara den här gången är det mycket värre som kärnan kan ha ändrats från föregående pixel. Men allt är inte förlorat. Kom ihåg att trick med boxen blurs där vi bara lagt till i pixlar när de gick in i kärnan och subtraherade dem när de lämnade. Det verkar som om det inte kommer att fungera i variabelradiefallet eftersom wed måste hålla totals för varje möjlig radie, men det är en modifikation vi kan göra till tricket som gör det möjligt för oss att dra ut summan totalt för alla rader med endast en subtraktion. Vad vi gör är preprocess bilden och ersätta varje pixel med summan av alla pixlar till vänster. På det sättet när vi vill hitta summan av alla pixlar mellan två punkter i en scanline, behöver vi bara subtrahera den första från den andra. Detta gör det möjligt för oss att göra en snabb variabel suddning med en modifierad version av rutans oskärpa kod ovan. Att hantera kanterna är lite mer komplicerat, eftersom det bara är att subtrahera totalen fungerar inte för pixlar utanför kanten, men det här är en mindre detalj. Vi behöver också lite mer lagringsutrymme eftersom summorna kommer att gå över det maximala värdet på en pixel - behöver väl använda en int per kanal i stället för att lagra fyra kanaler i ett int. Tja, OK, men det här är en Gaussian (ish) oskärpa, det är inte vad med att göra den linsen oskärpa sak med variabel radie Tyvärr är du inte lycklig här. Jag säger inte att det inte finns en super snabb sätt att göra det här, men så långt jag vet att du kommer att behöva göra den fulla convolutionen. Prova det i den här appleten, som blursar mer när du flyttar till höger: Skärpa genom suddning Du kan använda en suddighet för att skärpa en bild samt att bli suddig med en teknik som kallas oskarp maskering. Vad du gör är att ta bilden och dra bort en suddig version, se till att du kompenserar för förlusten av ljusstyrka. Det låter som magi, men det fungerar verkligen: jämför den här bilden med originalet. Prova det i den här appleten: Om du subtraherar en suddig version av en bild från sig själv skärper den, vad lägger den till Som någonsin behöver du inte gissa - Jag är här för att informera dig. Vad du får är en slags glödande effekt som kan se ganska fin ut, eller ganska ostliknande beroende på din synvinkel. Variera mängden oskärpa som tillsätts varierar den glödande effekten. Du kan se denna effekt används mycket på tv för drömmande utseende övergångar. Prova det i den här appleten: Att göra skuggor Att göra en skugga handlar bara om att skapa en bild som ser ut som silhuetten för skuggningsobjektet, suddar det, eventuellt snedvrider eller flyttar det och klistrar in originalbilden överst. Eftersom det här är en vanlig sak att vilja göra, borde det vara ett filter att göra det, och här är det. Det här är faktiskt en mycket enkel implementering - det blur bara skuggan och drar den ursprungliga bilden överst. I praktiken är det bättre att inte störa blekning av pixlarna som är helt dolda av objektet. Gjutningsstrålar Vi kan göra samma trick för att ljusstrålar verkar komma ut ur ett föremål, bara den här gången gör skuggfärgen vit och använder en zoomsläckning i stället för den vanliga suddningen och lägger sedan resultatet ovanpå originalet. Strålarna ser ofta bättre ut om du bara kastar dem från ljusa delar av bilden, så filtret har ett tröskelvärde som du kan ställa in för att begränsa strålarna till ljusa områden. Det här är en bra effekt att animera: gör att mitten av strålarna rör sig över bilden och du får effekten av en rörlig ljuskälla bakom bilden. Slutsats Tja, det är det, och jag har inte ens nämnt andra suddiga metoder som IIR-filter, rekursiva filter och alla andra otäcka saker. Jag hoppas att du kommer undan med något användbart från detta, även om det bara är en brinnande önskan att köpa lite grönt bläck och skriva mig ett brev. Slutligen kan du ha märkt att källan ovan är beroende av några andra klasser. Oroa dig inte, här är de: Lodes Computer Graphics Handledning Bildfiltrering Innehållsförteckning Inledning Bildfiltrering gör det möjligt att tillämpa olika effekter på foton. Den typ av bildfiltrering som beskrivs här använder ett 2D-filter som liknar det som ingår i Paint Shop Pro som användardefinierat filter och i Photoshop som anpassat filter. Konvoltering Tricket i bildfiltrering är att du har en 2D-filtermatris och 2D-bilden. Sedan, för varje bildpunkt, ta summan av produkterna. Varje produkt är färgvärdet för den aktuella pixeln eller en granne av den, med motsvarande värde för filtermatrisen. Filtermatrisens centrum måste multipliceras med den aktuella pixeln, de andra elementen i filtermatrisen med motsvarande nabopixlar. Denna operation där du tar summan av produkter av element från två 2D-funktioner, där du låter en av de två funktionerna flytta över varje element i den andra funktionen kallas Konvolvering eller Korrelation. Skillnaden mellan konvolution och korrelation är att för konvolution måste du spegla filtermatrisen, men vanligtvis är den symmetrisk i alla fall så det är ingen skillnad. Filtren med konvolvering är relativt enkla. Mer komplexa filter, som kan använda mer fina funktioner, existerar också, och kan göra mycket mer komplexa saker (till exempel Färgpennfiltret i Photoshop), men sådana filter diskuteras inte här. 2D-konvolutionsoperationen kräver en 4-dubbel loop, så det är inte extremt snabbt, om du inte använder små filter. Här brukar brukar använda 3x3 eller 5x5 filter. Det finns några regler om filtret: Dess storlek måste vara ojämn, så att den har ett centrum, till exempel 3x3, 5x5 och 7x7 är ok. Det behöver inte, men summan av alla element i filtret ska vara 1 om du vill att den resulterande bilden ska ha samma ljusstyrka som originalet. Om summan av elementen är större än 1 kommer resultatet att bli en ljusare bild, och om den är mindre än 1, en mörkare bild. Om summan är 0, är ​​den resulterande bilden inte nödvändigtvis helt svart, men det är väldigt mörkt. Bilden har ändliga dimensioner, och om du till exempel beräknar en pixel på vänster sida, finns det inte några fler pixlar till vänster om det, medan dessa krävs för falsningen. Du kan antingen använda värdet 0 här eller linda runt till andra sidan av bilden. I denna handledning väljes omslaget, eftersom det enkelt kan göras med en modulo-delning. De resulterande pixelvärdena efter applicering av filtret kan vara negativa eller större än 255. Om så händer kan du avkorta dem så att värden som är mindre än 0 är gjort 0 och värden större än 255 är satt till 255. För negativa värden kan du också ta det absoluta värdet istället. I Fourier Domain eller Frequency Domain blir konvolutionsoperationen en multiplikation istället, vilket är snabbare. I Fourier-domänen kan mycket kraftfullare och större filter appliceras snabbare, speciellt om du använder snabb Fourier-transformen. Mer om detta finns i Fourier Transform-artikeln. I den här artikeln, kolla på några mycket typiska småfilter, såsom oskärpa, kantdetektering och prägling. Bildfilter är inte möjliga för applikationer och spel i realtid, men de är användbara vid bildbehandling. Digitala ljud - och elektroniska filter fungerar också med convolution men i 1D. Häri koden som ska användas för att prova olika filter. Förutom att använda en filtermatris, har den också en multiplikatorfaktor och en bias. Efter applicering av filtret multipliceras faktorn med resultatet, och förspänningen läggs till den. Så om du har ett filter med ett element 0,25 i det, men faktorn är satt till 2, är alla element i filtret teoretiskt multiplicerat med två så att elementet 0,25 faktiskt är 0,5. Förspänningen kan användas om du vill göra den resulterande bilden ljusare. Resultatet av en pixel lagras i floats röd, grön och blå innan den konverteras till heltalet i resultatbufferten. Filtreringsberäkningen i sig är en 4-dubbelslinga som måste gå igenom alla pixlar av bilden, och sedan genom varje element i filtermatrisen. PlaceringsbildenX och imageY beräknas så att för centrumets element i filtret är det x, y, men för de andra elementen är det en pixel från bilden till vänster, höger, övre eller nedre delen av x, y. Dess modulo delad genom bredden (w) eller höjden (h) av bilden så att pixlar utanför bilden kommer att lindas runt. Innan modulo delar upp det, läggs även w eller h till det, eftersom denna modulo-delning inte fungerar korrekt för negativa värden. Nu blir pixel (-1, -1) korrekt pixel (w-1, h-1). Om du vill ta det absoluta värdet av värden som är mindre än noll istället för att avkorta det, använd den här koden istället: Tidsserieanalysen tsa statsmodels. tsa innehåller modellklasser och funktioner som är användbara för tidsserieanalys. Detta omfattar för närvarande univariate autoregressive modeller (AR), vektorautoregressiva modeller (VAR) och univariate autoregressive moving average models (ARMA). It also includes descriptive statistics for time series, for example autocorrelation, partial autocorrelation function and periodogram, as well as the corresponding theoretical properties of ARMA or related processes. It also includes methods to work with autoregressive and moving average lag-polynomials. Additionally, related statistical tests and some useful helper functions are available. Estimation is either done by exact or conditional Maximum Likelihood or conditional least-squares, either using Kalman Filter or direct filters. Currently, functions and classes have to be imported from the corresponding module, but the main classes will be made available in the statsmodels. tsa namespace. The module structure is within statsmodels. tsa is stattools. empirical properties and tests, acf, pacf, granger-causality, adf unit root test, ljung-box test and others. armodel. univariate autoregressive process, estimation with conditional and exact maximum likelihood and conditional least-squares arimamodel. univariate ARMA process, estimation with conditional and exact maximum likelihood and conditional least-squares vectorar, var. vector autoregressive process (VAR) estimation models, impulse response analysis, forecast error variance decompositions, and data visualization tools kalmanf. estimation classes for ARMA and other models with exact MLE using Kalman Filter armaprocess. properties of arma processes with given parameters, this includes tools to convert between ARMA, MA and AR representation as well as acf, pacf, spectral density, impulse response function and similar sandbox. tsa. fftarma. similar to armaprocess but working in frequency domain tsatools. additional helper functions, to create arrays of lagged variables, construct regressors for trend, detrend and similar. filters. helper function for filtering time series Some additional functions that are also useful for time series analysis are in other parts of statsmodels, for example additional statistical tests. Some related functions are also available in matplotlib, nitime, and scikits. talkbox. Those functions are designed more for the use in signal processing where longer time series are available and work more often in the frequency domain. Descriptive Statistics and Tests stattools. acovf (x, unbiased, demean, fft)

No comments:

Post a Comment