首页 > 编程知识 正文

opencv 字符识别,opencv图像识别思路

时间:2023-05-05 02:55:05 阅读:35021 作者:3164

一、角点(corner)拐角通常被定义为两条边的交点。 也就是说,拐角的局部邻域必须在两个不同区域的不同方向上具有边界。 角点检测是计算机视觉系统中获取图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维重建和目标识别等,也称为特征点检测。

1、角点的类型

2、角点检测算法的基本思想:

如果使用固定窗口在图像上沿任意方向滑动,并比较滑动前和滑动后这两种情况,则认为窗口内像素的灰度变化的程度,如果沿任意方向滑动都有较大的灰度变化,则该窗口存在角点

目前,角点检测算法尚不完善,许多算法依赖大量训练集和冗馀数据来防止和减少错误特征的出现。 角点检测算法的重要评估标准是对多个图像中相同或相似特征的检测能力,并能够应对光照变化、图像旋转等影响。

关于拐角的具体说明有几个。

与作为灰度梯度的一次导数的局部最大值对应的像素点; 2个以上边缘交点图像中的梯度值和梯度方向的变化速度高点; 角点的一次微分最大,二次微分为零,表示物体边缘变化不连续的方向。 三种角点检测算法:

基于二值图像的角点检测; 基于轮廓曲线的角点检测; 基于灰度图像的角点检测:基于梯度、基于模板、模板与基于梯度的组合三种方法; 常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测算法、Harris角点检测算法、KLT角点检测算法和犹豫不决的草丛角点检测算法。 基于模板的方法主要考虑像素区域的点灰度的变化,即亮度的变化。 http://www.Sina.com/http://www.Sina.com /

1、Harris角点检测

角点的原理来源于对人的对角点的感性判断,图像在各个方向灰度都发生显着变化。 算法的核心是使用局部窗口在图像上移动来判断灰度变化较大,因此该窗口的图像灰度变化为[-1,0,1; - 1,0,1; -1,0,1 ] [-1,-1,-1,- 1; 0,0,0; 1,1,1 ]。 从以下三张图可以清楚地看到拐角检测的过程。 如果一个窗口在图像上移动,并且如图(a )所示窗口没有向所有方向变化,则认为窗口区域是平滑的区域。 如图(b )所示,在窗不向一个方向变化,而在另一个方向有明显的变化的情况下,在该区域中可能存在边缘。 如图10 c所示,在窗口在各个方向上灰度变化较大的情况下,可能在该区域中存在转折点。 Harris角点检测利用这种直观的物理现象,根据窗口在不同方向上的变化程度来确定是否是角点。

1.1 原理分析

基于算法思想,建立数学模型,计算移动窗口的灰度差。

为了减少计算量,使用泰勒级数简化公式:

上图的w函数表示窗函数,m矩阵是偏导数矩阵。 矩阵可以变化对称矩阵,假设用两个特征值代替,其几何意义如下图所示。 在几何模型中,通过判断两个特征值的大小来判断像素的属性。

m是梯度协方差矩阵,定义角响应函数r,确定r的大小,以便应用实际更好的编程,从而确定像素是否是角。 r依赖于m的特征值,相对于拐角|R|较大,平坦区域|R|较小,边缘的r为负值。1.1.1 算法思想

OpenCV中的API :

c : voidcornerharris (32位单通道,用于存储输入8bit单通道灰度Mat矩阵OutputArray dst,Harris角点检测结果) //滑块窗口//Sobel边缘检测滤波器大小双精度k,//Harris中间参数,经验值0.04~0.06 intb ordertype=border _ default//插值类型) 330 Harris算法最原始的定义是减去矩阵m的行列式的值和m的痕迹,并将差值与预先给定的阈值进行比较。 之后,Shi和Tomasi提出了改进的方法,如果在两个特征值中

较小的一个大于最小阈值,则会得到强角点。
Shi 和Tomasi 的方法比较充分,并且在很多情况下可以得到比使用Harris 算法更好的结果。

OpenCV里面的API:

C++:void goodFeaturesToTrack( InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask=noArray(), int blockSize=3, bool useHarrisDetector=false, double k=0.04 );

参数详解:

第一个参数image:8位或32位单通道灰度图像;

第二个参数corners:位置点向量,保存的是检测到的角点的坐标;

第三个参数maxCorners:定义可以检测到的角点的数量的最大值;

第四个参数qualityLevel:检测到的角点的质量等级,角点特征值小于qualityLevel*最大特征值的点将被舍弃;

第五个参数minDistance:两个角点间最小间距,以像素为单位;

第六个参数mask:指定检测区域,若检测整幅图像,mask置为空Mat();

第七个参数blockSize:计算协方差矩阵时窗口大小;

