You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python+OpenCV检测视频为逐行或隔行扫描?

判断视频逐行/隔行扫描的两种方法

方法一:使用OpenCV内置属性

OpenCV提供了cv2.CAP_PROP_INTERLACED属性,可以直接查询视频的扫描类型,返回值规则如下:

  • 0:逐行扫描(progressive)
  • 1:隔行扫描(interlaced)
  • -1:无法检测(取决于视频后端支持)

你可以把这个属性查询加入到现有代码中:

cam: cv2.VideoCapture = cv2.VideoCapture(filename)

if cam.isOpened():
    video_codec: str = cam.get(cv2.CAP_PROP_FOURCC)
    video_fps: int = cam.get(cv2.CAP_PROP_FPS)
    video_height: int = cam.get(cv2.CAP_PROP_FRAME_HEIGHT)
    video_width: int = cam.get(cv2.CAP_PROP_FRAME_WIDTH)
    total_frames: int = cam.get(cv2.CAP_PROP_FRAME_COUNT)
    length: int = int(total_frames / video_fps)
    audio_samplerate: int = cam.get(cv2.CAP_PROP_AUDIO_SAMPLES_PER_SECOND)
    audio_channels: int = cam.get(cv2.CAP_PROP_AUDIO_TOTAL_CHANNELS)
    
    # 新增:查询扫描类型
    interlaced_flag = cam.get(cv2.CAP_PROP_INTERLACED)
    if interlaced_flag == 0:
        print("视频为逐行扫描")
    elif interlaced_flag == 1:
        print("视频为隔行扫描")
    else:
        print("无法通过内置属性确定扫描类型,建议使用帧内容检测法")

注意:这个属性的有效性依赖于视频的编码格式和OpenCV使用的后端(比如FFmpeg),部分老旧或特殊编码的视频可能返回-1,这时需要用第二种方法。

方法二:基于帧内容的检测(更可靠)

如果内置属性无法给出结果,可以通过分析视频帧的奇偶行差异来判断:隔行扫描的视频中,相邻帧的奇行和偶行是在不同时间捕获的,当画面有运动时,奇偶行的内容会出现明显错位。

具体实现步骤:

  1. 读取连续两帧
  2. 分离每帧的奇数行和偶数行
  3. 计算相邻帧对应行的像素差异均值
  4. 根据差异阈值判断是否为隔行扫描

代码示例:

import cv2
import numpy as np

def is_interlaced_by_frame_analysis(filename, threshold=10.0, sample_frames=5):
    cam = cv2.VideoCapture(filename)
    if not cam.isOpened():
        return None
    
    # 跳过前几帧(避免开头黑屏/静态帧)
    cam.set(cv2.CAP_PROP_POS_FRAMES, min(10, cam.get(cv2.CAP_PROP_FRAME_COUNT)-2))
    
    prev_frame = None
    diff_scores = []
    
    for _ in range(sample_frames):
        ret, frame = cam.read()
        if not ret:
            break
        if prev_frame is None:
            prev_frame = frame
            continue
        
        # 转换为灰度图减少计算量
        gray_prev = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
        gray_curr = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        
        # 分离奇偶行
        prev_odd = gray_prev[1::2, :]  # 奇数行(索引1,3,5...)
        prev_even = gray_prev[0::2, :] # 偶数行(索引0,2,4...)
        curr_odd = gray_curr[1::2, :]
        curr_even = gray_curr[0::2, :]
        
        # 计算相邻帧对应行的差异
        diff_odd = np.mean(np.abs(curr_odd - prev_even))
        diff_even = np.mean(np.abs(curr_even - prev_odd))
        avg_diff = (diff_odd + diff_even) / 2
        diff_scores.append(avg_diff)
        
        prev_frame = frame
    
    cam.release()
    
    if not diff_scores:
        return None
    
    # 取平均差异值,超过阈值则判断为隔行扫描
    avg_score = np.mean(diff_scores)
    return avg_score > threshold

# 使用示例
is_interlaced = is_interlaced_by_frame_analysis("your_video.mp4")
if is_interlaced is True:
    print("视频为隔行扫描")
elif is_interlaced is False:
    print("视频为逐行扫描")
else:
    print("无法确定视频扫描类型")

说明:

  • 阈值可以根据实际情况调整,一般运动场景下隔行视频的差异均值会远高于逐行视频
  • 跳过开头几帧是为了避免静态帧导致的误判
  • 转换为灰度图可以大幅减少计算量,不影响检测结果

内容的提问来源于stack exchange,提问作者Eelco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:15:06