(一) OpenCV3.1.0+VS2015开发环境配置

  • 下载OpenCV安装包(笔者下载3.1.0版本)
  • 环境变量配置(opencv安装路径\build\x64\vc14\bin,注意的是x64文件夹下分为vc12和vc14两个文件夹,他们对应于VS的版本,vc8 = Visual Studio 2005,vc9 = Visual Studio 2008,vc10 = Visual Studio 2010,vc11 = Visual Studio 2012,vc12 = Visual Studio 2013,vc14 = Visual Studio 2015)
  • VS2015配置。进入属性管理器(View—>Other Windows—>Property Manger,展开目录,选中Debug|Win64中的Microsoft.Cpp.x64.user,并右键点击属性(Properties)进入属性界面。)
    1. 包含目录配置(通用属性(Common Properties)—>VC ++目录—>包含目录(Include Directories))。添加路径:D:\Code\C\opencv\build\include;D:\Code\C\opencv\build\include\opencv;D:\Code\C\opencv\build\include\opencv2
    2. 配置库文件目录(Library Directories)。D:\Code\C\opencv\build\x64\vc14\lib(注意VS版本)
    3. 配置动态链接库(Linker(链接库)—>Input(输入)—>Additional Dependencies(添加依赖))。D:\Code\C\opencv\build\x64\vc12\bin路径下的。opencv_world310.lib和opencv_world310d.lib,这里两个库文件的区别就是:opencv_world310.lib是Release模式版本,而opencv_world310d.lib是Debug模式版本。

(二)算法思路

  • HOG特征提取获得定位矩形框,笔者使用SVM分类优化+多尺度检测获得带有矩形框的dst
/******************************HOG detector************************************************/
dst = src.clone();
vector<Rect> findrects, findrect;
HOGDescriptor HOG;
//SVM分类器
HOG.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
//多尺度检测
HOG.detectMultiScale(src, findrects, , Size(, ), Size(, ), 1.05, );
//若rects有嵌套,则取最外面的矩形存入rect
for (int i = ; i < findrects.size(); i++)
{
Rect rect = findrects[i];
int j = ;
for (; j < findrects.size(); j++)
if (j != i && (rect & findrects[j]) == rect)
break;
if (j == findrects.size())
findrect.push_back(rect);
}
Rect r;//用来选中所测图像中的测量对象。
r.height = -;
//框选出检测结果并选中图片测量对象
for (int i = ; i < findrect.size(); i++)
r = r.height > findrect[i].height ? r : findrect[i];
//HOG detector返回的矩形框比真正图像轮廓大,所以我们减少矩形框的大小来使得更符合外界边框
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
Scalar color = Scalar(,,);
rectangle(dst, r.tl(), r.br(), color, );
// imshow("src", src);
// imshow("dst", dst);

原图像和得到的dst图像

  • Grabcut算法分割
/********************************grabCut**********************************************/
cv::Mat mask = Mat::zeros(src.size(), CV_8UC1);//分割后的结果
//两个临时矩阵变量,作为算法的中间变量使用
cv::Mat bgModel, fgModel;
cv::Rect rectangle(r.tl(),r.br());//图像的前景对象也就是矩形选中图像
// GrabCut 分段
cv::grabCut(src, //输入图像
mask, //分段结果
rectangle,// 包含前景的矩形
bgModel, fgModel, // 前景、背景
, // 迭代次数
cv::GC_INIT_WITH_RECT); // 用矩形 // 得到可能是前景的像素
//比较函数保留值为GC_PR_FGD的像素
cv::compare(mask, cv::GC_PR_FGD, mask, cv::CMP_EQ);
// 产生输出图像
cv::Mat foreground(src.size(), CV_8UC3, cv::Scalar(, , ));
//背景值为 GC_BGD=0,作为掩码
src.copyTo(foreground, mask);
imshow("foreground", foreground);

处理后图像

  • BorderMatting边缘细化处理(由于版权问题,没有相应接口需自己编写)主要思想:把前景颜色值与估计值对比,选择较小的差异值颜色代替,使得平滑最好