第八个参数useHarrisDetector:是否使用Harris角点检测,为false,则使用Shi-Tomasi算子;

第九个参数k:留给Harris角点检测算子用的中间参数,一般取经验值0.04~0.06。第八个参数为false时,该参数不起作用;

三、亚像素级角点检测

       当我们想要进行几何测量或者标定的时候势必要比目标识别需要更高的精度的特征点。而上面的goodFeaturesToTrack()只能得到整数的坐标值,这时候我们就需要亚像素级的角点检测来得到实数坐标值来满足精度需求。

       亚像素级角点检测的位置摄像机标定,跟踪并重建摄像机的轨迹或者重建被跟踪目标的三维结构时,是一个基本的测量值。下面是将角点位置精确到亚像素精度的过程:

                                     

        一个向量与其正交的向量的点积为0,角点满足上图所示情况。其中(a)点p附近的图像是均匀的,其梯度为0;(b)边缘的梯度与沿边缘方向的q-p向量正交。在图中两种情况下,p点梯度与q-p向量的点积均为0。

      上图中,我们假设起始角点q在实际亚像素角点的附近。检测所有的q-p向量。若点p位于一个均匀区域,则点p的梯度为0。若q-p向量的方向与边缘的方向一致,则此边缘上p点处的梯度与q-p向量正交,在这两种情况下,p点处的梯度与q-p向量的点积为0.我们可以在p点周围找到很多组梯度以及相关的向量q-p,令其点集为0,然后可以通过求解方程组,方程组的解即为角点q的亚像素级精度的位置,即精确的角点位置。

OpenCV的API介绍:

C++:void cornerSubPix( InputArray image, //输入图像InputOutputArray corners,//输入角点的初始坐标和为输出的精确坐标Size winSize, //搜索窗口边长的一半Size zeroZone,//搜索区域中间的死区大小的一半,(-1,-1)表示没有这样的大小。TermCriteria criteria //终止角点优化迭代的条件);

示例程序:

//代码里面有三种程序#include "stdafx.h"#include "opencv2/opencv.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"using namespace std;using namespace cv;int main(int argv, char** argc){Mat srcImage = imread("C:/Users/zhj/Desktop/image/template.bmp");if (srcImage.empty()){printf("could not load image..n");return false;}Mat srcgray, dstImage, normImage,scaledImage;cvtColor(srcImage, srcgray, CV_BGR2GRAY);Mat srcbinary;threshold(srcgray, srcbinary,0,255, THRESH_OTSU | THRESH_BINARY);Mat kernel = getStructuringElement(MORPH_RECT, Size(15, 15), Point(-1, -1));morphologyEx(srcbinary, srcbinary, MORPH_OPEN, kernel, Point(-1, -1));/*//1、Harris角点检测cornerHarris(srcgray, dstImage, 3, 3, 0.01, BORDER_DEFAULT);//归一化与转换normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());convertScaleAbs(normImage, scaledImage);Mat binaryImage;threshold(scaledImage, binaryImage, 0, 255, THRESH_OTSU | THRESH_BINARY);*///2、Shi-Tomasi算法:确定图像强角点vector<Point2f> corners;//提供初始角点的坐标位置和精确的坐标的位置int maxcorners = 200;double qualityLevel = 0.01; //角点检测可接受的最小特征值double minDistance = 10;//角点之间最小距离int blockSize = 3;//计算导数自相关矩阵时指定的领域范围double k = 0.04; //权重系数goodFeaturesToTrack(srcgray, corners, maxcorners, qualityLevel, minDistance, Mat(), blockSize, false, k);//Mat():表示感兴趣区域;false:表示不用Harris角点检测//输出角点信息cout << "角点信息为:" << corners.size() << endl;//绘制角点RNG rng(12345);for (unsigned i = 0; i < corners.size(); i++){circle(srcImage, corners[i], 2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1, 8, 0);cout << "角点坐标:" << corners[i] << endl;}//3、寻找亚像素角点Size winSize = Size(5, 5); //搜素窗口的一半尺寸Size zeroZone = Size(-1, -1);//表示死区的一半尺寸//求角点的迭代过程的终止条件,即角点位置的确定TermCriteria criteria = TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40,0.001);//TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);cornerSubPix(srcgray, corners, winSize, zeroZone, criteria);//输出角点信息cout << "角点信息为:" << corners.size() << endl;//绘制角点for (unsigned i = 0; i < corners.size(); i++){circle(srcImage, corners[i], 2, Scalar(255,0,0), -1, 8, 0);cout << "角点坐标:" << corners[i] << endl;}waitKey(0);return(0);}

 效果图:                               (Shi-Tomasi角点检测效果图,以及角点数目、坐标值)

                                                                                         (亚像素级坐标位置)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。