文档结构  
可译网翻译有奖活动正在进行中,查看详情 现在前往 注册?
原作者:未知    来源:research.microsoft.com [英文]
magiaPants    计算机    2016-10-28    0评/479阅
翻译进度:已翻译   参与翻译: dreampuff (1)

 

IMAGE WATCH 帮助

目录

安装

基础操作

图像列表

图像查看器

图像类型

像素格式

颜色映射

图像操作

可扩展性

一直问题

安装

需要最低Visual Studio 2012 + Update 1 . 更推荐Update 3 ,因为它修复了一些印象Image Watch的问题。 Update 3能在这里 下载。

为了允许 混合模式调试,确认取消选择 Tools -> Options -> Debugging -> General -> Managed C++ Compatibility Mode.

基本操作

第一次打开Image Watch:在编译器中设置断点,选择View -> Other Windows -> Image Watch。注意你只需要设置一次:就像Visual Studio 在Watch窗口中生成,停止编译时Image Watch会消失,下次编译开始时会自动打开。

Image Watch就像是在一起Locals和Watch窗口。左上角的单选按钮(图1,A)能够在两个模式间转换,就像Visual Studio在Locals和Watch窗口生成:在Locals模式下,图像列表 (B)会随着当前堆栈中能够获得图像值的更新而更新。在Watch模式,图像能够由用户手动添加,例如通过输入可获得图像值的表示。

列表中的每个图片给变量都以一个正方形的缩略图标进行标示。当小图标为蓝色时,将在右侧窗口显示该图片变量的详细附加信息,包括图像的缩略图、图片的尺寸(以像素为单位的宽和高)、像素格式(通道数以及像素的数据类型),具体支持的C++类型以及像素数据格式将在下文提到。

  在右侧的图片浏览器中可以一次选定一张图片进行浏览,这个浏览窗口所支持的鼠标操作包括左键拖动以及滚轮滑动。当前图片的扩大倍数显示在又上角(F),当前像素坐标显示在鼠标指针处(G),当前像素值在窗口顶部显示,另外,通过旋转鼠标滚轮来放大图像,当放大倍数较高时,像素值将直接显示在原图上。

  ImageWatch可以自动的加载当前调试过程中的图片变量,我们也可以通过在代码编辑窗口(J)或者监视器窗口(I)中右键点击变量选择将其添加到Image Watch窗口中进行浏览。

图1:

screenshot1
 

 

图像列表

图像列表(Figure1 B)的设计与VisualStudio中列表的框的设计相似,包含有Local和Watch两个模式。在Local模式中,这个列表中的元素是只读的,并且是自动显示的。在Watch模式中,可以通过双击文本词条,按F2键后直接输入变量名等方式来添加新的变量,词条可以剪切(Ctrl+X、Ctrl+Delete)、复制(Ctrl+C、Ctrl+Insert)和粘贴(Ctrl+V,Shift+Insert)等等。

  可以通过Up和Down方向键、Tap/Ctrl+Tap以及Home/End键来操作图像列表

  通过单击图像列表中每个词条左上角的“+/-”可以把相应的缩略图折叠或展开,条目折叠起来之后,将只显示条目的名称,这样做的好处是可以减少调试过程中image watch窗口的更新时间,因为窗口中显示的所有信息,包括各个缩略图标,都需要在执行完每个断点或者单步操作后重新加载。当图像列表中有相当多的项目,图片非常大或者调试过程是在远程计算机上执行的时候,每次插件更新时间久变得很明显,这种折叠图标的做法就显得非常有效。

         如图2所示在image list窗口中有一个文本菜单(单击)鼠标右键激活。这个菜单里包含的项目有:

  •          Expand/Collapse All: 展开或折叠当前列表中的所有条目
  •          Expand New Items: 控制窗口条目默认显示状态是折叠还是展开
  •          Large Thumbnails: 控制两种缩略图显示尺寸之间的切换
  •          Auto Maximize Contrast:如果没有选中,像素值在映射成颜色时将使用标准调色板规则;如果选中,当前像素值将会被映射成全彩色,注意,这一设置是适用于所有图像
  •          1-Channel Pseudo Color: 如果没有选中,单通道图像将会显示成灰度图像;如果选中之后,将会使用一个伪彩色调色板对图像进行着色,这一设置也是适用于所有图像的。
  •          4-Channel Ignore Alpha: 这一选项重要是针对四通道图像。如果选中,则四通道图像的最后一个通道将解释为alpha;如果未被选中,则随后一个通道的将会被忽略。
  •          Add to Watch: 将选中的条目加入到watch窗口列表中。
  •          Add Address to Watch: 将选中图像条目的地址加入到watch窗口列表中,当一个图像的存储跨越了不同的堆栈结构时,这一做法是非常有效的。
  •          Dump to File: 把当前选中的图片存成一个文件,所支持的保存格式有PGN、JPG以及BIN格式(image watch的内部无损文件格式),BIN文件意味着只能用于image watch,可以使用@file operator来加载这些文件。

