OpenCV3.0 Examples学习笔记(5)-distrans.cpp
来源:互联网 发布:曼秀雷敦润唇啫喱知乎 编辑:程序博客网 时间:2024/06/08 17:22
这个系列的目的是通过对OpenCV示例,进一步了解OpenCV函数的使用,不涉及具体原理。
目录
简介
Example运行截图
Example分析
Example代码
简介
本文记录了对OpenCV示例distrans.cpp的分析。首先这个示例,主要讲述了distanceTransform函数的使用。distanceTransform函数用于计算二值图像中所有像素力其最近的值为0像素的近似距离。这个函数非常有用,
可以用于细化轮廓或者寻找物体质心。
整个示例可以总结为
(1)二值化
(2)调用distanceTransform函数
(3)根据distanceTransform函数计算结果,绘制距离变换图像(图像的值表示距离)。
Example截图
原图
处理结果
参数
二值化阈值:edgeThresh=100
distanceTransform参数:
distanceType = DIST_L1
maskSize = DIST_MASK_5
Example分析
示例主要涉及distanceTransform函数的使用。
如果对于distanceTransform算法本身感兴趣可以传送至Distance Transform 距离变换。
如果想进一步了解distanceTransform函数的使用,可以传送至Opencv距离变换distanceTransform应用——细化字符轮廓&&查找物体质心。
如果想进一步了解distanceTransform函数的使用,可以传送至Opencv距离变换distanceTransform应用——细化字符轮廓&&查找物体质心。
distanceTransform
计算二值图像,任意点到最近背景点的距离,一般为非零点到最近零点的距离。
distanceTransform函数计算二值图像中所有像素力其最近的值为0像素的近似距离。显然如果像素本身为0,则其距离显然也为0。
函数原型:
void distanceTransform( InputArray src, OutputArray dst,
int distanceType, int maskSize, int dstType=CV_32F);
参数说明:
src:源图像,需要采用二值化后的8位灰度图像
dst:目标图像,可以是8位或32位浮点,尺寸和src相同
distanceType:计算距离的方式,具体如下
DIST_USER = -1, //!< User defined distance
DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2|
DIST_L2 = 2, //!< the simple euclidean distance
DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|)
DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
DIST_HUBER = 7 //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345
maskSize:掩膜的尺寸,具体如下:
DIST_MASK_3 = 3, //!< mask=3
DIST_MASK_5 = 5, //!< mask=5
DIST_MASK_PRECISE = 0 //!<
PS:当distanceType = DIST_L1或DIST_C时,maskSize强制为3(设为5也没用)
dstType:目标图像的类型,默认为CV_32F;
Example代码
#include <opencv2/core/utility.hpp>#include "opencv2/imgproc.hpp"#include "opencv2/imgcodecs.hpp"#include "opencv2/highgui.hpp"#include <stdio.h>using namespace std;using namespace cv;int maskSize0 = DIST_MASK_5;int voronoiType = -1;int edgeThresh = 100;int distType0 = DIST_L1;// The output and temporary imagesMat gray;// threshold trackbar callbackstatic void onTrackbar( int, void* ){ static const Scalar colors[] = { Scalar(0,0,0), Scalar(255,0,0), Scalar(255,128,0), Scalar(255,255,0), Scalar(0,255,0), Scalar(0,128,255), Scalar(0,255,255), Scalar(0,0,255), Scalar(255,0,255) }; int maskSize = voronoiType >= 0 ? DIST_MASK_5 : maskSize0; int distType = voronoiType >= 0 ? DIST_L2 : distType0; Mat edge = gray >= edgeThresh, dist, labels, dist8u; if( voronoiType < 0 ) distanceTransform( edge, dist, distType, maskSize ); else distanceTransform( edge, dist, labels, distType, maskSize, voronoiType ); if( voronoiType < 0 ) { // begin "painting" the distance transform result dist *= 5000; pow(dist, 0.5, dist); Mat dist32s, dist8u1, dist8u2; dist.convertTo(dist32s, CV_32S, 1, 0.5); dist32s &= Scalar::all(255); dist32s.convertTo(dist8u1, CV_8U, 1, 0); dist32s *= -1; dist32s += Scalar::all(255); dist32s.convertTo(dist8u2, CV_8U); Mat planes[] = {dist8u1, dist8u2, dist8u2}; merge(planes, 3, dist8u); } else { dist8u.create(labels.size(), CV_8UC3); for( int i = 0; i < labels.rows; i++ ) { const int* ll = (const int*)labels.ptr(i); const float* dd = (const float*)dist.ptr(i); uchar* d = (uchar*)dist8u.ptr(i); for( int j = 0; j < labels.cols; j++ ) { int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1; float scale = 1.f/(1 + dd[j]*dd[j]*0.0004f); int b = cvRound(colors[idx][0]*scale); int g = cvRound(colors[idx][1]*scale); int r = cvRound(colors[idx][2]*scale); d[j*3] = (uchar)b; d[j*3+1] = (uchar)g; d[j*3+2] = (uchar)r; } } } imshow("Distance Map", dist8u );}static void help(){ printf("\nProgram to demonstrate the use of the distance transform function between edge images.\n" "Usage:\n" "./distrans [image_name -- default image is ../data/stuff.jpg]\n" "\nHot keys: \n" "\tESC - quit the program\n" "\tC - use C/Inf metric\n" "\tL1 - use L1 metric\n" "\tL2 - use L2 metric\n" "\t3 - use 3x3 mask\n" "\t5 - use 5x5 mask\n" "\t0 - use precise distance transform\n" "\tv - switch to Voronoi diagram mode\n" "\tp - switch to pixel-based Voronoi diagram mode\n" "\tSPACE - loop through all the modes\n\n");}const char* keys ={ "{@image |../data/stuff.jpg|input image file}"};int main( int argc, const char** argv ){ help(); CommandLineParser parser(argc, argv, keys); string filename = parser.get<string>(0); gray = imread(filename.c_str(), 0); if(gray.empty()) { printf("Cannot read image file: %s\n", filename.c_str()); help(); return -1; } namedWindow("Distance Map", 1); createTrackbar("Brightness Threshold", "Distance Map", &edgeThresh, 255, onTrackbar, 0); for(;;) { // Call to update the view onTrackbar(0, 0); int c = waitKey(0) & 255; if( c == 27 ) break; if( c == 'c' || c == 'C' || c == '1' || c == '2' || c == '3' || c == '5' || c == '0' ) voronoiType = -1; if( c == 'c' || c == 'C' ) distType0 = DIST_C; else if( c == '1' ) distType0 = DIST_L1; else if( c == '2' ) distType0 = DIST_L2; else if( c == '3' ) maskSize0 = DIST_MASK_3; else if( c == '5' ) maskSize0 = DIST_MASK_5; else if( c == '0' ) maskSize0 = DIST_MASK_PRECISE; else if( c == 'v' ) voronoiType = 0; else if( c == 'p' ) voronoiType = 1; else if( c == ' ' ) { if( voronoiType == 0 ) voronoiType = 1; else if( voronoiType == 1 ) { voronoiType = -1; maskSize0 = DIST_MASK_3; distType0 = DIST_C; } else if( distType0 == DIST_C ) distType0 = DIST_L1; else if( distType0 == DIST_L1 ) distType0 = DIST_L2; else if( maskSize0 == DIST_MASK_3 ) maskSize0 = DIST_MASK_5; else if( maskSize0 == DIST_MASK_5 ) maskSize0 = DIST_MASK_PRECISE; else if( maskSize0 == DIST_MASK_PRECISE ) voronoiType = 0; } } return 0;}
参考资料:
1.《基于distanceTransform-距离变换的区域中心提取》
2.《Distance Transform 距离变换》
3.《Distance Transform 距离变换》
4.《Opencv距离变换distanceTransform应用——细化字符轮廓&&查找物体质心》
5.《基于距离变换的新型骨架提取方法》
2 0
- OpenCV3.0 Examples学习笔记(5)-distrans.cpp
- OpenCV3.0 Examples学习笔记(2)-convexhull.cpp
- OpenCV3.0 Examples学习笔记(3)-cout_mat.cpp
- OpenCV3.0 Examples学习笔记(4)-demhist.cpp
- OpenCV3.0 Examples学习笔记(6)-edge.cpp
- OpenCV3.0 Examples学习笔记(7)-ffilldemo.cpp
- OpenCV3.0 Examples学习笔记(8)-filestorage.cpp
- OpenCV3.0 Examples学习笔记(1)-contours2.cpp-通过findContours 函数实现轮廓提取
- OpenCV3.0 Examples学习笔记(9)-fitellipse.cpp-fitEllipse函数实现椭圆拟合
- OpenCV3.0 Examples学习笔记(11)-houghcircles.cpp-houghcircles函数实现圆形检测
- OpenCV3.0 Examples学习笔记(12)-houghlines.cpp-通过HoughLinesP函数实现直线检测
- OpenCV3.0 Examples学习笔记(15)-lsd_lines.cpp-LSD直线检测
- OpenCV3.0 Examples学习笔记(18)-pca.cpp-PCA类实现降维处理
- OpenCV3.0 Examples学习笔记(10)-grabcut.cpp-grabcut函数实现人机交互高效分割图像前景背景
- OpenCV3.0 Examples学习笔记(13)-kmeans.cpp-kmeans函数实现对图像位置进行聚类
- OpenCV3.0 Examples学习笔记(14)-laplace.cpp-LaplaLacian实现对摄像头预览图边缘检测
- OpenCV3.0 Examples学习笔记(16)-minarea.cpp-minAreaRect,minEnclosingTriangle,minEnclosingCircle获取点集外接形状
- OpenCV3.0 Examples学习笔记(17)-morphology2.cpp-erode,dilate,morphologyEx函数实现数学形态学变换
- CFX系列(二):CXF处理复杂的对象
- Fetch.Type和FetchMode
- ...........0000000000000000
- Java POI 生成Word文档
- ButterKnife配置
- OpenCV3.0 Examples学习笔记(5)-distrans.cpp
- 北京天宇联科技有限责任公司—T语言html页面开发
- Error:java: Compilation failed: internal java compiler error
- android View 事件分发
- kernel中断分析七——tasklet
- 微信应用号(小程序)开发IDE配置
- 总结下在开发项目中禁用按钮的一些小方法
- wordexp函数的使用
- Hibernate 的三种查询方式:HQL、Criteria、Sql