緒:
最常用的角點檢測方式是Harris角點檢測,
OpenCV供給了Harris角點檢測的接口cornerHarris(),但Harris檢測的角點是像素級的,且檢測速度較慢;
這里介紹OpenCV另一個功能更為壯大角點檢測函數goodFeaturesToTrack(),
不僅撐持Harris角點檢測,也撐持Shi Tomasi算法的角點檢測。
但該函數檢測的角點依然是像素級此外。
若想獲取更為邃密的角點坐標,
則需要與cornerSubPix()函數共同利用,獲得亞像素角點。
goodFeaturesToTrack格局:
void goodFeaturesToTrack(
InputArray image, //輸入圖像
OutputArray corners, //輸出角點vector
int maxCorners, //最年夜角點數量
double qualityLevel, // 質量程度系數
double minDistance, // 最小距離,小于此距離的點忽略
InputArray mask = noArray(), // mask=0的點忽略
int blockSize = 3, //鄰域數
bool useHarrisDetector = false, // false =Shi Tomasi metric
double k = 0.04 //Harris角點檢測時利用
);
參數:
第一個參數是輸入圖像(8位或32位單通道圖);
第二個參數是檢測的所有角點,類型為vector或數組,由給心猿意馬的參數類型而心猿意馬。若是是vector,那么它應該是一個包含cv::Point2f的vector對象;若是類型是cv::Mat,那么它的每一行對應一個角點,點的x、y位置別離是兩列;
第三個參數用于限制檢測到的點數的最年夜值;
第四個參數暗示檢測到的角點的質量程度(凡是是0.10到0.01之間的數值,不克不及年夜于1.0);
第五個參數用于區分相鄰兩個角點的最小距離(小于這個距離得點將進行歸并);
第六個參數是mask,若是指心猿意馬,它的維度必需和輸入圖像一致,且在mask值為0處不進行角點檢測。
第七個參數是blockSize,暗示在計較角點時介入運算的區域巨細,常用值為3,可是若是圖像的分辯率較高則可以考慮利用較年夜一點的值;
第八個參數用于指心猿意馬角點檢測的方式,若是是true則利用Harris角點檢測,false則利用Shi Tomasi算法;
第九個參數是在利用Harris算法時利用,最好利用默認值0.04;
goodFeaturesToTrack應用
法式:
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\core\core.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat image_color = imread("Lighthouse.jpg", 1);
Mat image_gray;
cvtColor(image_color, image_gray, COLOR_BGR2GRAY);
//設置角點檢測參數
vector<Point2f> corners;
int max_corners = 500;
double quality_level = 0.01;
double min_distance = 3.0;
int block_size = 3;
bool use_harris = false;
double k = 0.04;
goodFeaturesToTrack(image_gray,
corners,
max_corners,
quality_level,
min_distance,
Mat(),
block_size,
use_harris,
k);
//將檢測到的角點繪制到原圖上
for (int i = 0; i < corners.size(); i++)
{
circle(image_color, corners[i], 1, Scalar(0, 0, 255), 2, 8, 0);
}
namedWindow("house corner",CV_WINDOW_NORMAL);
imshow("house corner", image_color);
waitKey(0);
return 0;
}
cornerSubPix()格局
goodFeaturesToTrack()提取的角點只能達到像素級別,在良多環境下并不克不及知足現實的需求,這時就需要cornerSubPix()對檢測的角點作進一步的優化計較,
使角點的精度達到亞像素級別。
void cornerSubPix(
InputArray image, // 輸入圖像
InputOutputArray corners, // 角點
Size winSize, // 區域巨細為 N*N; N=(winSize*2+1)
Size zeroZone, // 近似于winSize,Size(-1,-1)暗示忽略
TermCriteria criteria // 遏制優化的尺度
);
第一個參數是輸入圖像和goodFeaturesToTrack()中的輸入圖像是統一個圖像。
第二個參數是檢測到的角點,便是輸入也是輸出。
第三個參數是計較亞像素角點時考慮的區域巨細,巨細為N*N; N=(winSize*2+1)。
第四個參數感化近似于winSize,可是老是具有較小的規模,凡是忽略(即Size(-1, -1))。
第五個參數暗示計較亞像素時遏制迭代的尺度,可選的值有TermCriteria::MAX_ITER 、TermCriteria::EPS,前者暗示迭代次數達到了最年夜次數時遏制,后者暗示角點位置轉變的最小值已經達到最小時遏制迭代。二者均利用cv::TermCriteria()機關函數進行指心猿意馬。
goodFeaturesToTrack連系cornerSubPix的應用
法式:
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\core\core.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat image_color = imread("Lighthouse.jpg", 1);
Mat image_gray;
cvtColor(image_color, image_gray, COLOR_BGR2GRAY);
//設置角點檢測參數
vector<Point2f> corners;
int max_corners = 500;
double quality_level = 0.01;
double min_distance = 3.0;
int block_size = 3;
bool use_harris = false;
double k = 0.04;
goodFeaturesToTrack(image_gray,
corners,
max_corners,
quality_level,
min_distance,
Mat(),
block_size,
use_harris,
k);
//將檢測到的角點繪制到原圖上
for (int i = 0; i < corners.size(); i++)
{
circle(image_color, corners[i], 1, Scalar(0, 0, 255), 2, 8, 0);
}
namedWindow("goodTrack corner",CV_WINDOW_NORMAL);
imshow("goodTrack corner", image_color);
//指心猿意馬亞像素計較迭代標注
TermCriteria criteria = TermCriteria(
TermCriteria::MAX_ITER + TermCriteria::EPS,
40,
0.01);
//亞像素檢測
cornerSubPix(image_gray, corners, Size(5, 5), Size(-1, -1), criteria);
//將檢測到的亞像素角點繪制到原圖上
for (int i = 0; i < corners.size(); i++)
{
circle(image_color, corners[i], 5, cv::Scalar(0, 255, 0), 2, 8, 0);
}
namedWindow("sub pixel corner",CV_WINDOW_NORMAL);
imshow("sub pixel corner", image_color);
waitKey(0);
return 0;
}
像素角點與亞像素角點對比:
如圖所示:
0 篇文章
如果覺得我的文章對您有用,請隨意打賞。你的支持將鼓勵我繼續創作!