/********************************BorderMatting**********************************************/
BorderMatting bm;
Mat rst = Mat(src.size(), src.type());
Mat rstBm;
src.copyTo(rst);
for (int i = ; i<rst.rows; i++)
for (int j = ; j < rst.cols; j++)
{
if (mask.at<uchar>(i, j) == )
rst.at<Vec3b>(i, j) = Vec3b(, , );
}
bm.Initialize(src, mask);
rstBm=bm.Run();
imshow("bordingmatting", rstBm);

笔者自己创建的BorderMatting类。

结果图:

  • 灰度化、二值化便于计算
/******************************灰度化、二值化************************************************/

    Mat  rstGray, rstBin;
cvtColor(rstBm, rstGray, CV_BGR2GRAY);//灰度化
// imshow("灰度图", rstGray);
threshold(rstGray, rstBin, , , CV_THRESH_BINARY);//二值化
imshow("二值图", rstBin);

  • 最长像素距离计算。笔者一开始用欧氏距离遍历计算得到,结果处理时间过长,就采用最简单的简化方法,最长像素点距离≈最高像素点与最低像素点欧氏距离。
/**********************************计算最长像素距离********************************************/
double MAXPX = ;
int x1 = , y1 = ;
int x2 = , y2 = ;
int maxX1, maxX2, maxY1, maxY2;
int i, j;
int flag = ;
for (i = ; i < rstBin.rows; i++)
{
for (j = ; j < rstBin.cols; j++)
if (rstBin.at<uchar>(i, j) == )
{
x1 = i;
y1 = j;
flag = ;
break;
}
if (flag)
break;
}
flag = ;
for (i = rstBin.rows; i >= ; i--)
{
for (j = ; j < rstBin.cols; j++)
if (rstBin.at<uchar>(i, j) == )
{
x2 = i;
y2 = j;
flag = ;
break;
}
if (flag)
break;
}
cout << x1 << " " << y1 << endl;
cout << x2 << " " << y2 << endl;
line(src, Point(y1, x1), Point(y2, x2), Scalar(, , ), );
/* for ( i = 1; i <= rstBin.rows*rstBin.cols; i++)//第一个像素点开始遍历
{
x1 = i / rstBin.rows;
y1 = !x1 ? (i - 1) : (i % x1 - 1);
if (rstBin.at<uchar>(x1, y1) == 0)
continue;
for ( j = i + 1; j <= rstBin.rows*rstBin.cols; j++)
{
x2 = j / rstBin.rows;
y2 = !x2 ? (j - 1) : (j % x2 - 1);
if (rstBin.at<uchar>(x2, y2) == 255)//同为白色像素点时计算距离
{
double distance=abs(x2 - x1) +abs(y2 - y1);//避免欧氏距离计算浪费时间
if (MAXPX < distance)
{
maxX1 = x1;
maxX2 = x2;
maxY1 = y1;
maxY2 = y2;
MAXPX = distance;
}
}
}
}
*/
/*MAXPX = sqrt((maxX1 - maxX2)*(maxX1 - maxX2) + (maxY1 - maxY2)*(maxY1 - maxY2));
cout << MAXPX << endl;
cout << maxX1 << " " << maxY1 << endl;
cout << maxX2 << " " << maxY2 << endl;
line(src, Point(maxY1, maxX1), Point(maxY2, maxX2), Scalar(0, 0, 255), 3);
*/imshow("final", src);

注意像素点坐标顺序。结果如下

像素与毫米的转换 转换还需要知道另一个参数:PPI(每英寸多少像素) 象素数 / PPI = 英寸数 英寸数 * 25.4 = 毫米数

笔者 设定系统参数焦距(3.5mm)不会变动(图为35mm焦距所拍),物距1.1m,ppi:400(笔者电脑PPI260)

那么身高大概为:({[((709-152)^2+(281-247)^2)^0.5]/260}*25.4/35)*1.1≈1.71m