图2:

图像查看器

图像查看器(Figure1, E)对当前选中的条目进行更大尺寸的显示。在这个窗口中我们可以通过鼠标滚轮将图像迅速放大以便查看图像中单个像素的值(Figure 1, H)。

  在图像查看器中按住ctrl键同时按鼠标左键,能够快速实现在前后浏览的两个图片间进行切换。

  窗口中像素的显示格式如下:x y | c0 c1 … cN.其中通道值是按照其在内存中出现的顺序来进行显示的。

单击右键将会弹出该窗口中的快捷菜单(图3)

  •          Zoom to Fit:自动设置适合当前窗口显示的缩放比例
  •          Zoom to Original Size:将缩放比例设置为1.0,即图片中的一个像素对应着显示屏上的一个像素点。
  •          Link Views:如果被选中,所有的具有相同尺寸的图像在显示时都会在想对应的位置同比例显示。比如说,在放大观察了一幅1024*768的图像的某一区域后,在图像列表中选择了另外一张具有相同尺寸的图像,则浏览器将会显示第二章图像相同位置区域的放大效果;相反,如果选择了一张640*480的图片,将会看到一个不同的区域,也就是这张图片是按照所有640*480的图片规格进行显示的。
  •          Auto Maximize Contrast/1-Channel Pseudo Color/4-Channel Use Alpha: 这是图像列表中快捷菜单相应部分的镜像菜单,功能与之前的快捷菜单功能相同,在这里进行的这些选项的设置也是使用与所有图像的。
  •          Hexadecimal Display: 这个选项将会触发visual studio中的“HexadecimalDisplay”设置,这个设置在初始化构建image watch窗口的过程中生效。在image watch中这个选项将决定像素值将以什么样的进制显示。
  •          Copy Pixel Address:将当前像素值在内存中的地址信息复制到剪贴板上,这一点对于做记录非常有帮助。可以讲得到的地址粘贴到VS中内存调试器中,或者用来生成一个数据断点。

图3:

图像类型

image watch支持下列C/C++图形格式

OpenCV:

  • cv::Mat_<>
  • cv::Mat
  • CvMat
  • _IplImage

用户自己定义的图像格式可以通过下面介绍的extensibility interface来进行添加。

像素格式

image watch中的像素格式主要包括通道类型和每个通道的格式

  image watch主要支持以下数据类型

  •          INT8, UINT8
  •          INT16, UINT16
  •          INT32
  •          FLOAT16
  •          FLOAT32
  •          FLOAT64

通道格式表示通道数,最大为512通道。

