GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed分析

在调试OpenCV程序时遇到'g_object_unref'错误,通常是由于对象初始化失败导致。通过检查并修正对象的初始化,例如确保图片路径正确,可以避免此类错误并使代码成功运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在调试opencv程序的时候,对于新手来说,会有很多令人恶心的错误,这些错误编译器可能检查不出来,但是程序却运行不了。例如:

(pic:6130): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed

举个例子:

int main()
{
  while(1)
  {
    IplImage* pic=cvLoadImage("ubuntu.png");
    cvShowImage("pic",pic);
    waitKey(1);
  }
}

这个代码会提示如下的错误:

sh-3.2# gst-inspect-1.0 -b (gst-plugin-scanner:5027): GStreamer-WARNING **: 19:43:08.929: Failed to load plugin '/usr/lib64/gstreamer-1.0/libgstffmpeg.so': /usr/lib64/gstreamer-1.0/libgstffmpeg.so: undefined symbol: get_primary_transferfunc size of instance = 1624 size of class = 1848 size of basesrc = 648 size of basesrcclass = 824 (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.642: cannot register existing type 'GstTypeSMVideoEnc' (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: g_param_spec_enum: assertion 'G_TYPE_IS_ENUM (enum_type)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: validate_pspec_to_install: assertion 'G_IS_PARAM_SPEC (pspec)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: g_param_spec_ref_sink: assertion 'G_IS_PARAM_SPEC (pspec)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: g_param_spec_unref: assertion 'G_IS_PARAM_SPEC (pspec)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: cannot register existing type 'GstTypeSMVideoEncDRM' (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: g_param_spec_enum: assertion 'G_TYPE_IS_ENUM (enum_type)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: validate_pspec_to_install: assertion 'G_IS_PARAM_SPEC (pspec)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: g_param_spec_ref_sink: assertion 'G_IS_PARAM_SPEC (pspec)' failed (gst-plugin-scanner:5027): GLib-GObject-CRITICAL **: 19:43:09.643: g_param_spec_unref: assertion 'G_IS_PARAM_SPEC (pspec)' failed Blacklisted files: libgstffmpeg.so Total count: 1 blacklisted file
04-01
<think>好的,我现在需要帮助用户解决他们遇到的OpenCV相关的问题。用户提供的代码是一个使用OpenCV捕获摄像头视频并保存的脚本,但运行时出现了GLib-GObject-CRITICAL错误。我需要先理解代码的结构和潜在问题。 首先,用户导入了cv2和argparse模块,设置了参数解析,然后尝试从摄像头索引3打开视频捕获。如果失败,打印错误。接着获取fps,设置视频写入参数,并创建窗口循环读取帧,直到按下ESC键退出。不过,在退出时出现了GLib的错误提示。 接下来,我需要分析可能的问题点。用户的摄像头索引是3,这可能不正确,特别是如果用户只有一个摄像头的话,通常索引是0或1。如果摄像头没正确打开,后面的操作会导致问题。例如,capture.isOpened()在初始化时检查了一次,但在循环中又检查了一次,但这里可能有问题,比如窗口创建后才进入循环,但窗口是否成功创建没有判断。 另外,在循环中,用户使用了cv2.getWindowProperty("D435", 0) >= 0来判断窗口是否关闭,但如果在某些系统或环境下窗口管理不同,这可能导致问题。例如,如果窗口未能正确创建,这个判断可能不会触发,导致循环继续执行,从而在释放资源时出现错误。 然后,用户提到在退出时出现了GLib-GObject-CRITICAL错误,这通常与资源释放有关,比如重复释放或未正确释放资源。查看代码发现,用户可能在释放capture和窗口时存在问题。在循环中,当按下ESC键时,执行break退出循环,然后执行capture.release()和cv2.destroyAllWindows()。但当前的代码缩进有误,capture.release()和destroyAllWindows()是在if keyCode == 27的块内,但break之后,这部分代码可能不会执行到,导致资源未正确释放。正确的做法应该是在循环结束后释放资源。 此外,用户可能在每次循环中没有正确读取帧,导致VideoWriter写入空帧或者未处理读取失败的情况。例如,ret, frame = capture.read()的返回值没有检查,如果读取失败,继续写入会导致问题。 总结可能的错误点: 1. 摄像头索引错误导致无法打开。 2. 窗口创建失败,但循环仍然执行。 3. 资源释放的位置不正确,导致未正确释放。 4. 未正确处理读取帧的返回值。 5. GLib相关错误可能由于资源未正确释放或重复释放引起。 需要逐步排查这些可能性,并给出解决方案。例如,建议用户检查摄像头索引是否正确,确保摄像头能被正确打开。调整资源释放的位置到循环外部,确保无论是否正常退出都能释放资源。同时,检查窗口创建是否成功,并处理读取帧时的错误情况。此外,处理可能的视频编解码器问题,如使用不同的fourcc编码器。 另外,用户可能在使用WSL或其他虚拟环境,导致摄像头访问或显示问题,需要提醒用户注意环境兼容性。最后,建议用户添加详细的错误处理和日志,帮助定位问题。</think>这个OpenCV程序存在多个需要改进的关键问题,以下从错误现象到代码结构进行系统性分析--- ### 一、核心错误分析 ```log GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed ``` 该错误通常由**资源重复释放****无效对象操作**引起,常见于以下场景: $$ \text{错误触发条件} = \begin{cases} \text{窗口未正确初始化却被销毁} \\ \text{摄像头设备重复释放} \\ \text{视频写入对象异常终止} \end{cases} $$ --- ### 二、代码结构问题排查 #### 1. 摄像头初始化逻辑缺陷 ```python capture = cv2.VideoCapture(3) # 错误风险点 if capture.isOpened() is False: print("Error") # 未终止程序继续执行 ``` * **问题**:当摄像头初始化失败时仅打印信息但继续执行后续代码 * **修复方案**: ```python if not capture.isOpened(): raise RuntimeError("无法打开摄像头,请检查设备索引号") # 强制终止 ``` #### 2. 窗口生命周期管理 ```python window_handle = cv2.namedWindow(...) # 窗口创建未验证 while cv2.getWindowProperty(...) >=0: # 依赖窗口状态作为循环条件 ``` * **问题**:窗口创建失败时循环条件仍成立,导致后续操作异常 * **改进方法**: ```python if cv2.namedWindow("D435", cv2.WINDOW_AUTOSIZE) == -1: capture.release() sys.exit("窗口创建失败") ``` #### 3. 资源释放时序错误 ```python if keyCode == 27: break capture.release() # 错误缩进导致永远无法执行 cv2.destroyAllWindows() ``` * **问题**:释放代码位于`break`之后,实际不会被执行 * **正确结构**: ```python while True: # ...循环操作... if keyCode == 27: break # 退出循环后统一释放 capture.release() out_put.release() cv2.destroyAllWindows() ``` --- ### 三、完整修复方案 ```python import cv2 import argparse import sys parser = argparse.ArgumentParser() parser.add_argument("video_output", help="输出视频路径") args = parser.parse_args() # 摄像头初始化 capture = cv2.VideoCapture(0) # 通常主摄像头为0 if not capture.isOpened(): sys.exit("错误:无法访问摄像头,请检查设备连接") # 获取实际分辨率 frame_width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = capture.get(cv2.CAP_PROP_FPS) if fps <= 0: # 处理无效帧率 fps = 30 # 视频编码器配置 fourcc = cv2.VideoWriter_fourcc(*'XVID') out_put = cv2.VideoWriter(args.video_output, fourcc, fps, (frame_width, frame_height)) # 窗口创建验证 if cv2.namedWindow("D435", cv2.WINDOW_AUTOSIZE) == -1: capture.release() sys.exit("错误:无法创建显示窗口") try: while True: ret, frame = capture.read() if not ret: print("警告:帧获取失败") break out_put.write(frame) cv2.imshow("D435", frame) if cv2.waitKey(30) & 0xFF == 27: break finally: capture.release() out_put.release() cv2.destroyAllWindows() ``` --- ### 四、关键改进点说明 1. **设备索引修正**- 将`VideoCapture(3)`改为通用索引`0` - 添加设备初始化失败时的正确退出 2. **动态分辨率获取**: ```python frame_width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) ``` 避免硬编码分辨率与摄像头实际输出不匹配 3. **异常处理增强**- 使用`try...finally`确保资源释放 - 添加帧读取失败处理 4. **编解码器兼容性**- 推荐使用`MJPG`或`H264`代替`XVID` ```python fourcc = cv2.VideoWriter_fourcc(*'MJPG') # 更通用的选择 ``` --- ### 五、扩展建议 1. **环境验证**: ```bash ls -l /dev/video* # 查看可用摄像头设备 v4l2-ctl --list-formats # 查看支持的分辨率/格式 ``` 2. **性能优化**: ```python capture.set(cv2.CAP_PROP_BUFFERSIZE, 2) # 减少缓冲区延迟 capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G')) ``` 3. **多平台适配**: ```python if sys.platform.startswith('linux'): capture.set(cv2.CAP_PROP_FOURCC, ...) # Linux特定设置 ``` 建议在WSL环境下使用摄像头时,通过`Windows Camera`应用开启设备访问权限,并通过USB重定向工具进行设备映射。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值