openCV 简单实现身高测量(未考虑相机标定,windows)的更多相关文章

  1. OpenCV相机标定和姿态更新

    原帖地址: http://blog.csdn.net/aptx704610875/article/details/48914043 http://blog.csdn.net/aptx704610875 ...

  2. 相机标定 matlab opencv ROS三种方法标定步骤(1)

    一 . 理解摄像机模型,网上有很多讲解的十分详细,在这里我只是记录我的整合出来的资料和我的部分理解 计算机视觉领域中常见的三个坐标系:图像坐标系,相机坐标系,世界坐标系,实际上就是要用矩阵来表 示各个 ...

  3. 使用OpenCV进行相机标定

    1. 使用OpenCV进行标定 相机已经有很长一段历史了.但是,伴随着20世纪后期的廉价针孔照相机的问世,它们已经变成我们日常生活的一种常见的存在.不幸的是,这种廉价是由代价的:显著的变形.幸运的是, ...

  4. 相机标定过程(opencv) + matlab参数导入opencv + matlab标定和矫正

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 辛苦原创所得,转载请注明出处 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ...

  5. OpenCV相机标定

    标签(空格分隔): Opencv 相机标定是图像处理的基础,虽然相机使用的是小孔成像模型,但是由于小孔的透光非常有限,所以需要使用透镜聚焦足够多的光线.在使用的过程中,需要知道相机的焦距.成像中心以及 ...

  6. Opencv——相机标定

    相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像. 相机标定的输入:标定图像上所有内角 ...

  7. Camera Calibration 相机标定:Opencv应用方法

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/49427383 Opencv中Camer ...

  8. 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)

    使用Opencv实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定,标定需要的输入和输出分别是哪些? 相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的 ...

  9. 相机标定简介与MatLab相机标定工具箱的使用(未涉及原理公式推导)

    相机标定 一.相机标定的目的 确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,建立摄像机成像的几何模型,这些几何模型参数就是摄像机参数. 二.通用摄像机模型 世界坐标系.摄像机坐标 ...

随机推荐

  1. 2018-2019-1-20165221&20165225 《信息安全系统设计》实验五:通讯协议设计

    2018-2019-1-20165221&20165225 <信息安全系统设计>-实验五:通讯协议设计 OpenSSL学习: 简介: OpenSSL是为网络通信提供安全及数据完整性 ...

  2. 使用SpringSecurity体验OAuth2 (入门2)

    本文继续使用SpringSecurity从实战角度对OAuth2进行体验,上一篇 搭建了项目环境,并对配置做了初步分析,分析发现会有两套配置可能在影响OAuth,一个是由授权服务的启动类上的注解@En ...

  3. Gitlab_ansible_jenkins三剑客③Ansible的安装及使用

    一台服务器可能会安装不同的python应用,不同的应用可能使用的模块版本不同,如果都安装在同样的环境下容易冲突,为了避免冲突,引入virtualenv 这个包管理工具进行环境的隔离 使用pip安装之前 ...

  4. 工具篇之GIT知识整理(一)

    目录 项目工具篇(一)GIT 说在前面 背景 与其他版本控制产品对比 Git下载地址及安装 下载地址 安装 在案例中简单使用Git命令 git clone git log git diff git c ...

  5. 基于物品的协同过滤item-CF 之电影推荐 python

    推荐算法有基于协同的Collaboration Filtering:包括 user Based和item Based:基于内容 : Content Based 协同过滤包括基于物品的协同过滤和基于用户 ...

  6. stderr和stdout详细解说

    今天又查了一下fprintf,其中对第一个参数stderr特别感兴趣. int fprintf(FILE *stream,char *format,[argument]): 在此之前先区分一下:pri ...

  7. tomcat启动后产生的日志

    产生的日志  相当于 定时选取webapps里面搜索有没有超时的session,然后将超时的session关掉. 每一个webapp 都是独立的 一个application对应一个context,se ...

  8. 用 pdf.js兼容部分安卓显示PDF在线预览 时,a标签直接链接参数文件不能含中文的解决办法

    例子: 项目部署在 Tomcat 上的: <a href="../generic/web/viewer.html?file=doc/register/要显示的文件.pdf" ...

  9. buaaoo_second_improvement

    你不优化,我不优化,那大家就都是满分啦 (一)写在最前 电梯问题由于和实际关联比较紧密,所以实际上可以操作的空间比较多. 但第二单元的电梯,需要实现捎带:第三单元的电梯,需要实现楼层限制.人数限制.三 ...

  10. Swift 编译时间优化

    在Xcode中直接看到编译项目的时间 step1:关闭Xcode step2:打开终端执行defaults write com.apple.dt.Xcode ShowBuildOperationDur ...