需要指出的是,字符串的排列形式与像素的格式相关,每个通道是按照以下语义顺序进行排序的:

  • RG, UV
  • RGB, BGR, YUV
  • RGBA, BGRA

 如果没有明确指出通道语义的排列顺序(例如所有的opencv类型),image watch将使用缺省的调色板规则对图像进行分类。

  同时image watch也至此一定数量的YUV格式。在这种情况下,通道语义的排列顺序将决定数据的排列方式,

  • NV12 (两个方案:一个是Y平面,一个是打包后的UV平面,即在两个维度上进行二次抽样)

  •  YV12 (三个方案,一个是Y平面,一个是打包后的U平面和V平面,在两个维度上进行二次抽样)

  •  IYUV (与YV12方法相同但是U和V的平面顺序调换)

  •  YUY2 (单个方案,对两个通道进行各行扫描,Y是第一个通道,对U和V通道进行水平方向的二次抽样并以此存储在第二个通道中

颜色映射

image watch中使用下面两种规则对颜色进行映射:

  首先取决于相应的颜色空间。如果相应的语义顺序缺省,则根据通道数来确定对应的颜色空间:

  •          1 channel image: 根据当前浏览器窗口中的设置来决定使用灰度图或者伪彩色图
  •          2 channel image: 红/绿
  •          3 channel image: 蓝色绿色红色
  •          4 channel image: 蓝色绿色红色以及Alpha,或者忽略Alpha通道,与当前设置相关
  •          5 or more channels: 先使用 B, G, R, 方案同时忽略其他通道

第二,根据通道类型通道值映射到颜色强度 (0% … 100%) :

  •          INT8: -128 … 127
  •          UINT8: 0 … 255
  •          INT16: -32,768 … 32,767
  •          UINT16: 0 … 65,535
  •          INT32: 0 … 1 (注意:INT32像素值的范围根据应用不同造0到1内任意选择。在INT32型图像操作中请允许自动与最大值比较来调整数据显示)
  •          FLOAT16: 0 … 1
  •          FLOAT32: 0 … 1
  •          FLOAT64: 0 … 1

图像操作符

image watch中提供了很多简单操作符来更加形象的查看图像数据。为了与固有的C++语句相区分,这些操作符的名字都以“@”开头。

  所有的操作符都是用来对图像进行评估。例如,@band操作符就是用来从图像中提取出一个单通道图像。它有两个参数,一个是图像名称,另一个是需要提取的通道的数字表示。

  操作符之间可以进行嵌套。作为操作符输入的图像可以是任何形式的,即可以用其他一个操作符的输出作为另外操作符的输入。例如@thresh操作符可以对一幅图像进行二值化操作并返回一个二值图像,Figure 4 (L)显示了如何用120作为阈值去二值化一个图像中的Green通道中的值。

注意:在没有其他说明的情况下,imagewatch操作符的运行算法是的Float32位的,同时返回Float32的图像结果,这样就意味着INT32图像在经过运算后会丢失一些精度,FLOAT64图像在运算后不经会丢失精度,而且误差也会增大。

  注意:在缺省情况下,FLOAT32将按照以下规则对图像的颜色进行映射:将0%强度的像素值映成0.0f,将100%强度的像素值映成1,0f,超出的部分将会被直接省略。例如如果@clamp 把一个UINT8 的图像限制到10和20之间,则结果图像将会被全部显示成白色,因为所有的像素值都处在10到20之间,将其直接映成1.0f。因此我们在使用image watch操作符时,需要确保选择了automatic contrast maximization。无独有偶,下面将要介绍的@norm8 和@norm16操作符来对结果进行除255和除65535的处理,也是一种数据类型的转化。

  image watch操作符列表:

  • @band(img, number): 根据number所指定的通道数提取图像中对应的数值,注意这个操作符要求指定需要提取的对应通道标示。
  •  @thresh(img, threshold): 对图像进行二值化处理,大于阈值时将像素赋值为1,小于阈值时将像素赋值为0。
  •   @clamp(img, min, max):用给定的最小值和最大值对图像的像素值进行截断。
  •  @abs(img): 计算图像中像素的绝对值
  • @scale(img, factor): 将图像中的所有像素的像素值乘以比例系数factor
  •   @norm8(img): 将图像的像素值乘以1/255
  •  @norm16(img): 将图像的像素值乘以1/65535
  •  @fliph(img), @flipv(img), @flipd(img):将图像沿水平、垂直以及对角线方向进行对称翻转
  •  @rot90(img), @rot180(img), @rot270(img): 将图像沿顺时针方向旋转90度、180度和270度
  •  @diff(img0, img1): 逐点执行以下操作 img0 –img1
  •   @file(path): 从指定路径中加载图片.Example: @file(“d:\temp\debug.png”)
  •  @mem(address, type, channels, width, height, stride):根据给出的起始地址、通道类型、通道数、宽度、高度以及幅度来声明一段内存,例如Example: @mem(myimg.data,   UINT8, 1, 320, 240, 320)

图4:

screenshot2

可扩展性

Image Watch 能够根据用户自定义C/C++图像类型进行扩展显示。简便的用户自定义类型需要支持像素格式。

Image Watch 建立在Visual Studio natvis 框架下从而支持用户自定义类型。.natvis文件是编译友好型的C++类型xml描述:包括类型名称和如何显示类型属性的一系列规则。这里是一个很好的.natvis教程。在Image Watch中,.natvis 文件描述了如何从图像对象中读取图像的宽,长,像素地址等。

Image Watch在OpenCV类型下生成,如cv::Mat,以及_IplImage,是特殊的.natvis文件名为Image WatchOpenCV.natvis,在进行Image Watch扩展的时候它可以作为一个参考。 ImageWatchOpenCV.natvis是ImageWatch.vsix安装文件(.zip文件)的一部分。你能够简单的重命名外ImageWatch.zip并使用你最喜欢的zip工具获取内容。

示例1: 简单 8bit RGB 图像

struct My8BitRGBImage

{

    unsigned int ncols;

    unsigned int nrows;

    unsigned char* data;

};

它的.natvis 描述

<?xml version="1.0" encoding="utf-8"?>

<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

 

  <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1"

                MenuName="Add to Image Watch"/>

 

  <Type Name="My8BitRGBImage">

    <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />

  </Type>

 

  <Type Name="My8BitRGBImage">

    <Expand>

      <Synthetic Name="[type]">

        <DisplayString>UINT8</DisplayString>

      </Synthetic>

      <Synthetic Name="[channels]">

        <DisplayString>RGB</DisplayString>

      </Synthetic>
      <Item Name="[width]">ncols</Item>

      <Item Name="[height]">nrows</Item>

      <Item Name="[data]">data</Item>

      <Item Name="[stride]">ncols*3</Item>

    </Expand>

  </Type>  

</AutoVisualizer>

Image Watch 中,每个.natvis文件需要一个 <UIVisualizer> 声明,每个类型需要两个 <Type>声明。第一个 <Type>节点只有一个<UIVisualizer>自节点,第二个存在<Expand>子节点。注意到<Expand> 节是做到支持图像类型时唯一需要设置的部分。<Expand> 节必须包括<Item> 或<Synthetic> 子元素,后面跟随其名称属性。

  • [type]: a 通道类型.
  • [channels]: 通道格式.也可以是一个数字 (通道数)或者系统支持的字符  (能代表通道个数).
  • [width]: 图片宽度,单位是像素
  • [height]: 图片长度,单位是像素
  • [planes]: plane的数量, 默认为一个 (默认为填充像素布局). 注特殊YUV 格式 需要指定planes的个数 (如 2 - NV12, 3 - IYUV 或者 YV12).
  • [data]: 指向开始像素的指针. 对于填充图像, 这是一个单一的地址.对平面图像, 可以指定单独的平面地址的列表 (见下面的样例2 ). 否则,地址表示第一个平面的开始,而平面被假定为连续的在内存中。
  • [stride]: 每像素行的字节数. 对于平面图像, 每一行是一个以分号分隔的列表.
  • [range]: 自定义像素值范围的颜色映射 (可选). 两个浮点值 (min; max),由分号分隔. 例如, “0; 4095” 对应12bit 图像.如果省略此参数 Image Watch会假设 像素值的范围内的 默认值范围 (如, 0 … 65535 for UINT16).

 

 例 1 中的[type] 和[channels] 属性是 <Synthetic>类型, 因为他们的值 (UINT8, RGB) 不是c++表达式的结果, 而是任意文本。相反, 在 例 3 (下面会提到), [channels] 是 <Item>元素, 因为它的值是一个c++调试器表达式。

 

每次启动调试器, Image Watch会在 %USERPROFILE%\My Documents\Visual Studio 2012\Visualizers 查找 .natvis 文件并尝试解析. 这个过程的诊断信息被记录在 ...\Visualizers\ImageWatch.log. Image Watch还在调试日志错误如果不能解析上面的属性之一也会记录. 表明这是一个一个不支持的属性 (如 64位整形的通道类型), 简单的完全保留属性 (如 使用 <Synthetic>的表达式方法). 显示为图像缺失的属性 [invalid], 但没有记录错误. 同样,具有完整但不一致的属性的图像 如. stride 给定宽度太小和像素类型) 也显示 [invalid]. 表明你的图像是有效的, 但未初始化状态, 设置[width],[height] 和[data] 为0. Image Watch显示这些图像为 [noinit].

 

