FFmpeg - Applica la sfocatura sul viso


25

Sto cercando di sfocare una parte di un video usando FFmpeg (in particolare per sfocare un viso).

Ho cercato di utilizzare una combinazione di modifica della sequenza temporale e vari filtri di sfocatura, ma non riesco a trovare un modo per sfocare solo una sezione del video.

Spero in qualcosa del tipo:

-vf boxblur=enable='between(t,10,100)':width=20:height=20:x=400:y=200

Dove width/ heightè la dimensione della casella sfocata e x/ ysono la posizione della casella sfocata.

È possibile qualcosa del genere?

Risposte:


34

È possibile applicare la sfocatura temporale e spaziale a un segmento / sezione - supponendo che l'area che si desidera sfocare sia una posizione statica.

Cucciolo da laboratorio nero
Immagine originale del cucciolo di laboratorio nero.

Utilizzando un'immagine maschera

inserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagine
Immagine in scala di grigi PNG maschera e risultante immagine sfocata.

È possibile creare un'immagine in scala di grigi per indicare l'area da sfocare. Per facilità d'uso dovrebbe avere le stesse dimensioni dell'immagine o del video che si desidera sfocare.

Esempio con alphamerge , boxblur e overlay :

ffmpeg -i video.mp4 -i mask.png -filter_complex "[0:v][1:v]alphamerge,boxblur=10[alf];[0:v][alf]overlay[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy -movflags +faststart maskedblur.mp4
  • L'area bianca è dove si verificherà la sfocatura, ma questo può essere facilmente invertito con il filtro Negate, ad esempio:[1:v]negate[mask];[0:v][mask]alphamerge,boxblur=10[alf]...

  • È possibile utilizzare il filtro geq per generare una maschera come un gradiente.

Sfocatura area specifica (senza maschera)

Cucciolo di laboratorio nero con effetto sfocatura

ffmpeg -i derpdog.mp4 -filter_complex \
 "[0:v]crop=200:200:60:30,boxblur=10[fg]; \
  [0:v][fg]overlay=60:30[v]" \
-map "[v]" -map 0:a -c:v libx264 -c:a copy -movflags +faststart derpdogblur.mp4

Nota: i numeri di offset xey in overlay ( 60e 30in questo esempio) devono corrispondere agli offset di ritaglio.

Cosa fa questo esempio:

  1. Ritaglia la copia in modo che abbia le dimensioni dell'area da sfocare. In questo esempio: una casella di 200x200 pixel che è 60 pixel a destra ( xasse) e 30 pixel in basso ( yasse) dall'angolo in alto a sinistra.
  2. Sfoca l'area ritagliata.
  3. Sovrapponi l'area sfocata usando lo stesso xe i yparametri del filtro di ritaglio .

Sfocature multiple su aree specifiche (senza maschera)

inserisci qui la descrizione dell'immagine
Aree sfocate in alto a sinistra, vicino al centro e in basso.

"[0:v]crop=50:50:20:10,boxblur=10[b0]; \
 [0:v]crop=iw:30:(iw-ow)/2:ih-oh,boxblur=10[b1]; \
 [0:v]crop=100:100:120:80,boxblur=10[b2]; \
 [0:v][b0]overlay=20:10[ovr0]; \
 [ovr0][b1]overlay=(W-w)/2:H-h[ovr1]; \
 [ovr1][b2]overlay=120:80"

Area specifica non sfocata (senza maschera)

inserisci qui la descrizione dell'immagine

"[0:v]boxblur=10[bg];[0:v]crop=200:200:60:30[fg];[bg][fg]overlay=60:30"

Altre cose


Grazie mille per la tua risposta. Tutto ciò ha molto senso. Come nota a margine, ha anche reso finalmente sensato il filtro split! Inoltre, attraverso le espressioni aritmetiche potrebbe essere possibile spostare dinamicamente la casella sfocata attorno all'immagine? IE allo scopo di sfocare il viso di qualcuno mentre si muovono in modo non lineare?
occvtech,

