如何使用OpenCV实现基于标记的定位
展开全部
准备一张示例图片,如图示,图片中存在方形,多变形,不规则图形,圆形,且颜色各异。 下面介绍如何定位图中的两个圆。此图片大家可以使用windows自带的小画家来画,注意画圆的时候按shift键可以画出正圆。
引用OpenCV 头文件和库文件,并且包含vector, 后面要用到。
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <math.h>
#pragma comment (lib,"opencv_core244d.lib")
#pragma comment (lib,"opencv_highgui244d.lib")
#pragma comment (lib,"opencv_imgproc244d.lib")
using namespace std;
using namespace cv;
加载待处理图片,为了便于显示,对图片进行缩放,其实缩放这个小技巧还可以提高后续的处理速度。然后对图片进行灰度处理,然后对图片记性二值化处理,去掉饱和度较低的部分,利用HoughCircles函数,提取轮廓为圆的部分。
注意调整HoughCirles函数的几个参数,可以抓到不同的结果,要耐心根据实际情况调整。
Mat resized;
resize(src,resized,Size(src.cols/ratio,src.rows/ratio));
int w=resized.size().width;
int h=resized.size().height;
Mat gray;
cvtColor(resized,gray,CV_BGR2GRAY);
blur(gray,gray,Size(3,3));
threshold(gray,gray,160,255,THRESH_BINARY_INV);
blur(gray,gray,Size(3,3));
vector<Vec3f> circles;
HoughCircles(gray,circles,CV_HOUGH_GRADIENT,2,h/4,25,100,h/32,h/8);
vector<Vec3f>::const_iterator it=circles.begin();
while(it!=circles.end())
{
circle(resized,Point((*it)[0],(*it)[1]),2,Scalar(0,0,255),2);
circle(resized,Point((*it)[0],(*it)[1]),(*it)[2],Scalar(0,0,255),2);
++it;
}
namedWindow("src");
imshow("src",resized);
namedWindow("resized");
imshow("resized",gray);
waitKey(0);
代码解读:
使用HoughCircles必须注意,传入的第一个参数必须是灰度图,根据需要设置其参数,参数2 :累加器分辨率, 参数3: 两个圆之间的最小距离,参数4:Canny 高阀值,参数5:最小投票数,参数6,7:最小,最大半径。
函数抓取的圆保存到向量circles中, Vec3f 是个3个变量的结构体Vec3f[0] ,Vec3f[1] 对应圆心坐标值,Vec3f[2] 对应圆心半径。
为了显示结果, 使用circle函数画出圆心和圆,颜色使用红色。
但是摄像头拍照不比电脑作图,实际拍照会受光照条件和强度的影响,导致抓取结果偏差很大。 如下图,实际拍摄的图可能有阴影投射,灰度处理后影响值得抓取。使用上述代码,却抓到了7个圆,实际只需要左右2个,所以可以根据坐标将不需要的过滤掉。
实际基于标记的坐标定位也可使用如下的图形进行实现,该图解析出来后不但能够识别坐标,还可判断方向,实际开发中,下图会转化为海明码进行分析。
引用OpenCV 头文件和库文件,并且包含vector, 后面要用到。
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <math.h>
#pragma comment (lib,"opencv_core244d.lib")
#pragma comment (lib,"opencv_highgui244d.lib")
#pragma comment (lib,"opencv_imgproc244d.lib")
using namespace std;
using namespace cv;
加载待处理图片,为了便于显示,对图片进行缩放,其实缩放这个小技巧还可以提高后续的处理速度。然后对图片进行灰度处理,然后对图片记性二值化处理,去掉饱和度较低的部分,利用HoughCircles函数,提取轮廓为圆的部分。
注意调整HoughCirles函数的几个参数,可以抓到不同的结果,要耐心根据实际情况调整。
Mat resized;
resize(src,resized,Size(src.cols/ratio,src.rows/ratio));
int w=resized.size().width;
int h=resized.size().height;
Mat gray;
cvtColor(resized,gray,CV_BGR2GRAY);
blur(gray,gray,Size(3,3));
threshold(gray,gray,160,255,THRESH_BINARY_INV);
blur(gray,gray,Size(3,3));
vector<Vec3f> circles;
HoughCircles(gray,circles,CV_HOUGH_GRADIENT,2,h/4,25,100,h/32,h/8);
vector<Vec3f>::const_iterator it=circles.begin();
while(it!=circles.end())
{
circle(resized,Point((*it)[0],(*it)[1]),2,Scalar(0,0,255),2);
circle(resized,Point((*it)[0],(*it)[1]),(*it)[2],Scalar(0,0,255),2);
++it;
}
namedWindow("src");
imshow("src",resized);
namedWindow("resized");
imshow("resized",gray);
waitKey(0);
代码解读:
使用HoughCircles必须注意,传入的第一个参数必须是灰度图,根据需要设置其参数,参数2 :累加器分辨率, 参数3: 两个圆之间的最小距离,参数4:Canny 高阀值,参数5:最小投票数,参数6,7:最小,最大半径。
函数抓取的圆保存到向量circles中, Vec3f 是个3个变量的结构体Vec3f[0] ,Vec3f[1] 对应圆心坐标值,Vec3f[2] 对应圆心半径。
为了显示结果, 使用circle函数画出圆心和圆,颜色使用红色。
但是摄像头拍照不比电脑作图,实际拍照会受光照条件和强度的影响,导致抓取结果偏差很大。 如下图,实际拍摄的图可能有阴影投射,灰度处理后影响值得抓取。使用上述代码,却抓到了7个圆,实际只需要左右2个,所以可以根据坐标将不需要的过滤掉。
实际基于标记的坐标定位也可使用如下的图形进行实现,该图解析出来后不但能够识别坐标,还可判断方向,实际开发中,下图会转化为海明码进行分析。
AiPPT
2024-09-19 广告
2024-09-19 广告
随着AI技术的飞速发展,如今市面上涌现了许多实用易操作的AI生成工具1、简介:AiPPT: 这款AI工具智能理解用户输入的主题,提供“AI智能生成”和“导入本地大纲”的选项,生成的PPT内容丰富多样,可自由编辑和添加元素,图表类型包括柱状图...
点击进入详情页
本回答由AiPPT提供
展开全部
Kalman滤波理论主要应用在现实世界中个,并不是理想环境。主要是来跟踪的某一个变量的值,跟踪的依据是首先根据系统的运动方程来对该值做预测,比如说我们知道一个物体的运动速度,那么下面时刻它的位置按照道理是可以预测出来的,不过该预测肯定有误差,只能作为跟踪的依据。另一个依据是可以用测量手段来测量那个变量的值,当然该测量也是有误差的,也只能作为依据,不过这二个依据的权重比例不同。最后kalman滤波就是利用这两个依据进行一些列迭代进行目标跟踪的
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
如果仅有一张图片的样本的话,很难实现。 识别图片的过程大概是: 提取特征 训练样本,得到模型 使用模型判断 如果题主想速成的话,还是去下现成代码吧。。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询