Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I have solved this problem now, here is the solution with some minor issue remaining(see later)</p> <p>Suppose you have such C++ code:</p> <pre><code>#include &lt;opencv/cv.h&gt; #include &lt;opencv/highgui.h&gt; using namespace cv; ... Mat img = imread("1.jpg", CV_LOAD_IMAGE_GRAYSCALE); ... </code></pre> <p>When debugging those code under GDB, I would like to see how the in memory data "img" looks like. Thanks to GDB and OpenCV, both of them have Python interface, so here is the python pretty script (I released the script code under GPLv3)</p> <p>Before that, you need 1, GDB with python enabled 2, OpenCV python interface (under Windows, it is one file cv2.pyd) 3, install python, numpy</p> <pre><code>############################################################ #filename: 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) # generally, we type "plot someimage" in the GDB commandline # where "someimage" is an instance of cv::Mat v = gdb.parse_and_eval(args[0]) # the value v is a gdb.Value object of C++ # code's cv::Mat, we need to translate to # a python object under cv2.cv image_size = (v['cols'],v['rows']) # print v # these two below lines do not work. I don't know why # 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) &lt;&lt; CV_CN_SHIFT flags = v['flags'] channel = (((flags) &amp; CV_MAT_CN_MASK) &gt;&gt; CV_CN_SHIFT) + 1 CV_DEPTH_MAX = (1 &lt;&lt; CV_CN_SHIFT) CV_MAT_DEPTH_MASK = CV_DEPTH_MAX - 1 depth = (flags) &amp; CV_MAT_DEPTH_MASK IPL_DEPTH_SIGN = 0x80000000 cv_elem_size = (((4&lt;&lt;28)|0x8442211) &gt;&gt; depth*4) &amp; 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) # conver the v['data'] type to "char*" type char_type = gdb.lookup_type("char") char_pointer_type =char_type.pointer() buffer = v['data'].cast(char_pointer_type) # read bytes from inferior's memory, because # we run the opencv-python module in GDB's own process # otherwise, we use memory corss processes buf = v['step']['buf'] bytes = buf[0] * v['rows'] # buf[0] is the step? Not quite sure. inferior = gdb.selected_inferior() mem = inferior.read_memory(buffer, bytes) # set the img's raw data cv.SetData(img, mem) # create a window, and show the image cv.NamedWindow('debugger') cv.ShowImage('debugger', img) # the below statement is necessory, otherwise, the Window # will hang cv.WaitKey(0) PlotterCommand() ############################################################ </code></pre> <p>The script above add a new GDB command "plot" to show the in memory data cv::Mat. Now, you can simply type: "source cvplot.py" to load this script to GDB, then type: "plot img" to show the cv::Mat in OpenCV's Window, to let GDB continue, just close the debugger window.</p> <p>BTW: I found one issue, if I uncomment "# print v" in the script source, then this script will complain such message and abort:</p> <pre><code>Python Exception &lt;type 'exceptions.UnicodeEncodeError'&gt; 'ascii' codec can't encode characters in position 80-100: ordinal not in range(128): Error occurred in Python command: 'ascii' codec can't encode characters in position 80-100: ordinal not in range(128) </code></pre> <p>But if I run the command "print img" directly in the GDB's command line, it shows:</p> <pre><code>$2 = {flags = 1124024320, dims = 2, rows = 243, cols = 322, data = 0xb85020 "\370\362èèé?èè?èé?è?è?èèèèèèè\372\357èèèèèèèèèèèèèèè?è?èèèè???èè?èéèèè?èè??èèèéèééèèèèèèèèèèèèèèèè?è?èèèèèèè?èèè?è"..., refcount = 0xb981c8, datastart = 0xb85020 "\370\362èèé?èè?èé?è?è?èèèèèèè\372\357èèèèèèèèèèèèèèè?è?èèèè???èè?èéèèè?èè??èèèéèééèèèèèèèèèèèèèèèè?è?èèèèèèè?èèè?è"..., dataend = 0xb981c6 "\255\272\001", datalimit = 0xb981c6 "\255\272\001", allocator = 0x0, size = {p = 0x22fe64}, step = {p = 0x22fe8c, buf = {322, 1}}} </code></pre> <p>I'm not sure how to fix this, but surely I can see it was some issue that python try to decode the raw buffer to normal text. (I'm using WinXP)</p> <p>Many thanks to Tromey, Andre_, Pmuldoon for their kind help in GDB IRC, also thanks to Hui Ning for great help and suggestion, the solution also posted in GDB maillist <a href="https://sourceware.org/ml/gdb/2013-04/msg00104.html" rel="nofollow">Post in GDB maillist</a>, also I would like to contribute this to OpenCV community<a href="http://answers.opencv.org/question/25092/visualize-in-memory-opencv-image-or-matrix-from/" rel="nofollow">Visualize in memory OpenCV image or matrix from GDB pretty printers</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload