image watch不仅仅只为opencv服务!

在使用OpenCV的过程中,经常在visual studio中使用image watch查看图像。其实Image watch的功能非常强大, 不仅仅可以显示Opencv 图像数据,也可以显示其他类型的图像。 例如有一块内存保存的是图像数据,也可以将其显示出来。例如:

#include "ippi.h"
#include "ippcv.h"

int main()
{
	IppiSize size = {320,320 };
	int pitch = 0;
	Ipp16s *pSrc = ippiMalloc_16s_C1(size.width, size.height, &pitch);
	IppStatus status1 = ippiImageJaehne_16s_C1R(pSrc, pitch, size);
	ippifree(pSrc);
	return 0;
}

在这里插入图片描述
其中显示内存中的图像数据操作为: @ m e m ( p S r c , I N T 16 , 1 , s i z e . w i d t h , s i z e . h e i g h t , p i t c h ) @mem(pSrc, INT16, 1, size.width,size.height, pitch) @mem(pSrc,INT16,1,size.width,size.height,pitch)

我们还可以对内存中的图像进行二值化:
2

二值化操作为: @ t h r e s h ( @ m e m ( p S r c , I N T 16 , 1 , s i z e . w i d t h , s i z e . h e i g h t , p i t c h ) , 0 ) @thresh(@mem(pSrc, INT16, 1, size.width,size.height, pitch), 0) @thresh(@mem(pSrc,INT16,1,size.width,size.height,pitch),0)

更多操作见后文图像操作。

安装(Installation)

Visual Studio 2012 以上版本。 并安装Update1 和Update3。
下载Image Watch默认安装即可。
为了使用混合模式调试,请确保没有选中 Tools ->Options ->Debugging ->General ->Managed C++ Compatitibility Mode.

基本操作(basic operation)

  • 第一次如何找到Image Watch:
    在调试过程中中断,然后选择:视图 -> 其他窗口 -> Image Watch 。
    只要这样操作一次之后,停止调试时 Image Watch 会自动消失,下次调试过程中会自动出现。
    其实还是更简单的方法:将鼠标停靠在cv::Mat变量上,单击放大镜即可,具体见后文。

在 image watch窗口的左上角,有 Locals和 Watch 两个单选按钮。

  1. 如果在 Locals 模式,下面的图像列表(B区域)就会自动显示当前栈中图像变量(image watch 可以识别的类型,例如cv::Mat)。
  2. 如果在 Watch 模式,用户可以手动添加图像,例如输入图像表达式,具体怎么写见后文。

图像列表中的每一项都有一个小方块表示(蓝色表示有效,灰色表示无效),对于有效的表达式:下面会一张缩略图,图片大小,像素格式和 类型。支持的像素格式和类型见后文。

选中一个图像(D),就可以在右边的图像视图中看到原图(E区域)。图像视图支持放大缩小图像(滚动鼠标滚轮),拖动图像。在F区域显示着当前的放大系数。当前位置坐标,位置处的像素值显示在靠上的 H 区域。

在鼠标停靠 Image Watch 有效的图像变量时,会自动出现 J区域所示的相关信息。点击放大镜就可以在 Image Watch中显示对应图像。如果你不想去找或者找不到image watch 窗口,这是一种打开image watch 的简易的途径。

image watch region

图像列表(Image List )

如上图,B区域所示就是Image List。在Locals 模式下image List是只读的,在watch 模式下是可以编辑和增删的。
image list的右键菜单

  • Expand / Collapse all: 展开/收缩 列表
  • Expand New Items: 展开新的列表项
  • Large Thumbnails: 大缩略图
  • Atuo Maximize Contrast: 自动最大化对比图
  • 1-Channel Pseudo Color: 将灰度图转为伪彩色图显示
  • 4-Channel Ignore Alpha: 忽略四通道图的最后一个通道
  • Add to Watch : 将选择的图像加入到 Watch 模式
  • Add Address to Watch : 将图像地址加入到Watch 模式下,在查看其他栈中的图像时这是一个非常有用的功能。
  • Dump to File:下载到文件; 支持PNG,JPG和BIN格式。如果使用BIN格式,就只能使用 image watch查看图片,可以通过@file 操作符加载到watch中。

image list context menu

图像视图器(Image Viewer)

图像视图器(图一的E区域)可以在较大的区域显示图像,支持放大缩小和查看单个像素的信息。

图像视图的右键菜单

  • zoom to fit : 缩放图片至适应窗口大小
  • zoom to original size : 原始图像大小
  • Link Views : 所有相同大小的图像共享一个视图。这个比较好玩,也就是对相同大小的图片, 可以切换图片可以显示同一个区域。你可以看到不同图像的相同区域,方便查看和对比。
  • Auto Maximize Contrast : 和 上一节image list中的功能一致。
  • 1-Channel Pseudo Color: 和 上一节image list中的功能一致。
  • 4-Channel Ignore Alpha: 和 上一节image list中的功能一致。
  • Hexadecimal Display: 16进制显示,设置显示单个像素值的格式(图一的H区域)
  • Copy Pixel Address : 复制当前像素的内存地址。

