You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.9 KiB
88 lines
2.9 KiB
import cv2
|
|
import numpy as np
|
|
import sys
|
|
|
|
def convert_to_red_pseudo_color(input_path, output_path):
|
|
cap = cv2.VideoCapture(input_path)
|
|
if not cap.isOpened():
|
|
print("❌ 无法打开视频")
|
|
return
|
|
|
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
|
|
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
|
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
|
|
|
|
# 基础色 #f21762 (BGR 顺序)
|
|
#base_b, base_g, base_r = 98, 23, 242
|
|
# f80b5b
|
|
base_b, base_g, base_r = 91, 11, 248
|
|
# f31347
|
|
#base_b, base_g, base_r = 71, 19, 243
|
|
##b60430
|
|
#base_b, base_g, base_r = 48, 4, 182
|
|
|
|
|
|
# # 锐化核(锐度70)
|
|
# sharpen_kernel = np.array([[-0.7, -0.7, -0.7],
|
|
# [-0.7, 6.6, -0.7],
|
|
# [-0.7, -0.7, -0.7]], dtype=np.float32)
|
|
|
|
frame_count = 0
|
|
while True:
|
|
ret, frame = cap.read()
|
|
if not ret:
|
|
break
|
|
|
|
# 1. 灰度 + 明暗反转(亮变暗,暗变亮)
|
|
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
|
gray_inverted = 255 - gray
|
|
|
|
# 2. 归一化亮度 0~1
|
|
t = gray_inverted / 255.0
|
|
|
|
# 3. 关键:双向渐变 黑色 → #f21762 → 白色
|
|
# t < 0.5: 黑色到基础色的渐变
|
|
# t >= 0.5: 基础色到白色的渐变
|
|
pseudo = np.zeros_like(frame, dtype=np.float32)
|
|
|
|
# 4. 亮度提升100% + 对比度70
|
|
pseudo = cv2.convertScaleAbs(pseudo, alpha=2.0, beta=1000)
|
|
|
|
# 双向插值公式
|
|
mask_low = t < 0.5 # 暗区:黑 → 基础色
|
|
mask_high = t >= 0.5 # 亮区:基础色 → 白
|
|
|
|
# 暗区:从黑色(0)渐变到基础色
|
|
pseudo[mask_low, 0] = base_b * (t[mask_low] / 0.5)
|
|
pseudo[mask_low, 1] = base_g * (t[mask_low] / 0.5)
|
|
pseudo[mask_low, 2] = base_r * (t[mask_low] / 0.5)
|
|
|
|
# 亮区:从基础色渐变到白色(255)
|
|
t_high = (t[mask_high] - 0.5) / 0.5 # 重新映射到 0~1
|
|
pseudo[mask_high, 0] = base_b + t_high * (255 - base_b)
|
|
pseudo[mask_high, 1] = base_g + t_high * (255 - base_g)
|
|
pseudo[mask_high, 2] = base_r + t_high * (255 - base_r)
|
|
|
|
pseudo = np.clip(pseudo, 0, 255).astype(np.uint8)
|
|
|
|
# 5. 锐度70
|
|
# pseudo = cv2.filter2D(pseudo, -1, sharpen_kernel)
|
|
|
|
out.write(pseudo)
|
|
frame_count += 1
|
|
if frame_count % 100 == 0:
|
|
print(f"处理进度: {frame_count}/{total_frames}")
|
|
|
|
cap.release()
|
|
out.release()
|
|
print("🎉 完成 | #f80b5b 平滑双向渐变 + 反转 + 亮度/对比度/锐度")
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 3:
|
|
print("用法:python 脚本.py 输入.mp4 输出.mp4")
|
|
else:
|
|
convert_to_red_pseudo_color(sys.argv[1], sys.argv[2])
|