Harris算法提取角点技术详解

版权申诉
0 下载量 187 浏览量 更新于2024-10-02 收藏 859KB RAR 举报
资源摘要信息:"角点提取程序 Corner.rar" 一、知识点概述 角点提取是计算机视觉和图像处理领域的一个重要任务,它涉及到从图像中识别出具有独特性的点,这些点在图像的局部区域内有较高的曲率变化,通常被认为是图像特征的一部分,对于图像识别、图像配准、目标跟踪等任务至关重要。 二、角点提取的Harris算法 Harris算法是一种广泛使用的角点检测方法,由Chris Harris和Mike Stephens于1988年提出。该算法的核心思想基于信号处理中的自相关函数。Harris角点检测器认为在角点处,图像函数的梯度在各个方向上都应该有较大的变化,因此其算法步骤如下: 1. 计算图像梯度:首先需要计算图像在x和y方向上的梯度(即使用Sobel算子或Prewitt算子等进行边缘检测),得到图像在x和y方向的梯度矩阵Ix和Iy。 2. 计算梯度乘积:计算Ix和Iy的乘积矩阵,得到一个H矩阵,反映了该点在各个方向上的梯度变化。 3. 应用高斯滤波:为了减少噪声的影响,对H矩阵进行高斯平滑处理。 4. 角点响应函数:通过H矩阵计算角点响应函数(Corner Response Function, CRF),这通常通过提取矩阵H中局部极值点来完成,以确定角点的位置。 5. 确定角点阈值:通常会设定一个阈值,只有超过这个阈值的CRF值对应的点才会被认为是角点。 三、角点提取程序 角点提取程序 "Corner.rar" 通过封装Harris算法的实现,提供了一个简单易用的接口,使得用户能够方便地进行角点提取。具体来说,程序可能包含了以下几个关键功能: 1. 图像预处理:程序可能包含了图像读取、灰度化和高斯滤波等预处理步骤,为角点检测做好准备。 2. Harris角点检测:实现Harris算法的核心功能,包括梯度计算、梯度乘积、高斯平滑和角点响应函数的计算。 3. 角点定位与输出:在检测到角点响应函数的局部极值点后,程序将这些点在原图上进行定位,并以某种形式输出结果,可能包括绘制角点标记、输出角点坐标等。 4. 参数设置与阈值调整:程序可能允许用户设置算法中的参数,比如高斯滤波器的窗口大小和标准差,以及角点响应函数的阈值等。 四、应用场景 角点提取程序 "Corner.rar" 应用广泛,具体应用场景包括但不限于: 1. 机器人导航:在机器人视觉系统中,角点可以作为路径规划的特征点,帮助机器人定位自身位置。 2. 图像拼接:通过角点匹配可以实现多张图像的无缝拼接,用于创建全景图。 3. 视频跟踪:角点作为稳定特征,可以用于目标跟踪,在视频监控、运动分析等领域有着重要的应用。 4. 三维重建:角点可作为重建三维场景的基础特征,有助于从二维图像推断出三维结构。 总结来说,Harris角点检测算法和角点提取程序 "Corner.rar" 提供了一种快速准确地从图像中提取角点的方法,这些角点信息在计算机视觉和图像处理的许多高级任务中都具有极其重要的应用价值。通过封装良好的程序接口,即使是不具备深厚专业知识的用户也能够轻松地应用角点检测技术。

