怎么识别ai换脸?先看边缘再查光影与帧率
- 2026年11月11日
- 3 次
同一个 mp4,手机小屏上连看三遍都正常,把 I 帧抽出来摊在显示器上放大到 200%,四分钟就能看到接缝。连播时接缝被运动模糊一起糊掉了,单帧不会。想知道怎么识别ai换脸,顺序比设备重要:先读容器排掉一批,再按边缘、光影、帧率三条线往下走。
先读容器:四分钟能跑完的顺序
顺序是固定的。容器信息放在最前面,因为一条命令就能把「被重新封装过」和「原片直出」分开;分不开的再去抽关键帧看边缘;边缘干净就往光影和帧间一致性上走;最后才逐帧看动作。读容器这一步跟脸没关系,可它决定了后面走不走得下去,怎么识别ai换脸难的地方就在这里。

第一步只有一条命令,输出是七行 键=值,顺序按 codec_name、width、height、r_frame_rate、avg_frame_rate、nb_frames、bit_rate 排。
ffprobe -v error -select_streams v:0 \
-show_entries stream=codec_name,width,height,\
r_frame_rate,avg_frame_rate,nb_frames,bit_rate \
-of default=nw=1 0001.mp4
重点在第 4、5 行这两个分数:r_frame_rate=30000/1001、avg_frame_rate=25/1,除下来是 29.97 和 25,差近 5 帧。ffprobe 默认给分数不给小数,要两位小数得自己拿分子除分母。差到接近 5 帧,意味着每 6 帧里大约有 1 帧是补出来的,这是「模型按 25fps 出帧、再封进 30fps 容器」留下的形状;bit_rate 2.4 Mbps 配 1080×1920 偏低,说明至少转过一次码。
但这两个值不相等不能单独当证据。固定帧率的相机直出,两值一致;手机 VFR 录的原片本来就会差出几帧,只看这一条会把没处理过的素材判成重封装。判据得加一条:两值不等,并且 nb_frames 除以 avg_frame_rate 算出的时长跟播放器对不上。437 除以 25 得 17.5 秒,对不上说明流被截断或者拼接过多段,这种片子连抽帧都不必做。
四类现象可以提前列出来,后面每条分支对应一个:边缘有均匀描边、高光不随头转、齿形在连续帧里跳、帧率对不上时长。谁先谁后按命中率排。
边缘与轮廓的拼接痕迹,放大 200% 才有意义
容器干净只说明没被粗暴重封装,不说明没换脸。往下走第二条。
第二步把 I 帧(关键帧)全部抽出来。
ffmpeg -i 0001.mp4 -vf "select='eq(pict_type,I)'" \n -fps_mode passthrough kf_%03d.png
437 帧出了 9 张,kf_001.png 到 kf_009.png。挑脸占画面最大的三张,图片查看器按到 200%,先看耳廓,再看发际线,最后看下颌线和脖子交界那一段。

耳廓的问题最好读:外缘有一圈 1 到 2 像素的半透明描边,颜色偏肤色,跟背景之间没有过渡;真实拍摄里耳朵边缘是硬边,背后是什么颜色就是什么颜色。发际线更明显,贴合时按椭圆羽化,额头上会留下一条宽度均匀的浅环,大约 3 到 5 像素,从太阳穴到另一侧几乎不变。真人的发际线是毛发一根根散出去的,宽度不可能均匀成那样。
侧脸是第二个入口。头转到 45 度以上,被遮挡那侧的耳廓经常缺一块,或者耳垂形状在相邻两张 I 帧里对不上。
这一关最容易误判的是压缩,而压缩留下的痕迹有两种,别混成一个。块效应是按 8×8 宏块边界排的方格,缩到 200% 能看出规则的格子;蚊式噪声是贴着边缘外侧两三像素的细碎抖动,像水汽。换脸的羽化描边比这两种都厚,宽度均匀且严格跟着耳朵和下巴的曲线走,不会在直线处突然变粗。
光影方向与帧间一致性:第二道筛子
边缘是空间上的破绽,光影是时间上的。真实视频里鼻梁高光和颧骨高光位置不同,但同向——头一转,两处一起移动,相对距离基本不变。换脸后的高光来自源脸,由源视频的打光决定,跟当前场景对不上,逆光场景尤其明显。
验法很土,把 9 张 I 帧里头部朝向差别最大的三张横排在一起,只看高光方向。真片子高光位置连续变化,换脸的片子某个角度会突然跳到另一侧,或者干脆消失一帧。

帧间一致性看牙齿和眼睑。播放器切到逐帧,VLC 里按 e,嘴角开始动的那几帧最容易出问题:真人说话时牙齿在运动模糊下是渐变的,模型按帧独立生成,没有跨帧约束,齿形会在连续三四帧里跳一次。眨眼同理,真人闭眼跨两帧,换脸视频常常只有一帧闭到底,中间那帧被吃了。
这两类现象要一起看。高光方向对得上、齿形又在跳,说明不是打光的问题;高光对不上而齿形正常,更像换了光源或者后期调色,不能直接判成换脸。
帧率对不上时,先怀疑重封装
帧率这条线经常被当成怎么识别ai换脸的主要依据,其实它最不可靠。
r_frame_rate 和 avg_frame_rate 都是整数、码率也正常,这条线基本给不出信息。高分辨率模型做出来的换脸,痕迹只在边缘那一层,帧率一动不动的很常见。反过来,avg_frame_rate 出现 23.976 这类电影数值而画面是手机竖屏,基本能判定过了一道转码;转码会重排 P 帧、补重复帧,异常是转码造成的,跟脸无关。
想坐实重复帧,数一遍实际解码帧数,再跟容器写的帧数比。
ffprobe -v error -count_frames -select_streams v:0 \
-show_entries stream=nb_read_frames,nb_frames \
-of default=nw=1 0001.mp4
两个数一样,说明容器没有虚报,跳帧是内容本身复制出来的;差得多,说明 nb_frames 不可信,前面的时长换算也就作废。这条命令一秒内跑完,放哪个分支开头都行。
三条都干净的那一支
三条线都过,还有一种情况:片子确实被处理过,但不是换脸,是美颜、超分或者降噪。这三类痕迹跟换脸重叠度很高——皮肤过平、边缘发软、齿形轻微跳。区别仍在耳廓:美颜和降噪不会重绘耳朵,硬边还在;换脸会连耳廓一起重画。
排错树的走法就是按命中率往下排:容器、边缘、光影与帧间一致性、帧率,前一条排除了再走后面那条,每条留一个能截图的帧号,最后一并交人工复核。
今天能做的动作很小:找你确信没被处理过的一段自拍,跑第一条 ffprobe,把 r_frame_rate 和 avg_frame_rate 两行抄在便签上。以后遇到可疑片段,先比这两行,怎么识别ai换脸的第一步就落地了,剩下的交给那 9 张关键帧。
若非作者标注皆为李涛自留地原创文章,转载或复制请以超链接形式并注明出处。
- 社死啥意思,从来源到日常用法我给你捋一遍 2026-11-08
- ChatGPT和Claude区别在哪,写作与编程怎么选 2026-11-07
- PHP cURL 实战教程:从入门到 REST API 调用 2026-06-30
- docker打开报错无法启动:从日志到守护进程的排查顺序 2026-11-07
- ZblogPHP纯代码实现文章索引目录锚点功能 2022-10-26
- 抖音限流应该如何处理,三类触发原因和我踩过的坑 2026-11-08