Grazie ancora! Ci penserò io. So che un editor non lineare sarebbe 1000 volte più semplice qui, ma spero di elaborare in batch più file e non voglio aspettare attraverso il processo di importazione / key frame / export. Grazie ancora!
occvtech,

1
FFMPEG offre altre forme oltre alle scatole, come i cerchi?
Dom

@LordNeckbeard Sto usando cmd e voglio usare l'Esempio 1 ma quando eseguo il codice ottengo questo erroreUnrecognized option 'filter_complex[0:v]crop=200:200:60:30,boxblur=10[fg];[0:v][fg]overlay=60:30[v]-map [v] -map 0:a -c:v libx264 -c:a copy -movflags +faststart output.mp4'. Error splitting the argument list: Option not found
Jim,

1
@Jim Ho notato che il mio comando di esempio mancava un preventivo. Dovresti avere un aspetto simile al seguente:ffmpeg -i input.mp4 -filter_complex "[0:v]crop=200:200:60:30,boxblur=10[fg]; [0:v][fg]overlay=60:30[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy -movflags +faststart output.mp4
llogan,

0

Nel caso in cui uno non ami il bordo tagliente della sfocatura, ho creato una sceneggiatura che sovrappone diversi livelli di sfocatura in modo che il bordo non sia nitido e assomigli a questo:Softly_blurred_image

Invece di questo:Immagine originale

È uno script Python:

