FFmpeg - Appliquer un flou sur le visage

25

J'essaie de brouiller une partie d'une vidéo en utilisant FFmpeg (spécifiquement pour brouiller un visage).

J'ai essayé d'utiliser une combinaison de montage chronologique et les différents filtres de flou, mais je ne trouve pas de moyen de flouter seulement une section de la vidéo.

J'espère quelque chose comme:

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

width/ heightest la taille de la boîte floue et x/ ysont l'emplacement de la boîte floue.

Est-ce que quelque chose comme ça est possible?

occvtech
la source

Réponses:

34

Il est possible d'appliquer un flou temporel et spatial à un segment / une section - en supposant que la zone à flouter est un emplacement statique.

Chiot de laboratoire noir
Image originale de chiot de laboratoire noir.

Utilisation d'une image de masque

entrez la description de l'image icientrez la description de l'image ici
Image de masque PNG en niveaux de gris et image floue résultante.

Vous pouvez créer une image de masque en niveaux de gris pour indiquer la zone à estomper. Pour plus de facilité d'utilisation, elle doit être de la même taille que l'image ou la vidéo que vous souhaitez flouter.

Exemple utilisant alphamerge , boxblur et 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
  • La zone blanche est l'endroit où le flou se produira, mais cela peut facilement être inversé avec le filtre négatif par exemple:[1:v]negate[mask];[0:v][mask]alphamerge,boxblur=10[alf]...

  • Vous pouvez utiliser le filtre geq pour générer un masque tel qu'un dégradé.

Flou d'une zone spécifique (sans masque)

Chiot de laboratoire noir avec effet de flou

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

Remarque: Les nombres de décalage x et y dans la superposition ( 60et 30dans cet exemple) doivent correspondre aux décalages de recadrage.

Ce que fait cet exemple:

  1. Recadrez la copie à la taille de la zone à rendre floue. Dans cet exemple: une zone de 200x200 pixels qui est de 60 pixels à droite ( xaxe) et 30 pixels vers le bas ( yaxe) à partir du coin supérieur gauche.
  2. Flou la zone recadrée.
  3. Superposez la zone floue en utilisant les mêmes paramètres xet les yparamètres du filtre de recadrage .

Flous multiples sur des zones spécifiques (sans masque)

entrez la description de l'image ici
Zones floues en haut à gauche, près du centre et en bas.

"[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"

Zone spécifique non floue (sans masque)

entrez la description de l'image ici

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

Trucs supplémentaires

llogan
la source
Merci beaucoup pour ta réponse. Tout cela est très logique. En remarque, cela a également donné un sens au filtre divisé! En outre, pourrait-il être possible grâce à des expressions arithmétiques de déplacer dynamiquement la zone floue autour de l'image? IE dans le but de brouiller le visage d'une personne qui se déplace de façon non linéaire?
occvtech
Merci encore! Je vais essayer de le faire. Je sais qu'un éditeur non linéaire serait 1000 fois plus facile ici, mais j'espère traiter plusieurs fichiers par lots et je ne veux pas attendre le processus d'importation / image clé / exportation. Merci encore!
occvtech
1
FFMPEG offre-t-il d'autres formes que les boîtes, comme les cercles?
dim
@LordNeckbeard J'utilise cmd et je veux utiliser l'exemple 1 mais lorsque j'exécute le code, j'obtiens cette erreurUnrecognized 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 J'ai remarqué qu'il manquait un devis à mon exemple de commande. Votre commande devrait ressembler à ceci: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

Pour le cas où l'on n'aime pas le bord tranchant du flou, j'ai fait un script qui superpose différentes étapes de flou afin que le bord ne soit pas net et qu'il ressemble à ceci:Softly_blurred_image

Au lieu de cela:Image originale

Il s'agit d'un 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")

Vous pouvez modifier les paramètres dans la dernière et l'avant-dernière ligne, les deux derniers paramètres entre les marques de quatation sont le chemin vers votre vidéo et la vidéo de sortie (en supposant qu'ils soient placés dans le répertoire de travail). Dans l'avant-dernière ligne:

  • les deux premiers chiffres indiquent la taille de la zone initiale à laquelle le flou maximum sera appliqué,
  • les deux seconds indiquent leurs coordonnées x et y,
  • les trois derniers indiquent les temps en secondes où le flou doit être appliqué,
  • "25" dans cet exemple indique qu'il y aura 25 cases appliquées les unes sur les autres)
  • le "1" suivant indique que les boîtes plus grandes avec moins de flou devraient être juste un pixel plus larges que leurs prédécesseurs
  • le deuxième "1" indique que le flou doit augmenter de un jusqu'à ce que jusqu'à 25 maximum (par le haut)
  • "30" indique la marge qui est prise en considération pour appliquer le flou, donc augmenter cette valeur rend le flou plus respectueux de son environnement. L'augmentation de cette valeur résout également l'erreur textée commeInvalid chroma radius value 21, must be >= 0 and <= 20

En l'exécutant, on devrait obtenir une sortie comme celle-ci (elle est écrite dans un fichier qui peut être exécuté et imprimé sur la sortie qui peut être copypastée et exécutée):

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
souper
la source
Si quelqu'un connaît un moyen plus facile d'obtenir des bords flous, je serais intéressé. De plus, c'est plutôt lent.
sup
Appliquez une zone floue sur le masque avant de le fusionner.
Gyan
@Gyan Que voulez-vous dire? Je pense que je le fais déjà.
sup
Quoi qu'il en soit, j'ai amélioré le code plus loin, je ne suis toujours pas sûr de faire ce que vous avez recommandé.
sup