在使用 GDB 调试 C++ OpenCV 程序时,为了直观查看程序中的图像数据,需要将 cv::Mat 对象的可视化。本文介绍了如何使用 GDB 的 Python 界面和 OpenCV 的 Python 接口来实现 cv::Mat 对象的可视化。
2、解决方案
首先,确保您的 GDB 已启用 Python 支持,并已安装 Python、NumPy 和 OpenCV 的 Python 接口。然后,可以按照以下步骤操作:
- 创建一个 Python 脚本 cvplot.py,内容如下:
import gdb
import cv2.cv as cv
import sys

class PlotterCommand(gdb.Command):
def __init__(self):
super(PlotterCommand, self).__init__("plot",
gdb.COMMAND_DATA,
gdb.COMPLETE_SYMBOL)
def invoke(self, arg, from_tty):
args = gdb.string_to_argv(arg)
# 一般情况下,我们在 GDB 命令行中输入 "plot someimage",其中 "someimage" 是 cv::Mat 的一个实例
v = gdb.parse_and_eval(args[0])
# v 是一个 gdb.Value 对象,它表示 C++ 代码中的 cv::Mat,我们需要将其转换为 cv2.cv 中的一个 Python 对象
image_size = (v['cols'],v['rows'])
# print v
# 下面这两行代码不起作用,原因不明
# channel = gdb.execute("call "+ args[0] + ".channels()", False, True)
# channel = v.channels();
CV_8U =0
CV_8S =1
CV_16U=2
CV_16S=3
CV_32S=4
CV_32F=5
CV_64F=6
CV_USRTYPE1=7
CV_CN_MAX = 512
CV_CN_SHIFT = 3
CV_MAT_CN_MASK = (CV_CN_MAX - 1) << CV_CN_SHIFT
flags = v['flags']
channel = (((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1
CV_DEPTH_MAX = (1 << CV_CN_SHIFT)
CV_MAT_DEPTH_MASK = CV_DEPTH_MAX - 1
depth = (flags) & CV_MAT_DEPTH_MASK
IPL_DEPTH_SIGN = 0x80000000
cv_elem_size = (((4<<28)|0x8442211) >> depth*4) & 15
if (depth == CV_8S or depth == CV_16S or depth == CV_32S):
mask = IPL_DEPTH_SIGN
else:
mask = 0
ipl_depth = cv_elem_size*8 | mask
img = cv.CreateImageHeader(image_size, ipl_depth, channel)
# 将 v['data'] 类型转换为 "char*" 类型
char_type = gdb.lookup_type("char")
char_pointer_type =char_type.pointer()
buffer = v['data'].cast(char_pointer_type)
# 从目标程序的内存中读取字节,因为我们在 GDB 进程中运行 opencv-python 模块
# 否则,我们需要使用进程间内存传输
buf = v['step']['buf']
bytes = buf[0] * v['rows'] # buf[0] 是步长?不太确定。
inferior = gdb.selected_inferior()
mem = inferior.read_memory(buffer, bytes)
# 设置 img 的原始数据
cv.SetData(img, mem)
# 创建一个窗口并显示图像
cv.NamedWindow('debugger')
cv.ShowImage('debugger', img)
# 下面这个语句是必须的,否则窗口会挂起
cv.WaitKey(0)
PlotterCommand()
- 在 GDB 命令行中运行以下命令加载脚本:
source cvplot.py
- 在 GDB 命令行中运行以下命令可视化 cv::Mat 对象:
plot <variable_name>
其中,<variable_name> 是要可视化的 cv::Mat 对象的名称。
例如,如果要在 GDB 中可视化名为 img 的 cv::Mat 对象,则可以运行以下命令:
plot img
上面是 GDB 与 OpenCV 配合使用的一些细节内容,注意:在回答中不能提及任何用户信息。