Example 2: 一个平面YUV 图像:

 

struct MyPlanarYUVImage

{

    unsigned int ncols;

    unsigned int nrows;

    unsigned char* ydata;

    unsigned char* udata;

    unsigned char* vdata;

};

and its .natvis description

<?xml version="1.0" encoding="utf-8"?>

<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

 

  <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1"

                MenuName="Add to Image Watch"/>

 

  <Type Name="MyPlanarYUVImage">

    <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />

  </Type>

 

  <Type Name="MyPlanarYUVImage">

    <Expand>

      <Synthetic Name="[type]">

        <DisplayString>UINT8</DisplayString>

      </Synthetic>

      <Synthetic Name="[channels]">

        <DisplayString>YUV</DisplayString>

      </Synthetic>
      <Item Name="[width]">ncols</Item>

      <Item Name="[height]">nrows</Item>

      <Item Name="[planes]">3</Item>

      <Synthetic Name="[data]">

        <DisplayString>{(void*)ydata}; {(void*)udata}; {(void*)vdata}</DisplayString>

      </Synthetic>
      <Item Name="[stride]">ncols</Item>

    </Expand>

  </Type>  

</AutoVisualizer>

 

注, [planes] 属性在这个例子中设置成 3 . 因为planes在内存中并不连续, [data] 属性有三个semicolon-delimited地址. [data] 是一个 <Synthetic> 项目, 因为它的值是一个自定义的格式化的字符串, 不是一个C++ 表达式. 也请注意 (void*) cast: 这是需要强制的VS试器只打印地址, 不是一串字符 (由于数据指针是unsigned char类型). 这个例子没有行填充和所有的步进 相等, 因此 [stride] 是simplyncols. 同样 [data][stride] 可以是一个单一的价值, 或分隔的列表的planes的strides。

 

