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

如何使用Python将OpenCV检测数据追加写入CSV并解决格式错误问题

问题原因

你的代码主要存在4个错误导致输出不符合预期:

  1. csv.writer的writerow()方法要求传入元素为每个字段值的列表,如果传入拼接好的字符串,会把每个字符单独作为一个字段写入,逗号也会被自动转义加引号,就是你看到的错误输出
  2. 写入时用了未定义的变量data_pixel,前面组装数据的变量名是data,变量名不匹配
  3. 写入CSV的代码放在了遍历图片的for循环外部,只会执行一次,没法每行存一张图片的结果
  4. w/h/ew/eh都是在人脸、眼睛检测的for循环内部定义的,如果某张图没检测到人脸/眼睛,会直接报变量未定义的错误,需要加边界判断

修改方案

前面的视频采集代码保持不变,只需要修改后面遍历图片+写入CSV的部分即可,修改后完整代码段如下:

import cv2
import os
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from csv import writer


faceCascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eyeCascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + 'haarcascade_eye.xml')

font = cv2.FONT_HERSHEY_SIMPLEX

sampel_foto = 5
counter = 1
jarak = 50
dir_name = 'C:/MyDrive'

video_capture = cv2.VideoCapture(1)
while True:
    # Capture frame-by-frame
    ret, frame = video_capture.read()
    frame_copy = frame.copy()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(
        gray, scaleFactor=1.2, flags=cv2.CASCADE_SCALE_IMAGE)
    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 3)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = frame[y:y+h, x:x+w]
        cv2.putText(frame, 'face: '+str(w)+','+str(h),
                    (10, 30), font, 0.6, (255, 255, 255), 2)
        eyes = eyeCascade.detectMultiScale(roi_gray)
        # Draw a rectangle around the eyes
        for (ex, ey, ew, eh) in eyes:
            cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)
            cv2.putText(frame, 'eyes: '+str(ew)+','+str(eh),
                        (10, 50), font, 0.6, (255, 255, 255), 2)

    if cv2.waitKey(1) & 0xFF == ord('c'):
        cv2.imwrite(f'{dir_name}{jarak}.{counter}.jpg', frame_copy)
        print(f'simpan foto ke-{counter} dengan jarak: {jarak} cm!')
        counter += 1
        if counter > sampel_foto:
            break

    # Display the resulting frame
    cv2.imshow('Video', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()

# Get list of all files only in the given directory
imfilelist = [os.path.join(dir_name, f)
              for f in os.listdir(dir_name) if f.endswith(".jpg")]

# Sort list of files based on last modification time in ascending order
list_of_files = sorted(
    imfilelist, key=lambda x: os.path.getmtime(os.path.join(dir_name, x)))

# 先打开CSV文件,避免每次循环重复打开关闭,加newline=''避免Windows下输出空行
with open('test.csv', 'a', newline='') as f_object:
    writer_object = writer(f_object)
    # 遍历每张图片
    for el in list_of_files:
        imagen = cv2.imread(el)
        gray = cv2.cvtColor(imagen, cv2.COLOR_BGR2GRAY)
        # 初始化变量,避免未定义错误
        w = h = ew = eh = 0
        roi_gray = None
        # Detect faces
        faces = faceCascade.detectMultiScale(
            gray, scaleFactor=1.2, flags=cv2.CASCADE_SCALE_IMAGE)
        if len(faces) > 0:
            x, y, w, h = faces[0] # 取检测到的第一张人脸
            cv2.rectangle(imagen, (x, y), (x + w, y + h), (0, 255, 0), 2)
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = imagen[y:y+h, x:x+w]
            # Detect eyes
            eyes = eyeCascade.detectMultiScale(roi_gray)
            if len(eyes) > 0:
                ex, ey, ew, eh = eyes[0]
                cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)
        # 组装列表,直接传数值即可不需要转字符串
        data_row = [w, h, ew, eh, jarak]
        print(','.join([str(i) for i in data_row]))
        # 仅写入有效检测结果,不需要可以删掉这个判断
        if w > 0 and ew > 0:
            writer_object.writerow(data_row)

补充说明

如果需要保留表头,可以在打开CSV后先判断文件是否为空,为空的话先写入表头行['face_width', 'face_height', 'eye_width', 'eye_height', 'distance']即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:15:05