#!/usr/bin/env python3
import os,stat
def blur_softly(matrix,video_in="video_to_be_blurred.mp4",video_out=""):
    if video_out == "":
        video_out = video_in[:-4] + "_blurred" + video_in[-4:]
    s0 = "ffmpeg -i " + video_in + " -filter_complex \\\n\"[0:v]null[v_int0]; \\\n"
    s1 = ''
    a = 0
    for m in matrix:
        blur = m[6]
        multiple = m[7]
        width = m[0]+blur*multiple*2
        height = m[1]+blur*multiple*2
        x_cord = m[2]-blur*multiple
        y_cord = m[3]-blur*multiple
        timein = m[4]
        timeout = m[5]
        step = m[8]
        margin = m[9]
        for i in range(blur):
            ii = multiple*i
            s0 = s0 + "[v_int0]crop="+str(width-2*ii+(margin//2)*2)+":"+str(height-2*ii+(margin//2)*2)+":"+str(x_cord+ii-margin//2)+":"+str(y_cord+ii-margin//2) + \
            ",boxblur="+str((i+1)*step)+":enable='between(t,"+str(timein)+","+str(timeout)+ \
            ")',crop="+str(width-2*ii)+ ":"+str(height-2*ii)+":"+str(margin//2)+":"+str(margin//2)+ "[blur_int" + str(i+1+a)+"]; \\\n"
            s1 = s1 + "[v_int"+ str(i+a) +"][blur_int"+str(i+a+1)+"]overlay="+str(x_cord+ii)+":"+str(y_cord+ii)+":enable='between(t,"+str(timein)+","+str(timeout)+ ")'[v_int"+str(i+a+1)+"]; \\\n"
        a += i+1
    s = s0 + s1 + "[v_int"+str(a)+"]null[with_subtitles]\" \\\n-map \"[with_subtitles]\" -map 0:a -c:v libx264 -c:a copy -crf 17 -preset slow -y "+video_out+"\n"
    print(s)
    file_object = open('blur.sh', 'w')
    file_object.write(s)
    file_object.close()
    st = os.stat('blur.sh')
    os.chmod('blur.sh', st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
#w,h,x,y,timein,timeout,blur,multiple,step,margin
matrix = [[729,70,599,499,14.96,16.40,25,1,1,90],]
blur_softly(matrix,video_in="your_video.mp4",video_out="output_video.mp4")

È possibile modificare i parametri nell'ultima e penultima riga, gli ultimi due parametri tra i segni di quatazione sono il percorso del video e il video di output (supponendo che siano collocati nella directory di lavoro). Nella penultima riga:

  • i primi due numeri indicano la dimensione dell'area iniziale a cui verrà applicata la sfocatura massima,
  • le seconde due indicano le sue coordinate xey,
  • le terze due indicano i tempi in secondi in cui applicare la sfocatura,
  • "25" in questo esempio indica che saranno applicate 25 caselle una sopra l'altra)
  • il successivo "1" indica che le scatole più grandi con meno sfocatura dovrebbero essere solo un pixel più larghe rispetto ai loro predecessori
  • il secondo "1" indica che la sfocatura dovrebbe aumentare di uno fino a un massimo di 25 (dall'alto)
  • "30" indica il margine che viene preso in considerazione per l'applicazione della sfocatura, quindi aumentando ciò la sfocatura rispetta maggiormente l'ambiente circostante. L'aumento di questo valore risolve anche l'errore comeInvalid chroma radius value 21, must be >= 0 and <= 20

Eseguendolo, si dovrebbe ottenere un output come il seguente (viene scritto in un file che può essere eseguito e stampato sull'output che può essere copiato e eseguito):

ffmpeg -i video_to_be_blurred.mp4 -filter_complex \
"[0:v]null[v_int0]; \
[v_int0]crop=869:210:529:429,boxblur=1:enable='between(t,14.96,16.4)',crop=779:120:45:45[blur_int1]; \
[v_int0]crop=867:208:530:430,boxblur=2:enable='between(t,14.96,16.4)',crop=777:118:45:45[blur_int2]; \
[v_int0]crop=865:206:531:431,boxblur=3:enable='between(t,14.96,16.4)',crop=775:116:45:45[blur_int3]; \
[v_int0]crop=863:204:532:432,boxblur=4:enable='between(t,14.96,16.4)',crop=773:114:45:45[blur_int4]; \
[v_int0]crop=861:202:533:433,boxblur=5:enable='between(t,14.96,16.4)',crop=771:112:45:45[blur_int5]; \
[v_int0]crop=859:200:534:434,boxblur=6:enable='between(t,14.96,16.4)',crop=769:110:45:45[blur_int6]; \
[v_int0]crop=857:198:535:435,boxblur=7:enable='between(t,14.96,16.4)',crop=767:108:45:45[blur_int7]; \
[v_int0]crop=855:196:536:436,boxblur=8:enable='between(t,14.96,16.4)',crop=765:106:45:45[blur_int8]; \
[v_int0]crop=853:194:537:437,boxblur=9:enable='between(t,14.96,16.4)',crop=763:104:45:45[blur_int9]; \
[v_int0]crop=851:192:538:438,boxblur=10:enable='between(t,14.96,16.4)',crop=761:102:45:45[blur_int10]; \
[v_int0]crop=849:190:539:439,boxblur=11:enable='between(t,14.96,16.4)',crop=759:100:45:45[blur_int11]; \
[v_int0]crop=847:188:540:440,boxblur=12:enable='between(t,14.96,16.4)',crop=757:98:45:45[blur_int12]; \
[v_int0]crop=845:186:541:441,boxblur=13:enable='between(t,14.96,16.4)',crop=755:96:45:45[blur_int13]; \
[v_int0]crop=843:184:542:442,boxblur=14:enable='between(t,14.96,16.4)',crop=753:94:45:45[blur_int14]; \
[v_int0]crop=841:182:543:443,boxblur=15:enable='between(t,14.96,16.4)',crop=751:92:45:45[blur_int15]; \
[v_int0]crop=839:180:544:444,boxblur=16:enable='between(t,14.96,16.4)',crop=749:90:45:45[blur_int16]; \
[v_int0]crop=837:178:545:445,boxblur=17:enable='between(t,14.96,16.4)',crop=747:88:45:45[blur_int17]; \
[v_int0]crop=835:176:546:446,boxblur=18:enable='between(t,14.96,16.4)',crop=745:86:45:45[blur_int18]; \
[v_int0]crop=833:174:547:447,boxblur=19:enable='between(t,14.96,16.4)',crop=743:84:45:45[blur_int19]; \
[v_int0]crop=831:172:548:448,boxblur=20:enable='between(t,14.96,16.4)',crop=741:82:45:45[blur_int20]; \
[v_int0]crop=829:170:549:449,boxblur=21:enable='between(t,14.96,16.4)',crop=739:80:45:45[blur_int21]; \
[v_int0]crop=827:168:550:450,boxblur=22:enable='between(t,14.96,16.4)',crop=737:78:45:45[blur_int22]; \
[v_int0]crop=825:166:551:451,boxblur=23:enable='between(t,14.96,16.4)',crop=735:76:45:45[blur_int23]; \
[v_int0]crop=823:164:552:452,boxblur=24:enable='between(t,14.96,16.4)',crop=733:74:45:45[blur_int24]; \
[v_int0]crop=821:162:553:453,boxblur=25:enable='between(t,14.96,16.4)',crop=731:72:45:45[blur_int25]; \
[v_int0][blur_int1]overlay=574:474:enable='between(t,14.96,16.4)'[v_int1]; \
[v_int1][blur_int2]overlay=575:475:enable='between(t,14.96,16.4)'[v_int2]; \
[v_int2][blur_int3]overlay=576:476:enable='between(t,14.96,16.4)'[v_int3]; \
[v_int3][blur_int4]overlay=577:477:enable='between(t,14.96,16.4)'[v_int4]; \
[v_int4][blur_int5]overlay=578:478:enable='between(t,14.96,16.4)'[v_int5]; \
[v_int5][blur_int6]overlay=579:479:enable='between(t,14.96,16.4)'[v_int6]; \
[v_int6][blur_int7]overlay=580:480:enable='between(t,14.96,16.4)'[v_int7]; \
[v_int7][blur_int8]overlay=581:481:enable='between(t,14.96,16.4)'[v_int8]; \
[v_int8][blur_int9]overlay=582:482:enable='between(t,14.96,16.4)'[v_int9]; \
[v_int9][blur_int10]overlay=583:483:enable='between(t,14.96,16.4)'[v_int10]; \
[v_int10][blur_int11]overlay=584:484:enable='between(t,14.96,16.4)'[v_int11]; \
[v_int11][blur_int12]overlay=585:485:enable='between(t,14.96,16.4)'[v_int12]; \
[v_int12][blur_int13]overlay=586:486:enable='between(t,14.96,16.4)'[v_int13]; \
[v_int13][blur_int14]overlay=587:487:enable='between(t,14.96,16.4)'[v_int14]; \
[v_int14][blur_int15]overlay=588:488:enable='between(t,14.96,16.4)'[v_int15]; \
[v_int15][blur_int16]overlay=589:489:enable='between(t,14.96,16.4)'[v_int16]; \
[v_int16][blur_int17]overlay=590:490:enable='between(t,14.96,16.4)'[v_int17]; \
[v_int17][blur_int18]overlay=591:491:enable='between(t,14.96,16.4)'[v_int18]; \
[v_int18][blur_int19]overlay=592:492:enable='between(t,14.96,16.4)'[v_int19]; \
[v_int19][blur_int20]overlay=593:493:enable='between(t,14.96,16.4)'[v_int20]; \
[v_int20][blur_int21]overlay=594:494:enable='between(t,14.96,16.4)'[v_int21]; \
[v_int21][blur_int22]overlay=595:495:enable='between(t,14.96,16.4)'[v_int22]; \
[v_int22][blur_int23]overlay=596:496:enable='between(t,14.96,16.4)'[v_int23]; \
[v_int23][blur_int24]overlay=597:497:enable='between(t,14.96,16.4)'[v_int24]; \
[v_int24][blur_int25]overlay=598:498:enable='between(t,14.96,16.4)'[v_int25]; \
[v_int25]null[with_subtitles]" \
-map "[with_subtitles]" -map 0:a -c:v libx264 -c:a copy -crf 17 -slow preset -y video_to_be_blurred_blurred.mp4

Se qualcuno fosse a conoscenza di un modo più semplice per ottenere bordi sfocati, sarei interessato. Inoltre, questo è piuttosto lento.
sup

Applicare una sfocatura casella alla maschera prima di fonderla.
Gyan,

@Gyan Che vuoi dire? Penso che lo sto già facendo.
sup

Comunque, ho ulteriormente migliorato il codice, non sono ancora sicuro di fare quello che mi hai raccomandato.
sup
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.