FFmpeg - Zastosuj rozmycie na twarzy

25

Próbuję rozmazać fragment filmu za pomocą FFmpeg (szczególnie aby rozmazać twarz).

Próbowałem użyć kombinacji edycji osi czasu i różnych filtrów blurowania, ale nie mogę znaleźć sposobu na rozmycie tylko części filmu.

Mam nadzieję na coś takiego:

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

Gdzie width/ heightto rozmiar rozmytego pudełka i x/ yto lokalizacja rozmytego pudełka.

Czy coś takiego jest możliwe?

occvtech
źródło

Odpowiedzi:

34

Możliwe jest zastosowanie czasowego i przestrzennego rozmycia do segmentu / sekcji - przy założeniu, że obszar, który chcesz rozmazać, jest lokalizacją statyczną.

Czarny szczeniak laboratoryjny
Oryginalny obraz czarnego szczeniąt laboratoryjnych.

Korzystanie z obrazu maski

wprowadź opis zdjęcia tutajwprowadź opis zdjęcia tutaj
Obraz w skali szarości PNG i wynikowy obraz rozmazany.

Możesz zrobić obraz maski w skali szarości, aby wskazać obszar do rozmycia. Dla łatwości użycia powinien on mieć taki sam rozmiar jak obraz lub wideo, które chcesz rozmazać.

Przykład użycia alphamerge , boxblur i 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
  • Biały obszar jest miejscem rozmycia, ale można to łatwo odwrócić na przykład za pomocą filtra negacji :[1:v]negate[mask];[0:v][mask]alphamerge,boxblur=10[alf]...

  • Możesz użyć filtra geq do wygenerowania maski, takiej jak gradient.

Rozmycie określonego obszaru (bez maski)

Czarny szczeniak laboratoryjny z efektem rozmycia

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

Uwaga: Liczby przesunięcia xiy w nakładce ( 60iw 30tym przykładzie) muszą pasować do przesunięć przycięcia.

Co robi ten przykład:

  1. Przytnij kopię, aby uzyskać rozmiar obszaru do rozmycia. W tym przykładzie: pole 200 x 200 pikseli, które znajduje się 60 pikseli w prawo ( xoś) i 30 pikseli w dół ( yoś) od lewego górnego rogu.
  2. Rozmyj przycięty obszar.
  3. Nakładaj rozmazany obszar, używając tego samego xi yparametrów z filtra upraw .

Wiele plam na określonych obszarach (bez maski)

wprowadź opis zdjęcia tutaj
Zamazane obszary w lewym górnym rogu, w pobliżu środka i na dole.

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

Określony obszar nie zamazany (bez maski)

wprowadź opis zdjęcia tutaj

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

Dodatkowe rzeczy

Llogan
źródło
Dziękuję bardzo za odpowiedź. To wszystko ma sens. Na marginesie, dzięki temu filtr podzielony ma wreszcie sens! Czy można również za pomocą wyrażeń arytmetycznych dynamicznie przenosić rozmyte pole wokół obrazu? IE w celu zamazania czyjejś twarzy, gdy poruszają się one w sposób nieliniowy?
occvtech
Dzięki jeszcze raz! Zrobię to. Wiem, że edytor nieliniowy byłby tutaj 1000 razy łatwiejszy, ale mam nadzieję na przetwarzanie wsadowe wielu plików i nie chcę czekać przez proces importu / ramki klucza / eksportu. Dzięki jeszcze raz!
occvtech 16.04.15
1
czy FFMPEG oferuje inne kształty oprócz pudeł, takich jak koła?
niedz.
@ LordNeckbeard Używam cmd i chcę użyć przykładu 1, ale kiedy wykonuję kod, pojawia się ten błądUnrecognized 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 Zauważyłem, że w moim przykładowym poleceniu brakuje cytatu. Twoje polecenie powinno wyglądać 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
mniej więcej
0

Na wypadek, gdy ktoś nie lubi ostrego rozmycia, stworzyłem skrypt, który nakłada różne etapy rozmycia, aby krawędź nie była ostra i wyglądała tak:Softly_blurred_image

Zamiast tego:Oryginalny obraz

Jest to skrypt Pythona:

#!/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")

Możesz zmienić parametry w ostatniej i przedostatniej linii, ostatnie dwa parametry między znakami cudzysłowu to ścieżka do twojego wideo i wyjściowego wideo (zakładając, że są umieszczone w katalogu roboczym). W przedostatniej linii:

  • pierwsze dwie liczby wskazują rozmiar początkowego obszaru, do którego zostanie zastosowane maksymalne rozmycie,
  • drugie dwa wskazują ich współrzędne xiy,
  • trzecie dwa wskazują czasy w sekundach, w których należy zastosować rozmycie,
  • „25” w tym przykładzie oznacza, że ​​zostanie nałożone 25 pól na siebie)
  • następne „1” oznacza, że ​​większe pola z mniejszym rozmyciem powinny być tylko o jeden piksel szersze niż ich poprzednicy
  • drugie „1” oznacza, że ​​rozmycie powinno wzrosnąć o jeden, aż do maksymalnie 25 (z góry)
  • „30” oznacza margines brany pod uwagę przy stosowaniu rozmycia, więc zwiększenie tego powoduje, że rozmycie bardziej odpowiada otoczeniu. Zwiększenie tej wartości rozwiązuje również błąd tekstowy podobny doInvalid chroma radius value 21, must be >= 0 and <= 20

Uruchamiając go, należy uzyskać dane wyjściowe takie jak poniżej (jest zapisywane do pliku, który można uruchomić i wydrukować na wydruku, który można skopiować i uruchomić):

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
łyk
źródło
Jeśli ktoś wie o łatwiejszym sposobie uzyskania ostrych krawędzi, byłbym zainteresowany. Jest to również dość powolne.
sup
Zastosuj rozmycie pola do maski przed scaleniem.
Gyan
@ Gyan Co masz na myśli? Myślę, że już to robię.
sup
W każdym razie ulepszyłem kod w dalszym ciągu, nadal nie jestem pewien, czy robię to, co zaleciłeś.
sup