34 Opencv 自定义角点检测

文章目录

cornerEigenValsAndVecs

c 复制代码
void cornerEigenValsAndVecs(
       InputArray src,       --单通道输入8位或浮点图像
       OutputArray dst,    --输出图像,同源图像或CV_32FC(6)
       int blockSize,         --邻域大小值
       int apertureSize,    --Sobel算子当中的核大小
       int borderType=BORDER_DEFAULT --像素外插方法
)//对应于Harris

cornerMinEigenVal

c 复制代码
void cornerMinEigenVal(
       InputArray src,     --单通道输入8位或浮点图像
       OutputArray dst,  --图像存储的最小特征值。类型为CV_32FC1
       int blockSize,       --邻域大小值
       int apertureSize=3,   --Sobel算子的参数
       int borderType=BORDER_DEFAULT  --像素外插方法
}//对应Shi-Tomasi

示例

c 复制代码
#include <opencv2/opencv.hpp> // 包含OpenCV库的头文件
#include <iostream>           // 包含标准输入输出流库

#include <math.h>             // 包含数学函数库
using namespace cv;           // 使用cv命名空间,以避免每次调用OpenCV函数时都要写cv::
using namespace std;          // 使用std命名空间,以便使用cout, cin等函数

const char* harris_win = "Custom Harris Corners Detector"; // 定义Harris角点检测结果窗口名称
const char* shitomasi_win = "Custom Shi-Tomasi Corners Detector"; // 定义Shi-Tomasi角点检测结果窗口名称
Mat src, gray_src;            // 声明源图像和灰度图变量

// Harris角点响应相关的矩阵及最大最小响应值
Mat harris_dst, harrisRspImg;
double harris_min_rsp;
double harris_max_rsp;

// Shi-Tomasi角点响应相关的矩阵及最大最小响应值
Mat shiTomasiRsp;
double shitomasi_max_rsp;
double shitomasi_min_rsp;

int sm_qualitylevel = 30;     // Shi-Tomasi质量级别初始值
int qualityLevel = 30;        // Harris质量级别初始值
int max_count = 100;          // 滑动条的最大值

void CustomHarris_Demo(int, void*); // 声明Harris角点检测回调函数
void CustomShiTomasi_Demo(int, void*);// 声明Shi-Tomasi角点检测回调函数

int main(int argc, char** argv) {
    src = imread("D:/vcprojects/images/home.jpg"); // 读取图片到src Mat对象中
    if (src.empty()) {                             // 检查是否成功加载图片
        printf("could not load image...\n");
        return -1;
    }
    namedWindow("input image", CV_WINDOW_AUTOSIZE); // 创建一个名为"input image"的窗口
    imshow("input image", src);                     // 在该窗口中显示原始图像

    cvtColor(src, gray_src, COLOR_BGR2GRAY);        // 将BGR格式的src转换为灰度图gray_src

    // 计算特征值(Harris角点)
    int blockSize = 3;      // 邻域大小
    int ksize = 3;          // Sobel算子的孔径参数
    double k = 0.04;        // Harris公式中的自由参数k
    harris_dst = Mat::zeros(src.size(), CV_32FC(6)); // 初始化用于存储特征值和向量的矩阵
    harrisRspImg = Mat::zeros(src.size(), CV_32FC1); // 初始化用于存储Harris响应值的矩阵
    cornerEigenValsAndVecs(gray_src, harris_dst, blockSize, ksize, 4); // 计算每个像素处的特征值和特征向量

    // 计算Harris响应值
    for (int row = 0; row < harris_dst.rows; row++) {
        for (int col = 0; col < harris_dst.cols; col++) {
            double lambda1 = harris_dst.at<Vec6f>(row, col)[0]; // 获取第一个特征值
            double lambda2 = harris_dst.at<Vec6f>(row, col)[1]; // 获取第二个特征值
            harrisRspImg.at<float>(row, col) = lambda1 * lambda2 - k * pow((lambda1 + lambda2), 2); // 计算Harris响应值
        }
    }

    minMaxLoc(harrisRspImg, &harris_min_rsp, &harris_max_rsp, 0, 0, Mat()); // 找到响应值中的最大最小值

    namedWindow(harris_win, CV_WINDOW_AUTOSIZE); // 创建一个用于显示Harris角点检测结果的窗口
    createTrackbar("Quality Value:", harris_win, &qualityLevel, max_count, CustomHarris_Demo); // 创建滑块以调整质量级别
    CustomHarris_Demo(0, 0); // 初始调用回调函数

    // 计算最小特征值(Shi-Tomasi角点)
    shiTomasiRsp = Mat::zeros(src.size(), CV_32FC1); // 初始化用于存储Shi-Tomasi响应值的矩阵
    cornerMinEigenVal(gray_src, shiTomasiRsp, blockSize, ksize, 4); // 计算每个像素处的最小特征值

    minMaxLoc(shiTomasiRsp, &shitomasi_min_rsp, &shitomasi_max_rsp, 0, 0, Mat()); // 找到响应值中的最大最小值

    namedWindow(shitomasi_win, CV_WINDOW_AUTOSIZE); // 创建一个用于显示Shi-Tomasi角点检测结果的窗口
    createTrackbar("Quality:", shitomasi_win, &sm_qualitylevel, max_count, CustomShiTomasi_Demo); // 创建滑块以调整质量级别
    CustomShiTomasi_Demo(0, 0); // 初始调用回调函数

    waitKey(0); // 等待按键事件
    return 0;
}

