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

PyInstaller打包OpenCV标定程序exe后无法显示实时视频怎么办

实时相机标定程序PyInstaller打包故障排查

基础信息

  • 开发环境:Python 3.8 64位、Windows操作系统、Visual Studio Code
  • 实现功能:基于OpenCV展示相机实时采集画面,加载预先生成的标定参数对画面做去畸变校正
  • 调试阶段状态:VSCode中直接运行源码时功能完全正常,标定参数以calibration.npz文件名存储在代码同路径下,包含相机内参mtx、畸变系数dist、旋转向量rvecs、平移向量tvecs四类核心参数

相关实现代码

实时画面去畸变逻辑

h,w = frame.shape[:2]  
with np.load('calibration.npz') as X:
    mtx, dist, _ , _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 0)
mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx,(w, h), 5)
            
dst = cv2.remap(frame, mapx, mapy, cv2.INTER_LINEAR)
global dst_final       
x, y, w, h = roi
dst_final=dst[y:y+h, x:x+w]

标定参数文件生成代码

#!/usr/bin/env python

import cv2
import numpy as np
import os
import glob

CHECKERBOARD = (6,9)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

objpoints = []
imgpoints = [] 

objp = np.zeros((1, CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)*26  # 单格棋盘格边长为26mm
prev_img_shape = None

images = glob.glob('C:\\Users\\MyPc\\KHS\\test2\\*.jpg')
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE)
    
    if ret == True:
        objpoints.append(objp)
        corners2 = cv2.cornerSubPix(gray, corners, (11,11),(-1,-1), criteria)
        
        imgpoints.append(corners2)
        img = cv2.drawChessboardCorners(img, CHECKERBOARD, corners2, ret)
    
    cv2.imshow('img',img)
    cv2.waitKey(0)

cv2.destroyAllWindows()

h,w = img.shape[:2]

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 0)
mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx,(w, h), 5)
dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)
    
x, y, w, h = roi
dst=dst[y:y+h, x:x+w]
cv2.imshow('num', dst)
cv2.imshow('ori', img)
cv2.waitKey(0)

np.savez_compressed('calibration.npz',ret=ret,mtx=mtx,dist=dist,rvecs=rvecs,tvecs=tvecs)

打包命令

pyinstaller -w --ico=myico.ico --add-data *.png;. ABC.py

故障现象

未添加标定逻辑的程序版本打包为exe后可正常显示实时视频;添加标定逻辑后的exe运行无任何弹窗报错,但无法打开摄像头展示实时画面。

解决方法

  • 修复相对路径失效问题:PyInstaller打包后exe运行时的工作目录和源码运行目录不一致,直接写calibration.npz相对路径会触发文件找不到的异常,加-w参数打包的无控制台程序会直接静默吞掉这类错误,表现为程序无响应、画面不显示。在代码中添加路径解析函数,统一以exe/源码的实际所在目录为基准拼接文件路径:
    import sys
    import os
    def get_real_path(rel_path):
        if getattr(sys, 'frozen', False):
            base_dir = os.path.dirname(sys.executable)
        else:
            base_dir = os.path.dirname(os.path.abspath(__file__))
        return os.path.join(base_dir, rel_path)
    
    将原代码中np.load('calibration.npz')替换为np.load(get_real_path('calibration.npz'))即可。
  • 补全打包资源配置:当前打包命令仅将png格式文件打包进exe,未包含calibration.npz标定文件,就算路径逻辑正确也会找不到文件。修改打包命令,将npz文件加入附加资源列表:
    pyinstaller -w --ico=myico.ico --add-data *.png;. --add-data calibration.npz;. ABC.py
    
  • 排查隐藏报错:如果上述两步修改后仍存在问题,临时去掉打包命令中的-w参数,打包出带控制台窗口的版本,运行时控制台会直接打印具体错误信息,可根据报错针对性修复。
  • 优化代码性能:现有代码每一帧画面都重新计算newcameramtx、mapx、mapy三个映射参数,这三个参数仅和相机内参、采集分辨率有关,不需要逐帧重复计算,在摄像头初始化阶段计算一次即可,既能降低性能开销,也能减少异常触发概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:39:25