(一) 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, 0, Size(4, 4), Size(0, 0), 1.05, 2);//若rects有嵌套,则取最外面的矩形存入rectfor (int i = 0; i < findrects.size(); i++){Rect rect = findrects[i];int j = 0;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 = -1;//框选出检测结果并选中图片测量对象for (int i = 0; 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(0,0,255);rectangle(dst, r.tl(), r.br(), color, 2);
//    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, // 前景、背景1,        // 迭代次数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(0, 0, 0));//背景值为 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 = 0; i<rst.rows; i++)for (int j = 0; j < rst.cols; j++){if (mask.at<uchar>(i, j) == 0)rst.at<Vec3b>(i, j) = Vec3b(255, 255, 255);}bm.Initialize(src, mask);rstBm=bm.Run();imshow("bordingmatting", rstBm);

笔者自己创建的BorderMatting类。

结果图:

  • 灰度化、二值化便于计算
/******************************灰度化、二值化************************************************/Mat  rstGray, rstBin;cvtColor(rstBm, rstGray, CV_BGR2GRAY);//灰度化
//    imshow("灰度图", rstGray);threshold(rstGray, rstBin, 100, 255, CV_THRESH_BINARY);//二值化imshow("二值图", rstBin);

  • 最长像素距离计算。笔者一开始用欧氏距离遍历计算得到,结果处理时间过长,就采用最简单的简化方法,最长像素点距离≈最高像素点与最低像素点欧氏距离。
/**********************************计算最长像素距离********************************************/double MAXPX = 0;int x1 = 0, y1 = 0;int x2 = 0, y2 = 0;int maxX1, maxX2, maxY1, maxY2;int i, j;int flag = 0;for (i = 0; i < rstBin.rows; i++){for (j = 0; j < rstBin.cols; j++)if (rstBin.at<uchar>(i, j) == 255){x1 = i;y1 = j;flag = 1;break;}if (flag)break;}flag = 0;for (i = rstBin.rows; i >= 0; i--){for (j = 0; j < rstBin.cols; j++)if (rstBin.at<uchar>(i, j) == 255){x2 = i;y2 = j;flag = 1;break;}if (flag)break;}cout << x1 << " " << y1 << endl;cout << x2 << " " << y2 << endl;line(src, Point(y1, x1), Point(y2, x2), Scalar(0, 0, 255), 3);
/*    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

转载于:https://www.cnblogs.com/cc-xiao5/p/10785454.html

openCV 简单实现身高测量(未考虑相机标定,windows)相关推荐

  1. 3.OpenCV可视化(Viz)——单目相机标定模拟

    单目相机标定模拟 基于OpenCV中的Viz模块,虚拟一个相机,设置相机的内参数.然后在相机视野下放置标定板,通过相机标定算法,最终再获取相机内参数. 当然最终相机标定还是存在误差,我猜测主要原因是标 ...

  2. 立体视觉入门指南:相机标定之Zhang式标定法

    作者丨李迎松@知乎 来源丨https://zhuanlan.zhihu.com/p/378819083 编辑丨3D视觉工坊 亲爱的同学们,我们的世界是3D世界,我们的双眼能够观测三维信息,帮助我们感知 ...

  3. 立体视觉入门指南(3):相机标定之张式标定法【超详细值得收藏】

    亲爱的同学们,我们的世界是3D世界,我们的双眼能够观测三维信息,帮助我们感知距离,导航避障,从而翱翔于天地之间.而当今世界是智能化的世界,我们的科学家们探索各种机器智能技术,让机器能够拥有人类的三维感 ...

  4. halcon相机标定助手_Halcon 学习笔记---单相机标定(2)

    一.单项机标定原因 降低畸变(相差) 测量 二.相机标定求出什么 该方程是求取世界坐标系与像素坐标系之间转换矩阵,本质就是求出相机的内外参数.其中dx和dy为每个像素在图像坐标系(UVO)沿U和V方向 ...

  5. 利用Matlab进行相机标定并使用openCV进行简单三维重建

    注:本文主要针对Matlab和OpenCV跨平台进行相机标定.单相机三维重建工作的实现,因为我发现网上竟然没有一篇博客径直指出这两者在进行图像处理时的巨大差异(坐标系完全不同),不然我也不会走了很多弯 ...

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

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

  7. 使用OpenCV进行相机标定

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

  8. c++ opencv 通过网络连接工业相机_摄像头和机器人视觉开发中的「相机标定」,你了解多少?...

    目前我们团队在做一个项目,通过采集到的人脸图像测量人脸上两个瞳孔间的实际距离.注意是实际距离,不是两个瞳孔之间隔多少个像素点.找了很久资料,好像"相机标定"可以解决我的问题,看了不 ...

  9. OpenCV相机标定与畸变校正

    点击我爱计算机视觉标星,更快获取CVML新技术 本文转载自OpenCV学堂. OpenCV单目相机标定,图像畸变校正 相机标定定义与原理 01 在图像测量过程以及机器视觉应用中,为确定空间物体表面某点 ...

  10. 基于python的opencv相机标定(采用黑白棋盘格标定板)

    基于python的相机标定(采用黑白棋盘格图片) 系列文章目录 [第一章 基于python的相机标定(采用黑白棋盘格图片)](https://blog.csdn.net/HWHXXX/article/ ...

最新文章

  1. 还在用Jenkins?试试Gitlab的CI/CD功能吧,贼带劲!
  2. 如何以编程方式在Android上截屏?
  3. Swift中出现“no such module cocoa”的错误
  4. TCP keepAlive详解(TCP心跳包)
  5. u-boot编译过程分析
  6. python表情识别程序_Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
  7. Java中Long到Int的精确转换
  8. Asp.net网站开发架构设计要求
  9. kancloud mysql内核_锁 · Mysql · 看云
  10. centos7镜像文件
  11. 米家扩展程序初始化超时_Home · MiEcosystem/miot-plugin-sdk Wiki · GitHub
  12. UE4 人物运动基本设置
  13. 操作系统之多道程序设计
  14. .prevent 与 .stop,以及解决其他地方长按,文本被选中的问题
  15. 利用电脑学象棋的一点想法
  16. dell云存储服务器,dell云存储服务器(戴尔存储服务器)
  17. 一个字的伤感网名又是一个伤感的故事
  18. 如何利用数据挖掘让RTB广告效果倍增?
  19. 键盘win键和alt互换了怎么办
  20. Hooks详解(一)

热门文章

  1. 常用的公共 DNS 服务器 IP 地址
  2. AI人工智能+区块链+物联网+大数据可视化平台建设综合解决方案
  3. 计算机部分应用显示模糊,win10系统打开部分软件字体总显示模糊的解决方法-电脑自学网...
  4. 网页里添加Skype、WhatsApp及时聊天窗口
  5. 关于WhatsApp Business 和WhatsApp的一些区别
  6. CF #595 Div.3 F. Maximum Weight Subset//树形dp
  7. 基于系统性风险角度的基金资产配置策略分析
  8. 三星固态硬盘ssd产品线收集
  9. IT之软件公司组织架构
  10. JS用图片制作的走动的时间表