無論是harris角點檢測,shi-tomasi角點檢測都無法對畫素點精準定位,進而無法滿足一些高精度影象角點處理,追蹤的問題。如跟蹤。相機矯正,三維重建,幾何測量等。正如圖所描述的。
因此,亞畫素級別角點檢測應運而生。
亞畫素
面陣攝像機的成像面以畫素為最小單位。例如某cmos攝像晶元,其畫素間距為5.2微公尺。攝像機拍攝時,將物理世界中連續的影象進行了離散化處理。到成像面上每乙個畫素點只代表其附近的顏色。至於「附近」到什麼程度?就很困難解釋。兩個畫素之間有5.2微公尺的距離,在巨集觀上我們可以看作是連在一起的。但是在微觀上,它們之間還有無限的更小的東西存在。這個更小的東西我們稱它為「亞畫素」。實際上「亞畫素」應該是存在的,只是硬體上沒有個細微的感測器把它檢測出來。於是軟體上把它近似地計算出來。
亞畫素的精度
亞畫素精度是指相鄰兩畫素之間細分情況。輸入值通常為二分之一,三分之一或四分之一。這意味著每個畫素將被分為更小的單元從而對這些更小的單元實施插值演算法。例如,如果選擇四分之一,就相當於每個畫素在橫向和縱向上都被當作四個畫素來計算。因此,如果一張5x5畫素的影象選擇了四分之一的亞畫素精度之後,就等於建立了一張20x20的離散點陣,進而對該點陣進行插值。
亞畫素定位
我們已經知道,除了利用 harris進行角點檢測 和利用 shi-tomasi方法進行角點檢測 外, 還可以使用cornereigenvalsandvecs()函式和cornermineigenval()函式自定義角點檢測函式。 但是對角點的精度有更高的要求,則要用cornersubpix()函式將角點定位到子畫素,從而取得亞畫素級別的角點檢測效果。
函式goodfeaturestotrack()函式只能提供簡單的畫素的座標值,也就是說,有時候會需要實數座標值而不是整數座標值。在opencv中,就提供了乙個cornersubpix()函式,用於尋找亞畫素角點的位置,其函式宣告如下:
void cornersubpix(
inputarray image, // 輸入影象,即源影象;
inputoutputarray corners, // 提供輸入角點的初始座標和精確的輸出座標
size winsize, // size型別,表示搜尋視窗的半徑。若winsize=size(5,5),那麼就表示使用(5*2+1)x(5*2+1)=11*11大小的搜尋視窗。
size zerozone, // size型別,表示死區的一半尺寸。而死區為不對搜尋區的**位置做求和運算的區域,用來避免自相關矩陣出現的某些可能的奇異性。值為(-1,-1)表示沒有死區。
termcriteria criteria // termcriteria型別,求角點的迭代過程的終止條件。
);
這裡重點記錄一下corners這個引數,必須是包含了角點檢測後角點響應的初始座標,如用****omasi角點檢測後輸出的corners,或是經過儲存所有大於閾值thresh的harris角點檢測輸出值後的resultimage
看其他部落格,記錄的乙個api,用於尋找亞畫素角點的座標。
void cvfindcornersubpix(
const cvarr* image,
cvpoint2d32f* corners,
int count,
cvsize win,
cvsize zero_zone,
cvtermcriteria criteria
);
// opencv 檔案.cpp :
#include "pch.h"
#include#include#include using namespace cv;
using namespace std;
mat result;//儲存響應的r
int blocksize = 3;//矩陣m的大小
double k = 0.04;//響應係數
int ksize = 3;//視窗
double qualitylevel = 0.01;
int maxcorners = 20;
int max_count = 50;
double mindistance = 10;
int sm_qualitylevel=30;
void corner****_tomasi_demo(int, void*);
mat gray;
mat src1;
char output_****omasi_win = "corner_****omasi_demo";
int main()
namedwindow(output_****omasi_win, window_autosize);
imshow("src1", src1);
cvtcolor(src1, gray, color_bgr2gray);
createtrackbar("max_corners:", output_****omasi_win, &maxcorners, max_count, corner****_tomasi_demo);
corner****_tomasi_demo(0, 0);
waitkey(0);
return 0;
}//****omasi
void corner****_tomasi_demo(int, void*)
vector****omasi_corner1;
goodfeaturestotrack(gray, ****omasi_corner1, maxcorners, qualitylevel, mindistance, mat(), blocksize, false, k);
mat resultimage = src1.clone();
cout << "the corners' size = " << ****omasi_corner1.size() << endl;
for (size_t t= 0; t < ****omasi_corner1.size(); t++)
vector****omasi_corner2 = ****omasi_corner1;
//開始做亞畫素角點檢測
size winsize = size(5, 5);
size zerozone = size(-1,-1);
termcriteria tc = termcriteria(termcriteria::eps + termcriteria::max_iter, 40, 0.0001);
cornersubpix(gray, ****omasi_corner1, winsize, zerozone, tc);
//cout << "the number of the cornersubpixel is \n";
for (size_t t = 0; t < ****omasi_corner1.size(); t++) {
cout << "第"<
我們可以看到,用shi-tomasi角點檢測得到的基本是整數,而用亞畫素級別檢測,精度顯然提高,經過我的測試,最多支援4位小數,精度設定再小,至多也是4位小數。
Opencv特徵提取與目標檢測03
基於harris角點檢測理論與 omasi檢點檢測理論,我們可以通過獲取矩陣m的兩個特徵值以及qualitylevel的值,動態設計計算閾值t的公式,來選擇我們需要的有效角點。第乙個api 基於harris角點檢測理論的,輸出的影象dst必須定義為cv 32fc1等型別,且 矩陣的每個特徵值由下式求...
Opencv特徵提取
最近復現 講第 講關於 的 特徵提取的原理懂了,opencv裡的實現方式,特別是如何構造特徵點提取函式 描述子函式和暴力匹配等方法的函式不熟悉,因此翻到了 opencv程式設計入門 第三版了解了解,對整個流程有了個概念。我發現我的opencv版本不能構建fast的描述子,sift更是沒有了,sift...
opencv 特徵提取以及特徵匹配
用到的庫檔案 include include using namespace std opencv 特徵檢測模組 include include include 提取影象中的特徵 關鍵點 與 關鍵點的描述子,分別用到了opencv庫中的cv featuredetector和cv descriptor...