<Example_MarkerBasedAR>中Marker.cpp的源码与详细中文注释
来源:互联网 发布:80端口开启 编辑:程序博客网 时间:2024/06/01 14:18
/***************************************************************************** * Marker.cpp * Example_MarkerBasedAR ****************************************************************************** * by Khvedchenia Ievgen, 5th Dec 2012 * http://computer-vision-talks.com ****************************************************************************** * Ch2 of the book "Mastering OpenCV with Practical Computer Vision Projects" * Copyright Packt Publishing 2012. * http://www.packtpub.com/cool-projects-with-opencv/book *****************************************************************************/#include "Marker.hpp"#include "DebugHelpers.hpp"Marker::Marker(): id(-1)// id初始化为-1{}// 重载了‘<’运算符bool operator<(const Marker &M1,const Marker&M2){ return M1.id<M2.id;}// 顺时针旋转标记矩阵cv::Mat Marker::rotate(cv::Mat in){ cv::Mat out; in.copyTo(out); for (int i=0;i<in.rows;i++) { for (int j=0;j<in.cols;j++) { out.at<uchar>(i,j)=in.at<uchar>(in.cols-j-1,i); } } return out;}// 计算标记矩阵的海明距离int Marker::hammDistMarker(cv::Mat bits){ // bits中的每一行,都要与ids中的所有行进行比较 int ids[4][5]= { // id的顺序无所谓 {1,0,0,0,0}, {1,0,1,1,1}, {0,1,0,0,1}, {0,1,1,1,0} }; int dist=0; // rows for (int y=0;y<5;y++) { int minSum=1e5; // hamming distance to each possible word for (int p=0;p<4;p++) { int sum=0; // 统计海明距离 // cols for (int x=0;x<5;x++) { sum += (bits.at<uchar>(y,x) == ids[p][x]) ? 0 : 1; } // 求bits中第y行与ids中第p行的最小距离 if (minSum>sum) minSum=sum; } // 计算bits中所有行的总距离 dist += minSum; } return dist;}// mat转idint Marker::mat2id(const cv::Mat &bits){ int val=0; for (int y=0;y<5;y++) { val<<=1;// val=val<<1 // 只有1和3位是有用的,其他3位(0 2 4)是校验位 if ( bits.at<uchar>(y,1)) val|=1; val<<=1; if ( bits.at<uchar>(y,3)) val|=1; } return val;}int Marker::getMarkerId(cv::Mat &markerImage,int &nRotations){ assert(markerImage.rows == markerImage.cols); assert(markerImage.type() == CV_8UC1); cv::Mat grey = markerImage; // Threshold image cv::threshold(grey, grey, 125, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); #ifdef SHOW_DEBUG_IMAGES cv::showAndSave("Binary marker", grey);#endif //Markers are divided in 7x7 regions, of which the inner 5x5 belongs to marker info //the external border should be entirely black // 检测是否是标记的边界 int cellSize = markerImage.rows / 7; for (int y=0;y<7;y++) { int inc=6; if (y==0 || y==6) inc=1; //for first and last row, check the whole border for (int x=0;x<7;x+=inc) { int cellX = x * cellSize; int cellY = y * cellSize; // 在grey矩阵中取ROI矩阵 cv::Mat cell = grey(cv::Rect(cellX,cellY,cellSize,cellSize)); int nZ = cv::countNonZero(cell); if (nZ > (cellSize*cellSize) / 2) { return -1;//can not be a marker because the border element is not black! } } } cv::Mat bitMatrix = cv::Mat::zeros(5,5,CV_8UC1); //get information(for each inner square, determine if it is black or white) // 根据5*5的黑白格子元素来设置bitMatrix矩阵:白色=1 黑色=0 for (int y=0;y<5;y++) { for (int x=0;x<5;x++) { // 从5*5的第一个格子开始 int cellX = (x+1)*cellSize; int cellY = (y+1)*cellSize; // 在grey矩阵中取ROI矩阵 cv::Mat cell = grey(cv::Rect(cellX,cellY,cellSize,cellSize)); int nZ = cv::countNonZero(cell); if (nZ> (cellSize*cellSize) /2) bitMatrix.at<uchar>(y,x) = 1; } } //check all possible rotations cv::Mat rotations[4]; int distances[4]; rotations[0] = bitMatrix; distances[0] = hammDistMarker(rotations[0]); // 将第一个标记的海明距离作为最小距离 // 键值对里存的时 1.最小距离 2.对应标记的索引 std::pair<int,int> minDist(distances[0],0); for (int i=1; i<4; i++) { //get the hamming distance to the nearest possible word // 将其余的三种旋转可能标记的海明距离与最小距离进行比较ß rotations[i] = rotate(rotations[i-1]); distances[i] = hammDistMarker(rotations[i]); if (distances[i] < minDist.first) { minDist.first = distances[i]; minDist.second = i; } } // 保存识别出的标记的索引 nRotations = minDist.second; if (minDist.first == 0) { return mat2id(rotations[minDist.second]); } return -1;}void Marker::drawContour(cv::Mat& image, cv::Scalar color) const{ float thickness = 2; cv::line(image, points[0], points[1], color, thickness, CV_AA); cv::line(image, points[1], points[2], color, thickness, CV_AA); cv::line(image, points[2], points[3], color, thickness, CV_AA); cv::line(image, points[3], points[0], color, thickness, CV_AA);}
另附上TinyLA.cpp中的相关注释:
bool isInto(cv::Mat &contour, std::vector<cv::Point2f> &b){ for (size_t i=0;i<b.size();i++) { // 检查指定的点和指定的多边形的相对位置关系(在多边形内、外、边上或顶点上) // 返回值:该点和多边形上最近的一条边有符号的距离(>0表示在内部,<0表示在外部,=0表示在边上) // 当最后一个参数值为0的时候,返回的距离只会是100或-100. if (cv::pointPolygonTest( contour,b[i],false)>0) return true; } return false;}
- <Example_MarkerBasedAR>中Marker.cpp的源码与详细中文注释
- 《Example_MarkerBasedAR》中MarkerDetector.cpp源码及详细中文注释
- caffe 中classification.cpp的源码注释
- camshiftdemo.cpp的详细注释
- python源码中中文注释的处理
- Hog源码注释(hog.cpp的注解)
- 去除cpp中注释的小程序
- OpenCV2.4版本的camshiftdemo.cpp的详细注释
- OpenCV2.4版本的camshiftdemo.cpp的详细注释
- python源码中使用中文注释
- python源码中使用中文注释
- VC6中cpp文件源码中出现中文乱码问题的解决办法
- sqlHelper类的中文 详细注释
- php最详细的配置文件(中文注释)
- SqlHelper详细中文注释
- SqlHelper详细中文注释
- 剔出//与/**/注释的源码
- STL源码剖析之空间配置器(空间的配置与释放,代码中有详细的注释,相信大家都能看懂哦)
- js编写trim()函数
- java--时间
- mysql root用户密码修改
- 从键盘输入x值,根据公式得出y值
- apk反编译获取完整源码 及 apk反编译后的处理
- <Example_MarkerBasedAR>中Marker.cpp的源码与详细中文注释
- 第九周 根据a的值,输出菜名
- acm-输入年月日,输出是本年的多少天
- AddressBook 地址簿 (电话簿) 访问与修改
- extjs4学习笔记
- silverlight异步变同步
- 实例讲解seo实战操作(五)
- 第九周实践上机项目——构造菜单
- #J2EE之Servlet#——入门篇:JDK&Tomcat 开发环境搭建和配置