点击上方“3D视觉工坊”,选择“星标”
干货第一时间送达
整理:公众号@图像处理与计算机视觉
本文仅做学术分享,如有侵权,请联系删除。
二维码的特征定位和信息识别 背景介绍视觉的方法可以用来估计位置和姿态。最容易想到的是在目标上布置多个容易识别的特征,这样使用opencv相机标定和、相机畸变矫正、轮廓提取、solvepnp来获取目标相对于相机的位姿。在实际使用中只要相机和目标一方是估计的,那就可以得到全局坐标。如果相机和靶标都在移动,那只能获取到相对坐标。但是受限于相机视角和景深,这样多个特征的识别虽然精度可以很高,但是范围却很小。
对于如何扩大范围,使用二维码是一个很好的思路。首先,二维码本身具有多个特征,单个二维码可以用来实现上述方法的功能。其次,二维码本身带有信息,如果二维码的布置事先已知,那么位置和姿态估计的范围将只受限于二维码的数量。
本文主要是二维码的特征识别和信息识别。
二维码的的生成二维码是在一个网站上生成的,经过手机的测试,生成的二维码没有问题。http://www.liantu.com/,该网站是免费的,生成的图片及二维码各种参数可以自定义。 本文的测试图片有20张,是数字1到5,每个数字隔90度旋转各一张。
二维码特征识别的思路是:第一步,寻找二维码的三个角的定位角点,需要对图片进行平滑滤波,二值化,寻找轮廓,筛选轮廓中有两个子轮廓的特征,从筛选后的轮廓中找到面积最接近的3个即是二维码的定位角点。第二步:判断3个角点处于什么位置,主要用来对图片进行透视校正(相机拍到的图片)或者仿射校正(对网站上生成的图片进行缩放拉伸旋转等操作后得到的图片)。需要判断三个角点围成的三角形的最大的角就是二维码左上角的点。然后根据这个角的两个边的角度差确定另外两个角点的左下和右上位置。第三步,根据这些特征识别二维码的范围。 具体的代码:
Mat src = imread( "pic\\456.jpg", 1 ); if(src.empty()) { fprintf(stderr, "Can not load image!\n"); return 0; } Mat src_all=src.clone(); //彩色图转灰度图 Mat src_gray; cvtColor( src, src_gray, CV_BGR2GRAY ); //对图像进行平滑处理 blur( src_gray, src_gray, Size(3,3) ); //使灰度图象直方图均衡化 equalizeHist( src_gray, src_gray ); namedWindow("src_gray"); imshow("src_gray",src_gray); //灰度图 //指定112阀值进行二值化 Mat threshold_output; threshold( src_gray, threshold_output, 112, 255, THRESH_BINARY ); #ifdef DEBUG namedWindow("二值化后输出"); imshow("二值化后输出",threshold_output); //二值化后输出#endif //需要的变量定义 Scalar color = Scalar(1,1,255 ); vectorcontours,contours2; vectorhierarchy; Mat drawing = Mat::zeros( src.size(), CV_8UC3 ); //Mat drawing2 = Mat::zeros( src.size(), CV_8UC3 ); Mat drawingAllContours = Mat::zeros( src.size(), CV_8UC3 ); //利用二值化输出寻找轮廓 findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0) ); //寻找轮廓的方法 int tempindex1 = 0; int tempindex2 = 0; for(int i = 0;ia1]; vectorout2Contours = contours[it->a2]; double lenth1 = arcLength(out1Contours,1); double lenth2 = arcLength(out2Contours,1); if(abs(lenth1/lenth2-2)>1) { it = vin.erase(it); } else { drawContours( drawing, contours, it->a1, CV_RGB(255,255,255) , CV_FILLED, 8); it++; } } //获取三个定位角的中心坐标 Point point[3]; int i = 0; vectorpointthree; for(it = vin.begin(),i = 0;it != vin.end();i++,it++) { point[i] = Center_cal( contours, it->a1 ); pointthree.push_back(point[i]); } if(pointthree.size() <3) { cout << "找到的定位角点不足3个"<关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?


微信扫码登录