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

基于OpenCV检测并提取视频中最稳定的不透明电视台台标区域

Detect and Crop Static TV Logo from Frame-Averaged Video

Great start using frame averaging to blur moving elements and keep static logos sharp! Let’s build on your existing code to detect that static region, crop it, and save it as an image. Here’s a step-by-step solution:

Key Idea

Frame averaging makes moving elements blurry (since their pixels shift across frames) while static elements like logos stay crisp. To isolate the logo:

  • Calculate the absolute difference between the current frame and your averaged frame (avg2): static areas will have tiny pixel differences, while moving areas will show large discrepancies.
  • Use thresholding to create a mask of the static regions.
  • Clean up the mask with morphological operations to remove noise.
  • Find the bounding box of the logo and crop it from the sharp averaged frame.

Modified Code

Here’s the updated code that implements this logic:

import cv2
import numpy as np

c = cv2.VideoCapture('test.mp4')
# Read the first frame to initialize averages
ret, f = c.read()
if not ret:
    print("Couldn't read the video file!")
    exit()

avg1 = np.float32(f)
avg2 = np.float32(f)
# Store the final mask to capture consistently static regions
final_mask = None

while True:
    ret, f = c.read()
    if not ret:
        break  # Exit loop when video ends

    cv2.accumulateWeighted(f, avg1, 0.1)
    cv2.accumulateWeighted(f, avg2, 0.01)
    res2 = cv2.convertScaleAbs(avg2)

    # Step 1: Calculate absolute difference between current and averaged frame
    diff = cv2.absdiff(f, res2)
    gray_diff = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)

    # Step 2: Threshold to isolate static regions (low difference = static)
    _, mask = cv2.threshold(gray_diff, 10, 255, cv2.THRESH_BINARY_INV)
    # Adjust the threshold value (10) based on your video: lower = stricter static detection

    # Step 3: Clean up mask with morphological operations
    kernel = np.ones((5,5), np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)  # Fill small holes in the mask
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)   # Remove tiny noise dots

    # Update final mask to keep only consistently static regions across frames
    if final_mask is None:
        final_mask = mask
    else:
        final_mask = cv2.bitwise_and(final_mask, mask)

    # Optional: Display intermediate results for debugging
    cv2.imshow('Original Frame', f)
    cv2.imshow('Averaged Frame', res2)
    cv2.imshow('Static Mask', mask)

    # Press 'q' to exit early
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Step 4: Find the bounding box of the logo from the final mask
contours, _ = cv2.findContours(final_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if contours:
    # Grab the largest contour (assuming the logo is the biggest static region)
    largest_contour = max(contours, key=cv2.contourArea)
    x, y, w, h = cv2.boundingRect(largest_contour)

    # Step 5: Crop and save the logo from the sharp averaged frame
    logo = res2[y:y+h, x:x+w]
    cv2.imwrite('tv_logo.png', logo)
    print(f"Logo saved as tv_logo.png with dimensions {w}x{h}")
else:
    print("No static region detected! Try adjusting the threshold value.")

# Clean up resources
cv2.destroyAllWindows()
c.release()

Explanation of Key Steps

  • Absolute Difference: This highlights pixels that change between frames—static logos will have near-zero difference, making them easy to isolate.
  • Thresholding: THRESH_BINARY_INV inverts the difference so static regions appear white (255) and dynamic regions appear black (0). Tweak the threshold value if needed: increase it to reduce noise, decrease it if the logo isn’t fully captured.
  • Morphological Operations: MORPH_CLOSE fills small gaps in the mask, while MORPH_OPEN removes tiny random noise spots to get a clean outline of the logo.
  • Final Mask: By combining masks from multiple frames, we eliminate transient static spots (like a paused object) and keep only the consistently static logo.
  • Contour Detection: We find the largest contour in the final mask to get the logo’s bounding box, then crop it from the averaged frame (which has the sharpest version of the static logo).

Tips

  • If your logo has semi-transparent parts, lower the threshold value to be more lenient.
  • For longer videos, let the loop run for more frames before extracting the mask to ensure the average is stable.
  • If multiple static regions are detected, filter contours by area or aspect ratio to target the logo specifically.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:04:56