#include "prepare_ogm.hpp" namespace senior { namespace guardian { namespace prepare { std::string PrepareOgm::Name() { return "Prepare Ogm Element"; } void PrepareOgm::Initiate() {} void PrepareOgm::Process(data::DataFrame& his, data::DataFrame& cur) { if (cur.source_ogm_points_.is_invalid()) return; if (cur.source_visual_ogm_points_.is_valid()) { cur.source_ogm_points_.insert(cur.source_ogm_points_.end(), cur.source_visual_ogm_points_.begin(), cur.source_visual_ogm_points_.end()); } if (cur.source_higher_ogm_points_.is_valid()) { cur.source_ogm_points_.insert(cur.source_ogm_points_.end(), cur.source_higher_ogm_points_.begin(), cur.source_higher_ogm_points_.end()); } auto& predict_path = cur.monitor_data_.mutable_predict_path(); predict_path.GenerateBoundary(cur); cur.AABox2d_ = predict_path.vehicle_AABox2d_; // if (!his.monitor_data_.is_need_to_take_over()) { // LOG(INFO)<<"1"; cur.AABox2d_.SetWidth(cur.AABox2d_.width() + 1.0); cur.AABox2d_.SetLength(cur.AABox2d_.length() + 1.0); // } std::vector<math::Vec2d> corner_points_; cur.AABox2d_.GetAllCorners(&corner_points_); auto& polygon2d = predict_path.tractor_polygon2d_; math::Vec2d temp; VoxelGrid filter_; common::Time now = common::Time::Now(); for (auto& point : cur.source_ogm_points_) { temp.set_x(point.x()); temp.set_y(-point.y()); if (cur.AABox2d_.IsPointIn(temp)) { cur.AABB_ogm_points_.emplace_back(point); } } cur.guardian_diagnose_["Prepare_PrepareOgm_AABox_filter"] = std::to_string((common::Time::Now() - now).ToSecond() * 1000); now = common::Time::Now(); filter_.VoxelGrid_ApplyFilter( cur.AABB_ogm_points_, cur.ogm_points_, corner_points_, 0.1, 0.1, 0); cur.guardian_diagnose_["Prepare_PrepareOgm_VoxelGrid_ApplyFilter"] = std::to_string((common::Time::Now() - now).ToSecond() * 1000); cur.ogm_points_.set_stamp(cur.source_ogm_points_.stamp()); cur.ogm_points_.set_time(cur.source_ogm_points_.time()); cur.ogm_points_.set_delay_time(cur.source_ogm_points_.delay_time()); cur.ogm_points_.set_valid(); } } // namespace prepare } // namespace guardian } // namespace senior 改变为C语言程序

2023-06-13 上传

请详细解释下这段代码void FaceTracker::OnNewFaceData( const std::vector<human_sensing::CrosFace>& faces) { // Given |f1| and |f2| from two different (usually consecutive) frames, treat // the two rectangles as the same face if their position delta is less than // kFaceDistanceThresholdSquare. // // This is just a heuristic and is not accurate in some corner cases, but we // don't have face tracking. auto is_same_face = [&](const Rect<float>& f1, const Rect<float>& f2) -> bool { const float center_f1_x = f1.left + f1.width / 2; const float center_f1_y = f1.top + f1.height / 2; const float center_f2_x = f2.left + f2.width / 2; const float center_f2_y = f2.top + f2.height / 2; constexpr float kFaceDistanceThresholdSquare = 0.1 * 0.1; const float dist_square = std::pow(center_f1_x - center_f2_x, 2.0f) + std::pow(center_f1_y - center_f2_y, 2.0f); return dist_square < kFaceDistanceThresholdSquare; }; for (const auto& f : faces) { FaceState s = { .normalized_bounding_box = Rect<float>( f.bounding_box.x1 / options_.active_array_dimension.width, f.bounding_box.y1 / options_.active_array_dimension.height, (f.bounding_box.x2 - f.bounding_box.x1) / options_.active_array_dimension.width, (f.bounding_box.y2 - f.bounding_box.y1) / options_.active_array_dimension.height), .last_detected_ticks = base::TimeTicks::Now(), .has_attention = std::fabs(f.pan_angle) < options_.pan_angle_range}; bool found_matching_face = false; for (auto& known_face : faces_) { if (is_same_face(s.normalized_bounding_box, known_face.normalized_bounding_box)) { found_matching_face = true; if (!s.has_attention) { // If the face isn't looking at the camera, reset the timer. s.first_detected_ticks = base::TimeTicks::Max(); } else if (!known_face.has_attention && s.has_attention) { // If the face starts looking at the camera, start the timer. s.first_detected_ticks = base::TimeTicks::Now(); } else { s.first_detected_ticks = known_face.first_detected_ticks; } known_face = s; break; } } if (!found_matching_face) { s.first_detected_ticks = base::TimeTicks::Now(); faces_.push_back(s); } } // Flush expired face states. for (auto it = faces_.begin(); it != faces_.end();) { if (ElapsedTimeMs(it->last_detected_ticks) > options_.face_phase_out_threshold_ms) { it = faces_.erase(it); } else { ++it; } } }

2023-06-08 上传
2023-06-10 上传