image viewer context menu

图像类型(Image Types)

IMAGE WATCH 以及内置支持以下C/C++ 图像类型:
OpenCV:

  • cv::Mat_<>
  • cv::Mat
  • CvMat
  • _lpllmage
    如果不是这些类型的图像,是不是都不能使用Image Watch 显示了呢?那 Image Watch 的通用性岂不是大打折扣。答案是否定的,可以说基本都可以显示,有两种方式:
  1. 使用@mem 操作,具体见Image Operators
  2. 对于用户自定义的数据类型,可以使用扩展接口添加到image watch。具体将扩展接口。

像素格式(Pixel Formats)

像素格式包括单个通道的类型和通道格式。
image watch 支持以下通道类型(是内存中数据的类型):

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

通道格式也就是通道的个数。最大支持512个通道。
一个格式字符串是与像素格式相关联。它决定每个通道显示渲染方式。包括如下:

  • RG,UV
  • RGB, BGR, YUV
  • RGBA, BGRA
    我们在使用OpenCV类型时并没有指定格式,在这种情况下会使用默认的颜色映射(color mapping)规则去做显示渲染。

颜色映射(Color Mapping)
image watch 使用一下两个规则把像素值映射到显示的颜色。

  1. 决定颜色空间。如果没有设置像素格式就使用默认颜色空间(根据通道数)
  • 单通道图:灰度图(默认)或伪彩色(可以在视图器中设置了)
  • 双通道图:红/绿
  • 三通道图:蓝、绿、红
  • 四通道图:蓝、绿、红、透明通道(默认),或者忽略透明通道(可以在视图器中设置了)
  • 大于四个通道的图:取前三个通道为蓝、绿、红,忽略剩余通道。
  1. 根据通道类型,映射通道值到颜色强度(0% ··· 100%)
  • INT8: -128 … 127
  • UINT8: 0 … 255
  • INT16: -32,768 … 32,767
  • UINT16: 0 … 65,535
  • INT32:0 … 1。(由于INT32可以表示的范围太大,这里任意截断到了0到1,建议使用automatic contrast maximization自动最大化对比度显示数据)
  • FLOAT16::0 … 1
  • FLOAT32::0 … 1
  • FLOAT64::0 … 1

图像操作(Image Operators)

来看image watch提供的骚操作。
iamge watch 提供了许多简单的操作去帮助显示图像数据。为了区分C++操作符号,这些操作都以符号“@”开头。操作列表:

  • @band(img, number): 从图像img中提取出某个通道的图像,这个操作会保持输入的数据类型。
  • @thresh(img, threshold): 二值化图像。(大于阈值为1,否则为0)
  • @clamp(img,min,max): 截断像素值到min和max之间。
  • @abs(img): 像素值的绝对值图像
  • @scale(img,factor):使用缩放因子factor,缩放图像
  • @norm8(img):缩小255倍后的图像(factor=1/255)
  • @norm16(img):缩小65535倍后的图像(factor=1/65535)
  • @fliph(img),@flipv(img),@flipd(img): 水平翻转,垂直翻转,对角翻转(转置矩阵)。(保持输入数据类型)
  • @rot90(img),@rot180(img),@rot270(img): 旋转90度,180度,270(保持输入数据类型)
  • @diff(img0,img1): 逐像素相减后的图像(img0 - img1)
  • @file(path): 从路径path加载图像,例如 KaTeX parse error: Undefined control sequence: \temp at position 10: @file(“d:\̲t̲e̲m̲p̲\debug.png”)
  • @mem(address, type, channels, width, height, stride): 显示原始内存数据,输入的参数依次为:内存地址(UINT64),数据类型,通道数,宽度,高度,步长。例如 @mem(myimg.data, UINT8, 320,640,320)

说明:

  • 所有的操作都需要计算图像。例如@band 操作从图像中提出去摸个通道图像。下图展示了提取绿色通道图像。
  • 操作可以嵌套。下图展示了对提取绿色通道的图像二值化
  • 如果没有特定的说明,**默认这些操作都是以 Float32类型数据进行计算并返回Float32 类型的图像。**这意味着数据类型为INT32,FLOAT64会丢失精度,并被截断到FLOAT32范围。
    operator

扩展(extensibility)

扩展部分主要讲解如何让image watch支持自定义的图像类型。这样在调试程序的过程中就可以像cv::Mat变量一样,自动显示到image watch的图像列表中。
具体操作见官方文档。

参考资料

官方文档

欢迎关注个人公众号

在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