Use this skill when creating Python scripts that target Kaggle Notebooks. This skill ensures correct cell separator format (# %% [code] and # %% [markdown]), proper markdown cell formatting (each line prefixed with #, no triple quotes), and Kaggle-specific conventions (Chinese comments, English output, %pip install). Also covers common pitfalls: OpenCV video decoding limits and Chinese text rendering with PIL.
Kaggle Notebook Format Rules
Cell Separators
- Code cells:
# %% [code] - Markdown cells:
# %% [markdown]
Markdown Cell Formatting
CRITICAL RULES:
- Every line must start with
#(hash + space) - NEVER use triple quotes (
"""or''') for markdown cells - NO empty lines with only
#- they create extra whitespace in rendered notebook
Correct markdown cell:
# %% [markdown]
# # Title
# Content line 1
# Content line 2
# - Bullet point 1
# - Bullet point 2
Code Cell Conventions
- Printed output in English
- File extension:
.py(not.ipynb) - Dataset paths:
/kaggle/input/dataset-name/ - NEVER truncate print output — 必须原样完整输出数据,禁止用
text[:100]或...截断
Package Installation
- Only install packages NOT pre-installed on Kaggle
- Use
%pip install -q package-name(not!pip install) - Common libraries (pandas, numpy, scipy, scikit-learn, torch, torchvision) are already available
Common Mistakes to Avoid
- Triple quotes in markdown cells → Use
#prefix on every line - Empty
#lines → Remove them - Missing
#prefix → Every line must start with# - Using
## Title→ Use# Titleonly - Using
!pip→ Use%pip
process video(always use ffmpeg)
example:
from IPython.display import Image, Video
import os
output_video_path='/kaggle/working/runs/detect/predict/650-1-y1_particle_video.avi'
# Using ffmpeg to compress the video to display
compressed_output_path = 'compressed_output_particle.mp4'
os.system(f'ffmpeg -i {output_video_path} -vcodec libx264 -crf 28 {compressed_output_path}')
display(Video(compressed_output_path, embed=True))
Common Pitfalls on Kaggle (实战踩坑记录)
1. 视频解码:OpenCV 读不了某些编码格式
问题: cv2.VideoCapture 在 Kaggle 上对 H.265/HEVC 等编码格式支持很差,cap.read() 返回 (False, None)。
解决方案: 用 ffmpeg 解码为 raw BGR24 格式,再用 numpy 逐帧读取:
raw_video_path = "/kaggle/working/video_raw.rgb"
subprocess.run([
"ffmpeg", "-y", "-i", VIDEO_PATH,
"-f", "rawvideo", "-pix_fmt", "bgr24",
"-v", "quiet", raw_video_path
], capture_output=True)
frame_bytes = width * height * 3
actual_frames = os.path.getsize(raw_video_path) // frame_bytes
with open(raw_video_path, "rb") as f:
for frame_idx in range(actual_frames):
raw_data = f.read(frame_bytes)
frame = np.frombuffer(raw_data, dtype=np.uint8).reshape((height, width, 3))
获取视频元信息用 ffprobe 而非 cv2:
probe = subprocess.run(
["ffprobe", "-v", "quiet", "-print_format", "json",
"-show_streams", "-select_streams", "v:0", VIDEO_PATH],
capture_output=True, text=True
)
probe_data = json.loads(probe.stdout)
vstream = probe_data["streams"][0]
width = int(vstream["width"])
height = int(vstream["height"])
fps_num, fps_den = map(int, vstream["r_frame_rate"].split("/"))
fps = fps_num / fps_den
2. OpenCV putText 不支持中文
问题: cv2.putText() 只支持 ASCII 字符,中文会显示为乱码或方块。
解决方案: 使用 PIL 绘制中文文字:
from PIL import Image, ImageDraw, ImageFont
# 字体加载(使用wget从网络下载)
font_url = "https://github.com/adobe-fonts/source-han-sans/raw/release/OTF/SimplifiedChinese/SourceHanSansSC-Regular.otf"
font_path = "/kaggle/working/fonts/SourceHanSansSC-Regular.otf"
subprocess.run(["wget", "-q", "-O", font_path, font_url], capture_output=True)
pil_font = ImageFont.truetype(font_path, font_size)
def put_text_pil(frame_bgr, text, font_color, stroke_color, stroke_width):
img_pil = Image.fromarray(cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_pil)
# 计算位置、绘制描边+正文...
draw.text((text_x, text_y), text, fill=font_color, font=pil_font)
return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
3. ffmpeg 切片:scale 参数 -1 vs -2
问题: scale=640:-1 按比例缩放时,若计算出来的高度为奇数(如 1137),H.264 编码器报错退出,输出 0 字节文件:
height not divisible by 2 (640x1137)
解决: 改用 -2,让 ffmpeg 自动向下取最近的偶数:
VIDEO_SCALE = "640:-2" # -2 保证高度为偶数(H.264 要求宽高均为偶数)