opencv学习_11 (moravec角点检测及缺点)

2023-05-16

(1)首先我们来看三幅图片理解什么是角点:



我们在图片以某像素点为中心,取一窗口,当窗口向各个方向移动时,其内部灰度值变化不是很明显,则该点即处在平坦区域(如左边图);当其内部灰度值只在几个固定的方向上变化较为明显,那么该点则处在边缘区域(如图中间部分);当向各个方向移动,其变化都是很明显,则该点为角点(如图右)。

当然,上面所说的变化明显与否,是与我们事先设定的阀值进行对比的。

(2)moravec算法对角点定义:

窗口在各个方向上移动,窗口内的灰度值都会产生较大的变化。但实际程序中,这里的各个方向实际只有8个方向。即米形0°,45°,90°,135°,180°,225°,270°,315°。

例如:

这里我们为了简单起见,我们只取了四个方向(0°,45°,90°,135°),取一个w*w(如:5x5)的方形窗口, 计算0度、45度、90度、135度四个方向灰度差的平方和, 取其中的最小值作为该像素点的兴趣值(如下图)。

公式:    




(3)moravec角点检测实现:

步骤:

<1>对于每一个像素点,计算在E(u,v),在我们的算法中,(u,v)的取值是((1,0), (1,1), (0,1), (-1, 1),这里只取了四个方向

       <2>计算最小值对应的每个位置minValue = min{E(u,v)}

       <3>对每个位置minValue进行判定,是不是大于设定的阀值,其中还有个过程是判断其是否为局部最大值以防止产生重复的角点

   代码:

#include <iostream>
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"

using namespace std;

int getMoravec(IplImage *src, CvSeq *corners, float threshold)
{
	int winSize = 5;
	int y, x;
	int halfwin = winSize/2;
	int win;
	IplImage *diffDst = cvCreateImage(cvGetSize(src), 32, 1);  // 保存最小的变量值
	int cornersCount = 0;   // 保存角点个数
	for(y = halfwin; y < src->height - halfwin; y++)
	{
		for(x = halfwin; x < src->width - halfwin; x++)
		{
			float cornersResult[4];
			cornersResult[0] = 0;
			cornersResult[1] = 0;
			cornersResult[2] = 0;
			cornersResult[3] = 0;
			float minValue;
			for(win = -halfwin; win < halfwin; win++)
			{
				cornersResult[0] += pow(cvGetReal2D(src, y, x+win) - cvGetReal2D(src, y, x+win+1), 2);
				cornersResult[1] += pow(cvGetReal2D(src, y+win, x+win) - cvGetReal2D(src, y+win+1, x+win+1), 2);
				cornersResult[2] += pow(cvGetReal2D(src, y+win, x) - cvGetReal2D(src, y+win+1, x), 2);
				cornersResult[3] += pow(cvGetReal2D(src, y+win, x-win) - cvGetReal2D(src, y+win+1, x-win-1),2);
			}
			minValue = cornersResult[0];
			minValue = minValue < cornersResult[1] ? minValue : cornersResult[1];
			minValue = minValue < cornersResult[2] ? minValue : cornersResult[2];
			minValue = minValue < cornersResult[3] ? minValue : cornersResult[3];
			cvSetReal2D(diffDst, y, x, minValue);
		}
	}
	int yywin, xxwin, maxValue;
	CvPoint resultLoc;
	for(y = halfwin; y < src->height - halfwin; )
	{
		for(x = halfwin; x < src->width - halfwin;)
		{	
			resultLoc.x = -1;
			resultLoc.y = -1;
			maxValue = 0;
			for(yywin = -halfwin; yywin <= halfwin; yywin++)
			{
				for(xxwin = -halfwin; xxwin < halfwin; xxwin++)
				{
					if(cvGetReal2D(diffDst, y+yywin, x+xxwin) > maxValue)
					{
						maxValue = cvGetReal2D(diffDst, y+yywin, x+xxwin);
						resultLoc.y = y+yywin;
						resultLoc.x = x+xxwin; 
					}
				}
			}
			if(maxValue > threshold)
			{
				cvSeqPush(corners, &resultLoc);    //  将角点加入到corners中  这个函数需要记住*******
				cornersCount ++;
			}
			x += winSize;       //  ++  可能会出现多个corners
		}
		y += winSize;
		
	}
	cvReleaseImage(&diffDst);
	return cornersCount;
}
int main()
{
	IplImage *src = cvLoadImage("E:\\study_opencv_video\\lesson17_1\\1.bmp", 0);
	if(!src)
	{
		cout << "No Image loading..." << endl;
		return 0;
	}
	CvSeq *corners;
	CvMemStorage *mem = cvCreateMemStorage(0);  // 创建内存序列  用于保存最终角点的空间
	corners = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), mem);  // corners指向该内存序列  角点将会保存在一个CvSeq中
	float threshold =30000;
	// 调用函数计算角点
	int cornersCount = getMoravec(src, corners, threshold);

		//图像show用于显示角的提取结果
	IplImage* show= cvCreateImage(cvGetSize(src),8,3);
	cvCvtColor(src,show,CV_GRAY2BGR);


	// 获取每一个角点的坐标
	for(int i = 0; i < cornersCount; i++)
	{
		// 以角点坐标为中心, 绘制一个半斤为5的圆
		CvPoint *pt = (CvPoint *)cvGetSeqElem(corners, i);  // 这个也得记住*******
		cvCircle(show, *pt, 5, cvScalar(0,0,255));
	}
	cvNamedWindow("show");
	cvShowImage("show", show);
	cvWaitKey(0);
	cvReleaseImage(&src);
	cvReleaseImage(&show);
	cvReleaseMemStorage(&mem);    // 这个也得记住***
	cvDestroyWindow("show");
	return 0;



}
 效果:

