kinect学习笔记四(距离变换 distance tranform 和opencv像素访问方式)

本文主要是介绍kinect学习笔记四(距离变换 distance tranform 和opencv像素访问方式),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当时自己理解的一点小误区,放到这里防止再犯错。

距离变换的基本意思就是计算一个图像中非零像素点到最近的零像素点的距离,也就是到所有零像素点的最短距离。建立距离变换图像可以方便提取骨骼

在opencv中有专门的函数cvDistTransform来计算距离变换图像。

DistTransform
计算输入图像的所有非零元素对其最近零元素的距离void cvDistTransform( const CvArr* src, CvArr* dst, int distance_type=CV_DIST_L2,int mask_size=3, const float* mask=NULL );
src
输入 8-比特、单通道 (二值) 图像.
dst
含计算出的距离的输出图像(32-比特、浮点数、单通道).
distance_type
距离类型; 可以是 CV_DIST_L1, CV_DIST_L2, CV_DIST_C 或 CV_DIST_USER.
mask_size
距离变换掩模的大小,可以是 3 或 5. 对 CV_DIST_L1 或 CV_DIST_C 的情况,参数值被强制设定为 3, 因为 3×3 mask 给出 5×5 mask 一样的结果,而且速度还更快。
mask
用户自定义距离距离情况下的 mask。 在 3×3 mask 下它由两个数(水平/垂直位量,对角线位移量)组成, 5×5 mask 下由三个数组成(水平/垂直位移量,对角位移和 国际象棋里的马步(马走日)) 
函数 cvDistTransform 二值图像每一个象素点到它最邻近零象素点的距离。对零象素,函数设置 0 距离,对其它象素,它寻找由基本位移(水平、垂直、对角线或knight's move,最后一项对 5×5 mask 有用)构成的最短路径。 全部的距离被认为是基本距离的和。由于距离函数是对称的,所有水平和垂直位移具有同样的代价 (表示为 a ), 所有的对角位移具有同样的代价 (表示为 b), 所有的 knight's 移动具有同样的代价 (表示为 c). 对类型 CV_DIST_C 和 CV_DIST_L1,距离的计算是精确的,而类型 CV_DIST_L2 (欧式距离) 距离的计算有某些相对误差 (5×5 mask 给出更精确的结果), OpenCV 使用 [Borgefors86] 推荐的值:CV_DIST_C (3×3):
a=1, b=1CV_DIST_L1 (3×3):
a=1, b=2CV_DIST_L2 (3×3):
a=0.955, b=1.3693CV_DIST_L2 (5×5):
a=1, b=1.4, c=2.1969

其中mask刚开始不是很理解,经过模拟数据得到了其含义。

距离计算
2b?2a b
?bab?
2aa0a2a
?bab?
b?a?b

a\b分别表示在水平垂直方向的距离,?/问号部分表示根据a和b的值的大小再确定其值。
如果定义了c值(用户自定义mask或者选择CV_DIST_L2等)在变为

a,b,c
2bc2ac2b
cbabc
2aa0a2a
cbabc
2bc2ac2b

所以定义c的时候必须是5*5的mask,然后在往外扩充的时候类似上面的问号类型,找到最小距离即可。

下面代码表示自己创建一个9*9的矩阵,然后利用该函数计算其值:

//距离变换代码,在微软的那个ppt中用来计算掌心的位置可能用到这个
//部分内容在http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=4574&start=0有解释#include <iostream>
#include "highgui.h"
#include "cv.h"using namespace std;int main()
{IplImage *src = cvCreateImage(cvSize(9, 9), 8, 1);cvZero(src);uchar *ptr = (uchar*)(src->imageData);*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0; *ptr++ = 0;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 0;*ptr++ = 0; *ptr++ = 0;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255; *ptr++ = 0;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 0;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 0;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 0;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 0;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 0;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255;*ptr++ = 255; *ptr++ = 0;*ptr++ = 0;ptr +=3;*ptr++ = 0;*ptr++ = 0;*ptr++ = 255;*ptr++ = 0;*ptr++ = 255;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0; ptr +=3;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;IplImage *dist = cvCreateImage( cvGetSize(src), IPL_DEPTH_32F, 1 );cvDistTransform( src, dist, CV_DIST_L1, 3, NULL, NULL );/*cvConvertScale( dist, dist, 1000.0, 0 );cvShowImage("dist2", dist);cvPow( dist, dist, 0.5 );cvShowImage("dist3", dist);IplImage *dist32s = cvCreateImage(cvGetSize(src), IPL_DEPTH_32S, 1);cvConvertScale( dist, dist32s, 1.0, 0.5 );cvShowImage("dist32s", dist32s);cvAndS( dist32s, cvScalarAll(255), dist32s, 0 );cvShowImage("dist32s2", dist32s);IplImage *dist8u1 = cvCloneImage(src);cvConvertScale( dist32s, dist8u1, 1, 0 );cvShowImage("dist8u1", dist8u1);*/for (int y=0; y<src->height; y++){uchar *pt = (uchar*)(src->imageData+y*src->widthStep);for (int x=0; x<src->width; x++){cout << int(pt[x]) << '\t';}cout << endl;}cout << endl << endl;for (int y=0; y<dist->height; y++){float *p = (float *)(dist->imageData+y*dist->widthStep);//因为输出图像必须是浮点型数据,所以这里必须采用float。也是自己一开始做错的。虽然IplImage->imageData是char型的,但是针对不同类型(字节型浮点型)要有不同的处理方式for (int x=0; x<dist->width; x++){cout << float(p[x]) << '\t';}cout << endl;}cvShowImage("src",src);cvShowImage("dist", dist);cvWaitKey(0);return 0;}
运行结果



如果将距离运算改为CV_DIST_L2运行结果:




因为一开始栽倒数据访问上了,所以有必要将opencv中像素访问方式贴出来,方便以后查阅。csnd编辑界面太差了,一堆乱码,大家还是移步到:http://www.opencv.org.cn/index.php/OpenCV_编程简介(矩阵/图像/视频的基本读写操作)

这篇关于kinect学习笔记四(距离变换 distance tranform 和opencv像素访问方式)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888132

相关文章

如何突破底层思维方式的牢笼

我始终认为,牛人和普通人的根本区别在于思维方式的不同,而非知识多少、阅历多少。 在这个世界上总有一帮神一样的人物存在。就像读到的那句话:“人类就像是一条历史长河中的鱼,只有某几条鱼跳出河面,看到世界的法则,但是却无法改变,当那几条鱼中有跳上岸,进化了,改变河道流向,那样才能改变法则。”  最近一段时间一直在不断寻在内心的东西,同时也在不断的去反省和否定自己的一些思维模式,尝试重

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

idea lanyu方式激活

访问http://idea.lanyus.com/这个地址。根据提示将0.0.0.0 account.jetbrains.com添加到hosts文件中,hosts文件在C:\Windows\System32\drivers\etc目录下。点击获得注册码即可。

vcpkg安装opencv中的特殊问题记录(无法找到opencv_corexd.dll)

我是按照网上的vcpkg安装opencv方法进行的(比如这篇:从0开始在visual studio上安装opencv(超详细,针对小白)),但是中间出现了一些别人没有遇到的问题,虽然原因没有找到,但是本人给出一些暂时的解决办法: 问题1: 我在安装库命令行使用的是 .\vcpkg.exe install opencv 我的电脑是x64,vcpkg在这条命令后默认下载的也是opencv2:x6