OpenCV C++ 特征提取:從角點檢測到對象識別

特征提取是計算機視覺的核心技術,通過識別圖像中具有代表性的關鍵點及其描述信息,實現圖像匹配、對象識別、姿態估計等高級任務。本章將系統講解從基礎的圖像金字塔、角點檢測,到復雜的 ORB 和 SIFT 特征提取與匹配,最終實現基于特征的對象檢測完整流程。

一、圖像金字塔

圖像金字塔是多尺度表示圖像的有效方法,通過構建不同分辨率的圖像集合,實現多尺度特征提取。

1.1 高斯金字塔

高斯金字塔通過下采樣(縮小)構建,每一層都是對上層圖像進行高斯模糊后再隔點采樣得到。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;// 構建高斯金字塔
vector<Mat> buildGaussianPyramid(const Mat& img, int levels) {vector<Mat> pyramid;pyramid.push_back(img.clone());  // 第0層(原始圖像)Mat current = img;for (int i = 1; i < levels; ++i) {Mat down;// 高斯模糊并下采樣(尺寸減半)pyrDown(current, down);pyramid.push_back(down);current = down;}return pyramid;
}// 顯示高斯金字塔
void showGaussianPyramid(const vector<Mat>& pyramid) {// 創建一個大圖像拼接所有金字塔層int totalHeight = 0;int maxWidth = 0;for (const auto& layer : pyramid) {totalHeight += layer.rows;maxWidth = max(maxWidth, layer.cols);}Mat display(totalHeight, maxWidth, CV_8UC3, Scalar(0, 0, 0));int y = 0;for (size_t i = 0; i < pyramid.size(); ++i) {const Mat& layer = pyramid[i];// 將當前層復制到顯示圖像layer.copyTo(display(Rect(0, y, layer.cols, layer.rows)));// 顯示層索引string text = "Level " + to_string(i);putText(display, text, Point(10, y + 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0), 2);y += layer.rows;}imshow("高斯金字塔", display);
}

1.2 拉普拉斯金字塔

拉普拉斯金字塔通過高斯金字塔各層與上層上采樣后的差值構建,用于表示圖像的細節信息。

