Debug helper for visualizing images



  • I'd like to make a debug visualizer for displaying image data similar to this product:
    https://visualstudiogallery.msdn.microsoft.com/e682d542-7ef3-402c-b857-bbfba714f78d
    Except for GDB in qt creator.
    Does anyone know if this is possible? All the examples I've seen show displaying custom text data in the same variable watch window, but I'm more interested in spawning a dialog that can display images.

    Is this possible with qtcreator? What kind of effort is required and where can I learn how to do this?



  • It's possible. See e.g. http://blog.qt.digia.com/blog/2010/04/22/peek-and-poke-vol-3/. Syntax has changed a bit since then, but the feature is there.



  • Excellent assistance, I've sorted out all the issues getting my debugger run.

    Now I'm just running into an issue getting it to actually dump the image and display it.
    Here is what I have so far:
    @
    #!/usr/bin/python
    from dumper import *

    def qform__cv__Mat():
    return "Normal,Displayed"

    def qdump__cv__Mat(d, value):
    cols = value["cols"]
    rows = value["rows"]
    flags = value["flags"]
    depth = flags & 7
    channels = 1 + (flags >> 3) & 63
    line_step = value['step']['p'][0]

    if depth == 0:
        d.putValue("(%dx%dx%d) CV_8U" %(rows,cols,channels))
    if depth == 1:
        d.putValue("(%dx%dx%d) CV_8S" %(rows,cols,channels))
    if depth == 2:
        d.putValue("(%dx%dx%d) CV_16U" %(rows,cols,channels))
    
    if depth == 3:
        d.putValue("(%dx%dx%d) CV_16S" %(rows,cols,channels))
    
    if depth == 4:
        d.putValue("(%dx%dx%d) CV_32S" %(rows,cols,channels))
    
    if depth == 5:
        d.putValue("(%dx%dx%d) CV_32F" %(rows,cols,channels))
    
    if depth == 6:
        d.putValue("(%dx%dx%d) CV_64F" %(rows,cols,channels))
    
    line_step = value['step']['p'][0]
    data_start = value['data']
    #data_start = d.extractPointer(d.addressOf(value['datatstart']))
    data_end = value['dataend']
    nbytes = data_end - data_start
    nbytes = rows * cols * channels
    d.putNumChild(1)
    padding = line_step - cols * channels
    bits = d.extractPointer(data_start)
    with Children(d):
       d.putSubItem("Data start", data_start)
       d.putSubItem("Rows", rows)
       d.putSubItem("Cols", cols)
       d.putSubItem("Channels", channels)
       d.putSubItem("Depth", depth)
       d.putSubItem("Num Bytes", nbytes)
       d.putSubItem("Data end", data_end)
       d.putSubItem("Row Step", line_step)
       d.putSubItem("Padding", padding)
       with SubItem(d, "data"):
           d.putValue("0x%x" % bits)
           d.putNumChild(0)
           d.putType("void *")
    format = d.currentItemFormat()
    if format == 1:
        d.putDisplay(StopDisplay)
    if format == 2:
        #file = tempfile.mkstemp(prefix="gdbpy_")
        #filename = file[1].replace("\\", "\\\\")
        #gdb.execute("dump binary memory %s %s %s" % (filename, bits, bits + nbytes))
        #d.putDisplay(DisplayImageFile, " %d %d %d %d %s" % (cols, rows, nbytes, channels, filename))
        d.putField("editformat", DisplayImageData)
        d.put('editvalue="')
        d.put('xxxx' % (cols, rows, nbytes, channels))
        d.put(d.readMemory(bits,nbytes))
        d.put('",')
    

    @
    This dumps all the requested information nicely, but the problem lies in actually viewing the image now.
    In a simple test program, I make a QImage and then load a cv::Mat, I can then view the QImage through change local display format > Displayed. This option however doesn't exist for the cv::Mat.

    Here is a section of test code:
    @
    QImage im(QSize(200, 200), QImage::Format_RGB32);
    im.fill(QColor(200, 10, 30).rgba());
    QPainter p;
    p.begin(&im);
    p.setPen(QPen(Qt::black, 5.0, Qt::SolidLine, Qt::RoundCap));
    p.drawEllipse(20, 20, 160, 160);
    p.drawArc(70, 115, 60, 30, 200 * 16, 140 * 16);
    p.setBrush(Qt::black);
    p.drawEllipse(65, 70, 15, 15);
    p.drawEllipse(120, 70, 15, 15);
    p.end();
    ui->setupUi(this);
    std::string path = "/home/dan/Dropbox/Photos/x0ml8.png";
    if(path.size() == 0) return;
    cv::Mat img = cv::imread(path);
    cv::imshow("test",img);
    @



  • The 'xxxx' in the "d.put('xxxx' % (cols, rows, nbytes, channels))" line should be 'xxxx' - the exact format is important.



  • Ok... something here eats percent signs. So I guess you did it correctly initially ( 'percent' 'zero' 'eight' 'x' , repeated four times)

    Your problem might be 'execfile', which is Python 2.x only, and a GDB build with Python 3.x.

    The easiest solution for that would be using a recent Qt Creator build, and enter the path the file with your dumpers in Tools->Options, Debugger, GDB tab, "Extra Debugging Helpers"



  • Hi Andre,
    Thanks again for helping me with this. Here's a link to the source in a github page.
    https://github.com/dtmoodie/GDB-ImageWatch/blob/master/qt-imageWatch/cvTypes.py

    The 'data' field is stored as an "unsigned char *" which is the starting point of where the memory dump should occur. Unfortunately I think I'm extracting this incorrectly, but I don't know how I should change it. I've looked at a few examples in the boost library dumpers and from tutorials, but none have done anything.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.