// Harris角点检测回调函数:根据用户设定的质量级别绘制角点
void CustomHarris_Demo(int, void*) {
    if (qualityLevel < 10) { // 设定最低质量级别
        qualityLevel = 10;
    }
    Mat resultImg = src.clone(); // 复制原始图像用于绘制角点
    float t = harris_min_rsp + (((double)qualityLevel) / max_count) * (harris_max_rsp - harris_min_rsp); // 根据质量级别计算阈值
    for (int row = 0; row < src.rows; row++) {
        for (int col = 0; col < src.cols; col++) {
            float v = harrisRspImg.at<float>(row, col); // 获取当前像素的Harris响应值
            if (v > t) { // 如果响应值大于阈值,则认为是角点
                circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0); // 在图像上绘制红色圆圈标记角点
            }
        }
    }
    imshow(harris_win, resultImg); // 显示带有角点标记的图像
}

// Shi-Tomasi角点检测回调函数:根据用户设定的质量级别绘制角点
void CustomShiTomasi_Demo(int, void*) {
    if (sm_qualitylevel < 20) { // 设定最低质量级别
        sm_qualitylevel = 20;
    }

    Mat resultImg = src.clone(); // 复制原始图像用于绘制角点
    float t = shitomasi_min_rsp + (((double)sm_qualitylevel) / max_count) * (shitomasi_max_rsp - shitomasi_min_rsp); // 根据质量级别计算阈值
    for (int row = 0; row < src.rows; row++) {
        for (int col = 0; col < src.cols; col++) {
            float v = shiTomasiRsp.at<float>(row, col); // 获取当前像素的Shi-Tomasi响应值
            if (v > t) { // 如果响应值大于阈值,则认为是角点
                circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0); // 在图像上绘制红色圆圈标记角点
            }
        }
    }
    imshow(shitomasi_win, resultImg); // 显示带有角点标记的图像
}
相关推荐
AndrewHZ12 分钟前
【图像处理基石】GIS图像处理入门:4个核心算法与Python实现(附完整代码)
图像处理·python·算法·计算机视觉·gis·cv·地理信息系统
掘金安东尼16 分钟前
Google+禁用“一次性抓取100条搜索结果”,SEO迎来变革?
人工智能
FIN666822 分钟前
射频技术领域的领航者,昂瑞微IPO即将上会审议
前端·人工智能·前端框架·信息与通信
小麦矩阵系统永久免费32 分钟前
短视频矩阵系统哪个好用?2025最新评测与推荐|小麦矩阵系统
大数据·人工智能·矩阵
Mr.Lee jack35 分钟前
【vLLM】源码解读:高性能大语言模型推理引擎的工程设计与实现
人工智能·语言模型·自然语言处理
IT_陈寒42 分钟前
Java性能优化:这5个Spring Boot隐藏技巧让你的应用提速40%
前端·人工智能·后端
MicroTech20251 小时前
微算法科技(NASDAQ:MLGO)开发延迟和隐私感知卷积神经网络分布式推理,助力可靠人工智能系统技术
人工智能·科技·算法
喜欢吃豆1 小时前
多轮智能对话系统架构方案(可实战):从基础模型到自我优化的对话智能体,数据飞轮的重要性
人工智能·语言模型·自然语言处理·系统架构·大模型·多轮智能对话系统
文火冰糖的硅基工坊1 小时前
[嵌入式系统-83]:算力芯片的类型与主流架构
人工智能·重构·架构
视觉语言导航3 小时前
ICRA-2025 | 阿德莱德机器人拓扑导航探索!TANGO:具有局部度量控制的拓扑目标可穿越性感知具身导航
人工智能·机器人·具身智能