Example 3: C++模板支持.这里是一个比较普遍的图像模板:

 

template <typename T>

struct MyGenericImage

{     

    unsigned int ncols;

    unsigned int nrows;

    unsigned int nchannels;

    T* data;

};

 

相应的 .natvis 定义:

 

<?xml version="1.0" encoding="utf-8"?>

<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

 

  <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1"

                MenuName="Add to Image Watch"/>


  <Type Name="MyGenericImage&lt;*&gt;">

    <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />

  </Type>

 

  <Type Name="MyGenericImage&lt;*&gt;">

    <Expand>

      <Synthetic Name="[type]" Condition='strcmp("unsigned char", "$T1") == 0'>

        <DisplayString>UINT8</DisplayString>

      </Synthetic>

      <Synthetic Name="[type]" Condition='strcmp("float", "$T1") == 0'>

        <DisplayString>FLOAT32</DisplayString>

      </Synthetic>

      <Item Name="[channels]">nchannels</Item>

      <Item Name="[width]">ncols</Item>

      <Item Name="[height]">nrows</Item>

      <Item Name="[data]">data</Item>

      <Item Name="[stride]">ncols*nchannels*sizeof($T1)</Item>

    </Expand>

  </Type>
 

</AutoVisualizer>

 

这个.natvis 定义支持 unsigned char 或 float pixels的 MyGenericImage 图像。 另注“*” 在Condition属性中是通配符,$T1 模板参数的引用. 这个例子也展示了如何使用 Visual Studio的 debugger intrinsics strcmp() 和 sizeof() 来处理 C++ 的类型名. 关于 .natvis 通用模板的信息, 请参考 Visual Studio’s .natvisdocumentation.

 

已知问题

当使用Image Watch(或者其他的Visual Studio UI 可视化工具)的时候,你可能会遇到如下一个或过个问题。

  • (Visual Studio 2013 已修正) 在constpointer/reference类型上不显示放大镜符号
  • (Update 3 已修正) 如果你在调试器中中断Visual Studio会蹦溃, Visual Studio’的Autos 窗口会显示函数返回的图片。
  • (Update 3 已修正) 当使用 natvis的内联函数,像strcmp()您会看到一个链接器错误.pdb相关文件。

 

 

第 1 段(可获 40.23 积分)

文章评论