// 構建拉普拉斯金字塔
vector<Mat> buildLaplacianPyramid(const vector<Mat>& gaussianPyramid) {vector<Mat> laplacianPyramid;for (size_t i = 0; i < gaussianPyramid.size() - 1; ++i) {Mat up;// 上采樣高斯金字塔上層pyrUp(gaussianPyramid[i + 1], up, gaussianPyramid[i].size());// 當前層減去上采樣結果得到拉普拉斯層Mat laplacian = gaussianPyramid[i] - up;laplacianPyramid.push_back(laplacian);}// 最后一層為高斯金字塔的頂層laplacianPyramid.push_back(gaussianPyramid.back().clone());return laplacianPyramid;
}// 從拉普拉斯金字塔重建圖像
Mat reconstructFromLaplacian(const vector<Mat>& laplacianPyramid) {Mat current = laplacianPyramid.back();for (int i = laplacianPyramid.size() - 2; i >= 0; --i) {Mat up;pyrUp(current, up, laplacianPyramid[i].size());current = up + laplacianPyramid[i];}return current;
}

1.3 圖像金字塔應用

// 多尺度特征檢測示例
void multiScaleFeatureDetection(const Mat& img) {// 構建3層高斯金字塔vector<Mat> gaussian = buildGaussianPyramid(img, 3);// 在不同尺度上檢測邊緣vector<Mat> edges;for (const auto& layer : gaussian) {Mat gray, edge;cvtColor(layer, gray, COLOR_BGR2GRAY);Canny(gray, edge, 50, 150);// 轉換為彩色以便顯示Mat edgeColor;cvtColor(edge, edgeColor, COLOR_GRAY2BGR);edges.push_back(edgeColor);}// 顯示結果imshow("原始圖像", img);showGaussianPyramid(gaussian);// 顯示多尺度邊緣Mat edgeDisplay;vconcat(edges, edgeDisplay);imshow("多尺度邊緣檢測", edgeDisplay);
}int main() {Mat img = imread("building.jpg");if (img.empty()) {cout << "圖像加載失敗!" << endl;return -1;}// 高斯金字塔示例vector<Mat> gaussian = buildGaussianPyramid(img, 4);showGaussianPyramid(gaussian);// 拉普拉斯金字塔示例vector<Mat> laplacian = buildLaplacianPyramid(gaussian);// 從拉普拉斯金字塔重建圖像Mat reconstructed = reconstructFromLaplacian(laplacian);imshow("原始圖像", img);imshow("從拉普拉斯重建", reconstructed);// 多尺度特征檢測multiScaleFeatureDetection(img);waitKey(0);destroyAllWindows();return 0;
}

圖像金字塔關鍵應用

  • 多尺度特征檢測(確保不同大小的物體都能被檢測到)
  • 圖像融合與拼接
  • 目標跟蹤(適應目標大小變化)
  • 特征匹配(提高匹配魯棒性)

二、角點檢測

角點是圖像中亮度變化劇烈的點或在兩個邊緣交叉處的點,是最常用的局部特征之一。

2.1 Harris 角點檢測

Harris 角點檢測基于圖像灰度的局部變化,通過計算自相關矩陣的特征值來判斷是否為角點。

// Harris角點檢測
Mat detectHarrisCorners(const Mat& gray, double qualityLevel = 0.01, double k = 0.04) {Mat dst, dstNorm, dstScaled;// 檢測Harris角點cornerHarris(gray, dst, 2, 3, k, BORDER_DEFAULT);// 歸一化結果normalize(dst, dstNorm, 0, 255, NORM_MINMAX, CV_32FC1, Mat());convertScaleAbs(dstNorm, dstScaled);// 繪制角點Mat result = gray.clone();cvtColor(result, result, COLOR_GRAY2BGR);for (int i = 0; i < dstNorm.rows; ++i) {for (int j = 0; j < dstNorm.cols; ++j) {if ((int)dstNorm.at<float>(i, j) > qualityLevel * 255) {circle(result, Point(j, i), 5, Scalar(0, 0, 255), 2);}}}return result;
}

Harris 角點響應函數:

R = det(M) - k*(trace(M))2

其中,M是自相關矩陣,det(M)是行列式,trace(M)是跡,k是經驗常數(通常取 0.04~0.06)。

  • R > 0且較大:角點
  • R ≈ 0:邊緣
  • R < 0且較小:平坦區域

2.2 Shi-Tomasi 角點檢測

Shi-Tomasi 角點檢測是 Harris 算法的改進,使用兩個特征值中的最小值作為響應函數,提高了角點檢測的穩定性。

// Shi-Tomasi角點檢測
Mat detectShiTomasiCorners(const Mat& gray, int maxCorners = 100, double qualityLevel = 0.01, double minDistance = 10) {vector<Point2f> corners;// 參數設置TermCriteria criteria(TermCriteria::EPS | TermCriteria::MAX_ITER, 30, 0.001);// 檢測Shi-Tomasi角點goodFeaturesToTrack(gray, corners, maxCorners, qualityLevel, minDistance, Mat(), 3, false, 0.04);// 繪制角點Mat result = gray.clone();cvtColor(result, result, C

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96466.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96466.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96466.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Codeforces Round 1049 (Div. 2) D題題解記錄

大致題意&#xff1a;給定nnn個區間(li,ri)(l_i,r_i)(li?,ri?)。每次選取兩個尚未被標記的區間(l1,r1)(l_1,r_1)(l1?,r1?)與(l2,r2)(l_2,r_2)(l2?,r2?)&#xff0c;使得他們均被標記&#xff0c;同時可以任選x∈[l1,r1]&#xff0c;y∈[l2,r2]x\in[l_1,r_1]&#xff0c;y…

《WINDOWS 環境下32位匯編語言程序設計》第15章 注冊表和INI文件

15.1 注冊表和INI文件簡介在一個操作系統中&#xff0c;無論是操作系統本身還是運行于其中的大部分應用程序&#xff0c;都需要使用某種方式保存配置信息。在DOS系統中&#xff0c;配置信息往往是軟件的開發者根據自己的喜好用各種途徑加以保存的&#xff0c;比如在磁盤上面寫一…

JDK 17、OpenJDK 17、Oracle JDK 17 的說明

Java生態系統的核心概念&#xff1a;簡單來說&#xff1a;JDK 17 是一個標準規范&#xff0c;定義了Java開發工具包第17個長期支持版應該包含什么功能。openjdk-17-jdk 是一個具體的實現&#xff0c;是遵循上述規范、由OpenJDK社區提供的開源軟件包。下面我們通過一個表格和詳細…

手寫MyBatis第58彈:如何優雅輸出可執行的SQL語句--深入理解MyBatis日志機制:

&#x1f942;(???)您的點贊&#x1f44d;?評論&#x1f4dd;?收藏?是作者創作的最大動力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;點贊&#x1f44d;收藏??留言&#x1f4dd;歡迎留言討論 &#x1f525;&#x1f525;&…

Spring Boot 監控實戰:集成 Prometheus 與 Grafana,打造全方位監控體系

前言 在當今微服務架構盛行的時代&#xff0c;應用程序的監控變得尤為重要。Spring Boot 作為廣泛使用的微服務框架&#xff0c;其監控需求也日益增加。Prometheus 和 Grafana 作為開源監控領域的佼佼者&#xff0c;為 Spring Boot 應用提供了強大的監控能力。本文將詳細介紹如…

JS中的多線程——Web Worker

眾所周知&#xff0c;JavaScript 是單線程運行的&#xff08;至于為什么是單線程可以看一下這篇文章——事件循環機制&#xff09;&#xff0c;當瀏覽器主線程被大量計算任務阻塞時&#xff0c;頁面就會出現明顯的卡頓現象。Web Worker 提供了在獨立線程中運行 JavaScript 的能…

【SQL注入】延時盲注

sleep(n)??: 核心延時函數。使數據庫程序暫停 n秒。??if(condition, true_expr, false_expr)??: 條件判斷函數。如果 condition為真&#xff0c;執行 true_expr&#xff0c;否則執行 false_expr。??用于將延時與判斷條件綁定??。??mid(a, b, c)??: 字符串截取函數…

IntelliJ IDEA 2025.1 Java Stream Debugger 快速使用指南

1. 功能概覽 Java Stream Debugger 提供 Trace Current Stream Chain 功能&#xff0c;用來在調試時分析和可視化 Stream 操作鏈。 主要用途&#xff1a; 在運行時查看流操作鏈的每一步輸出找出 map/filter 等操作的問題避免手動加 peek() 打印調試2. 使用入口 在 IDEA 2025.1 …

ARM-指令集全解析:從基礎到高階應用

一、ARM 指令集體系結構版本ARM 公司定義了多個指令集版本&#xff1a;ARMv1&#xff1a;原型機 ARM1&#xff0c;沒有用于商業產品。ARMv2&#xff1a;擴展 V1&#xff0c;包含 32 位乘法指令和協處理器指令。ARMv3&#xff1a;第一個微處理器 ARM6 核心&#xff0c;支持 Cach…

第3講 機器學習入門指南

近年來&#xff0c;隨著企業和個人生成的數據量呈指數級增長&#xff0c;機器學習已成為日益重要的技術領域。從自動駕駛汽車到流媒體平臺的個性化推薦&#xff0c;機器學習算法已廣泛應用于各個場景。讓我們深入解析機器學習的核心要義。3.1 機器學習定義機器學習是人工智能的…

深入理解跳表:多層索引加速查找的經典實現

跳表&#xff08;Skip List&#xff09;是一種多層有序鏈表結構&#xff0c;通過引入多級索引加速查找&#xff0c;其核心設計類似于“立體高速公路系統”&#xff0c;底層是原始鏈表&#xff0c;上面有各種高度的"高架橋"。 高層道路跨度大&#xff0c;連接遠方節點…

Flutter 視頻播放器——flick_video_player 介紹與使用

在移動端應用中&#xff0c;視頻播放是一個常見的功能場景&#xff0c;例如短視頻、直播、課程、廣告展示等。 Flutter 本身并沒有直接提供視頻播放器組件&#xff0c;而是依賴第三方庫來實現。 今天要介紹的庫是 flick_video_player&#xff0c;它基于 video_player 封裝&…

編寫cmakelists文件常用語句

cmake_minimum_required (VERSION 3.10) 指定最小版本project(XXXX) 指定項目名字 ---------------set(MAIN_EXEC_NAME dwarf_parser) 定義變量${ MAIN_EXEC_NAME } 變量取值set(CMAKE_CXX_STANDARD 14) 指定c14標準&#xff0c;還有11、17、20等標準…

麒麟桌面系統找不到mbr啟動,并重新安裝grub

根據你提供的情況,“麒麟桌面系統找不到MBR啟動”,這通常是由于GRUB引導損壞、MBR記錄丟失或分區表異常導致的。你可以按照以下步驟重新安裝GRUB并修復MBR啟動: ? 步驟一:準備工具 使用銀河麒麟LiveCD或U盤啟動盤(可用Ventoy制作); 啟動電腦,選擇從U盤或光盤進入Live環…

【音頻字幕】構建一個離線視頻字幕生成系統:使用 WhisperX 和 Faster-Whisper 的 Python 實現

一、背景介紹 對于一端沒有字幕外國視頻、字幕&#xff0c;在不懂外語的情況下&#xff0c;怎么獲取相關內容&#xff1f;作為技術宅&#xff0c;怎么自建搭建一個語音轉文字的環境當前AI技術這么發達&#xff1f; 試試 二、系統設計 音頻提取(僅僅是視頻需要該邏輯、本身就是音…

Linux ALSA架構:PCM_OPEN流程 (二)

一 應用端源碼路徑: external\tinyalsa\pcm.c external\tinyalsa\pcm_hw.cstruct pcm *pcm_open(unsigned int card, unsigned int device,unsigned int flags, struct pcm_config *config) {...pcm->ops &hw_ops;pcm->fd pcm->ops->open(card, device,…

tp5的tbmember表閉包查詢 openid=‘abc‘ 并且(wx_unionid=null或者wx_unionid=‘‘)

閉包查詢 tbmember表閉包查詢查詢 openid‘abc并且islose0并且islogout0并且&#xff08;wx_unionidnull或者wx_unionid’&#xff09; Db::table(tbmember)->where([openid>abc,islose>0,islogout>0])->where(function ($query){$query->where(wx_unioni…

邪修實戰系列(3)

1、第一階段邪修實戰總覽&#xff08;9.1-9.30&#xff09; 把第一階段&#xff08;基礎夯實期&#xff09;的學習計劃拆解成極具操作性的每日行動方案。這個計劃充分利用我“在職學習”的特殊優勢&#xff0c;強調“用輸出倒逼輸入”&#xff0c;確保每一分鐘的學習都直接服務…

【GD32】ROM Bootloader、自定義Bootloader區別

Bootloader是應用程序跑起來之前&#xff0c;用于初始化的一段程序&#xff0c;它分為兩種&#xff0c;ROM Bootloader、自定義Bootloader。GD32芯片出廠時預燒錄在ROM中的Bootloader&#xff08;以下簡稱ROM Bootloader&#xff09;和自己編寫的Bootloader&#xff08;以下簡稱…

Linux防火墻-Firewalld

一、 概述 按表現形式劃分&#xff1a; 軟件防火墻&#xff1a; 集成在系統內部&#xff0c;Linux系統&#xff1a; iptables、firewalld、ufw&#xff1b; windows系統下&#xff1a; windows defender 硬件防火墻&#xff1a; 華為防火墻、思科防火墻、奇安信防火墻、深信服防…