Rörelsekompensation

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 11 mars 2018; kontroller kräver 13 redigeringar .

Rörelsekompensation är en av de huvudsakliga algoritmerna  som används vid bearbetning och komprimering av videodata . Algoritmen använder likheten med närliggande bildrutor i videosekvensen och hittar rörelsevektorerna för enskilda delar av bilden (vanligtvis block på 16x16 och 8x8). Användningen av kompensation gör det möjligt att upprepade gånger öka kompressionsförhållandet under kompression på grund av borttagandet av redundans i form av matchande delar av ramar. Används inte bara för komprimering, utan också för videofiltrering , ändring av bildhastighet , etc.

Idén med algoritmen

Att lösa problemet med komprimering har varit ett avgörande problem sedan tillkomsten av digital video. För utvärdering, låt oss ta en videosekvens med följande parametrar:

Som ett resultat kommer det att ta 14,8 megabyte att spela in eller sända en sekund av sådan video utan komprimering, exklusive ljud och serviceinformation. För att lagra en och en halv timmes film kommer det redan att behövas 79 920 megabyte (78 gigabyte ).

I nästan vilken video som helst är intilliggande ramar lika, har gemensamma objekt, som i regel rör sig parallellt. Och det är ganska naturligt att vilja koda video på ett sådant sätt att objekt inte kodas många gånger, utan en del av deras förskjutningar beskrivs enkelt.[ neutralitet? ]

Även i det här exemplet, om vi tar och packar den 0:e ramen och alla bilder av interframe-skillnaden med arkiveraren, får vi en märkbar[ hur mycket? ] kompressionsförstärkning. Men denna vinst kan ökas avsevärt.

Ett exempel på hur algoritmen fungerar

På grund av den höga beräkningskomplexiteten hos mönsterigenkänningsalgoritmer och den otillräckliga noggrannheten i deras arbete, används olika metoder för att snabbt hitta rörelsevektorer (naturligtvis, inte utan förlust).

1. Den aktuella ramen laddas.
2. Ramen är uppdelad i block (t.ex. 16×16).

3. Block förbigås (varje block bearbetas separat i detta fall).
4. När man räknar ett block, förbigås ett visst område av blocket i sökandet efter maximal överensstämmelse med bilden av blocket på föregående bildruta inom detta område.

5. Sålunda, efter att sökningen är klar, får vi en uppsättning vektorer som indikerar "rörelsen" av bildblock mellan bildrutor. Dessa vektorer kan naturligtvis användas för att skapa en bild av en kompenserad bildruta som bättre approximerar den bildruta för vilken rörelsekompensation utfördes.

Implementeringsfrågor

När du skriver en algoritm kan frågan uppstå - "Hur man utvärderar "likheten" mellan bildfragment?". Några av alternativen:

Den vanligaste beräkningen är SAD. Nästa fråga är: "Hur söker man efter önskat block?"

Implementeringsexempel

Implementering av brute force-metoden i C++

void ME ( BYTE * CurrentFrame , BYTE * PreviousFrame , int Width , int Height , MV * MotionVectors ) { int BlocksPerHeight = ( Höjd + 15 ) >> 4 ; //Antal block vertikalt int BlocksPerWidth = ( Width + 15 ) >> 4 ; //Antal block horisontellt int VerticalOffset , HorizontalOffset , TempOffset ; //Offsets int OffsetPerLine = Width + Border * 2 ; //Offset by one line int StartOffset = OffsetPerLine * Border + Border ; //Startoffset BYTE * CurrPtr , * PrevPtr ; //Pekare till föregående och nästa MV -ramar ProbMV ; //Trial vector long MinError , Error ; //Felvärden for ( int i = 0 ; i < BlocksPerHeight ; i ++ ) { för ( int j = 0 ; j < BlocksPerWidth ; j ++ ) { // Beräkna offsets VerticalOffset = ( i << 4 ) * OffsetPerLine + StartOffset ; HorizontalOffset = ( j << 4 ); //Set offsets för det aktuella blocket CurrPtr = CurrentFrame + VerticalOffset + HorizontalOffset ; PrevPtr = PreviousFrame + VerticalOffset + HorizontalOffset ; MinError = MAXLONG ; //Vi anser att felet är mycket stort för ( int y = - MaxMotion ; y < MaxMotion ; y ++ ) { TempOffset = y * OffsetPerLine ; //Spara på multiplikationer för ( int x = - MaxMotion ; x < MaxMotion ; x ++ ) { //GetError - blockjämförelsefunktion, t.ex. SAD Error = GetError ( CurrPtr , PrevPtr + TempOffset + x , OffsetPerLine ); //Ny kandidat :) if ( Error < MinError ) { ProbMV . x = x ; ProbMV . y = y _ MinError = Fel ; } } } //Skriv den resulterande vektorn :) MotionVectors [ i * BlocksPerWidth + j ] = ProbMV ; } } }

I det nya[ när? ] MPEG - 4 AVC/H.264-standarden introducerade också icke-kvadratiska (rektangulära) block, vars storlek kan delas upp till 4×4 pixlar . Således är det möjligt att använda likheten mellan angränsande ramar mycket effektivt, och på grund av blockens mer komplexa form ökar noggrannheten i rörelsekompensation vid gränserna för rörliga föremål. Förutom rörelsekompensation används interframe-informationskomprimering och oberoende blockkomprimering för ytterligare bildförfining (eller för nyuppkomna områden som inte fanns i tidigare bildrutor).

Förutom kompression används aktivt rörelsekompensation[ av vem? ] i videofiltrering, i synnerhet i filteralternativ av hög kvalitet: deinterlacing ( interlacing till progressiv ), brusreducering , bildhastighetsförändringar och andra.

Se även

  • rörelsekompensation

Länkar