附加:简单解释下代码中的cvSeq和cvMemStorage,我用的不是太熟,当做笔记了哈哈~~:

CvMemStorage *mem = cvCreateMemStorage(0);  //创建内存序列
CvSeq*corners = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), mem);  // corners指向内存序列
cvSeqPush(corners, &resultLoc);    //  将点加入到内存序列中
CvPoint *pt = (CvPoint *)cvGetSeqElem(corners, i);  // 获得seq中第i个元素
cvReleaseMemStorage(&mem);   //释放内存序列空间
cvSeqRemove(corners,i);  // 移除第i个点
cvSeqSort(corners,cmpFunc,0);// 对内存序列中的点进行排序

//对seq排序时的比较函数
static int cmpFunc(const void* _cur , const void* _next , void* userdata)
{
	PHARRISPOINT cur = (PHARRISPOINT)_cur;
	PHARRISPOINT next = (PHARRISPOINT)_next;

	return cur->cornerness < next->cornerness ? 1 : -1;
}


(4)moravec角点检测的缺点

moravec角点检测主要有两个缺点:

一:不具有旋转不变性

二:对边缘点的反应比较强烈



作者:小村长  出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)  





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv学习_11 (moravec角点检测及缺点) 的相关文章

  • 如何在 Ubuntu 16.04 上安装适用于 Python 2.7 的 openCV 2.4.13?

    我尝试了很多在线帖子来安装 opencv 但它们不适用于 Ubuntu 16 04 有人可以给我安装 openCV 2 4 13 的步骤吗 我不久前制作了一个脚本 用于安装最新版本的 OpenCV 截至本答案的最后一次更新为 4 2 这是它
  • 变形:Opencv 使用 Visual Studio 将图像显示到曲面屏幕

    我正在尝试使用 opencv API 来扭曲图像 以便将其显示到曲面屏幕上 我已经浏览了opencv中提供的翘曲apihere http docs opencv org 2 4 modules stitching doc warpers h
  • 如何在 OpenCV 中删除 mouseCallback

    在使用 C 的 OpenCV 中 有没有办法删除 mouseHandler int event int x int y int flags void param 通过函数添加到窗口 image window cv setMouseCallb
  • 如何使用 Python 3 在 OpenCV 3 上正确加载 cv2.KeyPoint 和描述符?

    有一天 我不得不恢复一个使用 OpenCV 3 和 Python 2 7 的旧项目 在此代码中 要加载 cv2 KeyPoint 我执行以下操作 import numpy as np import cPickle import cv2 ke
  • OpenCV Python 删除图像中的某些对象

    我正在使用带有 opencv 和 numpy 的 python 来检测天文中的星星 例如这个1 https i stack imgur com AKwEJ jpg图片 使用模板匹配 我可以用阈值检测星星 单击 2 2 https i sta
  • 针对不同相机(RGB 和红外)的 StereoCalibrate

    我在校准两个摄像头时遇到问题 第一个是 RGB 第二个是红外 它们有不同的分辨率 我调整了大小并裁剪了更大的图像 焦距等等 例子 RGB 1920x1080 Infrared 512x424 如何相互校准它们 我应该在stereoCalib
  • 检测骰子的上侧

    是否可以检测骰子的上面 虽然从顶部看这将是一项简单的任务 但从许多角度来看 可以看到多个侧面 Here is an example of a dice feel free to take your own pictures 您通常想知道自己
  • 使用 Unity3D 解决 PnP

    我有一个真实 物理的棍子 上面连接有红外摄像头和一些红外 LED 它们形成了我正在使用的模式 以便使虚拟棍子以与物理棍子相同的方式移动 为此 我在 Python 中使用 OpenCV 并将由solvePnP 计算的旋转和平移向量发送到 Un
  • 如何使用 OpenCV 从图像中获取调色板 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想提取图像的调色板 类似于此 来自 我需要它来提取特定的颜色 如黄色 绿色和棕色 并显示该颜色覆盖的区域的百分比 另外 我可以添加更
  • OpenCV:使用 StereoCamera 系统对颜色标记进行 3D 姿态估计

    我有一个立体摄像系统并使用两者正确校准它 cv calibrateCamera and cv stereoCalibrate My reprojection error似乎没问题 凸轮0 0 401427 凸轮1 0 388200 立体声
  • 如何使用Java OpenCV

    我正在使用图像处理开始我的最后一年项目 并希望完成类似的事情this http www youtube com watch v EPai5f2sWaA 它是人体和物体检测的结合 我真的很想用 Java 来做 因为我在 C 方面的经验很少 I
  • OpenCV,捕获的视频比原始相机视频运行得更快!

    我正在使用 openCV 从相机捕获视频并将其存储到 avi 文件 问题是当我完成捕获并运行 avi 文件时 视频流看起来速度很快 这是代码 void main CvCapture capture cvCaptureFromCAM 0 in
  • 使用 SURF 在检测到的对象周围绘制矩形

    我正在尝试从涉及冲浪检测器的以下代码中检测对象 我不想绘制匹配项 我想在检测到的对象周围绘制一个矩形 但不知何故我无法获得正确的单应性 请任何人指出在哪里我走错了 include
  • OpenCV 旋转图像而不裁剪澄清

    我想扩展这个主题 参考用户 Lars Schillingmann 给出的这个 SO 问题和接受的答案 在 C 中的 OpenCV 中旋转图像而不裁剪 https stackoverflow com questions 22041699 ro
  • OpenCV Python RTSP 流

    我想使用 RTSP 从 IP 摄像机流式传输视频 但我有一个问题 我已经安装了先决条件 而且我的 RTSP 链接可以在 VlC 播放器上运行 但是当我在编辑器中尝试并运行它时 它说找不到相机 这是我的代码 import cv2 import
  • Android for OpenCV - 打开跟踪文件时出错,UnsatisfiedLinkError

    我对 Android 开发和 OpenCV 都是新手 我从 Android 下载了 OpenCV 库http sourceforge net projects opencvlibrary files opencv android http
  • GrabCut - bgdModel 和 fgdModel 为空 - 断言错误

    我正在尝试使用 OpenCV2 1 C 中的 GrabCut 算法进行图像分割 这是我的代码 Mat rgbWorkImage imread argv 1 Mat mask mask Scalar 0 Mat bgdModel fgdMod
  • python openCV 中的人口普查变换

    我开始在一个与立体视觉相关的项目中使用 openCV 和 python 我找到了关于使用 openCV 在 C 中进行人口普查转换的文档页面 link http docs opencv org 3 1 0 d2 d7f namespacec
  • 从凸点获取角点

    我编写了算法来提取图像中显示的点 它们形成凸形 我知道它们的顺序 如何从这些点中提取角点 顶部 3 个和底部 3 个 我正在使用opencv 如果你已经有了物体的凸包 并且该包包含角点 那么你需要做的就是简化包直到它只有 6 个点 有很多方
  • 如何识别与我的对象相关的轮廓并找到它们的几何质心

    问题陈述和背景信息 EDIT 约束 法兰上的红色会随着时间的推移而变化 所以我此时不会尝试使用颜色识别来识别我的对象 除非它足够强大 此外 外部照明也可能是一个因素 因为将来这将是在室外区域 我有 RGB 深度相机 有了它 我就能捕捉到这个

随机推荐