1. 코너의 특징
1) 코너의 정의 및 특징
- 두 에지의 교차점. 서로 다른 방향의 에지가 공존하는 점
- 평탄한 영역(flat)과 에지(edge) 영역은 고유한 위치 찾기 어려움
- 코너는 변별력이 높은 편이며, 영상의 이동 및 회전 변환에 강인함.
위치를 알 수 있는 부분들이 코너이다.
2. 해리스 코너 검출 방법
1) 해리스 코너 검출방법
- 영상 내 정의된 윈도우 안의 픽셀 값이 상하좌우 방향으로 모두 급격하게 변하는 위치를 코너로 규정하고 이를 효과적으로 구하는 방법 제시.
void cornerHarries(InputArray src, OutputArray dst, int blockSize,
int ksize, double k, int borderType = BORDER_DEFAULT);
src: (입력) 단일채널, 8비트 또는 실수형 영상
dst: (출력) 해리스 코너 응답계수 값 행렬. 입력영상 src와 같은 크기. CV_32FC1
| dst(x,y) < 0 | 에지픽셀 |
| |dst(x,y)| is small | 평탄한 영역 |
| dst(x, y) >> 0 | 코너. local maximum 선택 // dst값이 충분히 0보다 커야 코너로 검출함. |
blockSize: 내부 연산에서 사용되는 이웃 픽셀 크기. 주변 blockSize x blockSize 이웃 픽셀을 이용 // 2 또는 3 또는 5..
ksize : (미분을 위한) 소벨 연산자 커널 크기. // 대부분 3 을 지정하는걸 권장.
k: 해리스 코너 검출 상수 (보통 0.04)
borderType: 가장자리 픽셀 확장 방식
3. 추적하기 좋은 특징 (Good features to track)
-해리스코너 검출법 향상시킨 코너검출방법
-코너 품질 함수 값이 큰 순서대로 정렬하여 코너 점 반환
-비 최대 억제 수행
void goodFeaturesToTrack(InputArray image, OutputArray corners, int maxCorners,
double qualityLevel, double minDistance, InputArray mask = noArray(),
int blockSize = 3, bool useHarrisDetector = false, double k = 0.04);
image: (입력) 8비트 또는 32비트 실수, 단일 채널 영상.
corners: (출력) 검출된 코너점 좌표. vector<Point2f> // 코너점 몇개 추출될지 모르기에 벡터 자료형으로.
maxCorners: 최대 코너 갯수, maxCorners <= 0 이면 무제한 검출.
qualityLevel: 코너점 결정을 위한 값, 보통 0.01 ~ 0.1 사이의 값을 지정하며, 이 값이 커질 수 록 더욱 엄격하게 코너를 검출함.
minDistance : 코너점 사이의 최소거리
mask: 마스크 영상
blockSize: 내부 연산에서 사용되는 이웃 픽셀 크기. 주변 blockSize x blockSize 이웃 픽셀을 이용.
//알고리즘 내부에 사용할 blocksize 지정. 해리스코너는 blockSize 기본값없었지만 해당 함수는 기본값 3으로 결정됨
useHarrisDetector: 해리스 코너 응답 함수 사용여부
k: 해리스 코너 응답 함수 사용 시 사용되는 파라미터
4. FAST 코너 검출 방법.
- 아주 빠르게 코너를 검출하는 알고리즘으로, 각각의 픽셀에 대해 주변 16개 픽셀 값 크기를 분석하여 해당 픽셀(p) 보다 충분히 밝거나(>p+t) 또는 충분히 어두운(<p-t) 픽셀이 n개 이상 연속으로 나타나면 코너로 인식(n은 보통 9)
- 비최대 억제 수행
- 해리스 , GFTT 방법보다 매우 빠르게 동작 (약 30배 더 빠름)
https://www.edwardrosten.com/work/fast.html
FAST Corner Detection -- Edward Rosten
[ Home : Programs | libCVD | Hardware hacks | Publications | Teaching | TooN | Research ] FAST Corner Detection -- Edward Rosten Try FAST Today! If you use FAST in published academic work then please cite both of the following papers: Fusing points and lin
www.edwardrosten.com
void FAST(InputArray image, std::vector<KeyPoint>& keypoints,
int threshold, bool nonmaxSuppression = true);
image : (입력) 그레이스케일 영상
keypoints: (출력) 검출된 키포인트. KeyPoint 클래스의 pt 멤버를 이용하여 코너 좌표에 접근 가능.
thereshold : 중심 픽셀값과 주변 픽셀 값과의 차이 임계값 // > p + t , < p-t *t is big than 0
nonmaxSuppression: 비최대 억제 수행 여부
GFTT & FAST 코너 검출 예제
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("building.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image laod failed!" << endl;
return -1;
}
//goodFeaturesToTrack
TickMeter tm1;
tm1.start();
vector<Point2f> corners;
goodFeaturesToTrack(src, corners, 400, 0.01, 10); // 코너 검출 갯수가 너무 많을시 quality level 조절 가능 eg. 0.05
tm1.stop();
cout << "goodFeaturesToTrack() took " << tm1.getAvgTimeMilli() << "ms." << endl;
Mat dst1;
cvtColor(src, dst1, COLOR_GRAY2BGR);
for (size_t i = 0; i < corners.size(); ++i) { // 코너점위치에 원 그림. 2픽셀 두께. 원 반지름 5
circle(dst1, corners[i], 5, Scalar(0, 0, 255), 2);
}
//FAST
TickMeter tm2;
tm2.start();
vector<KeyPoint> keypoints;
FAST(src, keypoints, 60, true);
// Ptr<FeatureDetector> detector = FastFeatureDetector::create(60);
// detector->detect(src, keypoints);
tm2.stop();
cout << "FAST() took " << tm2.getTimeMilli() << "ms." << endl;
Mat dst2;
cvtColor(src, dst2, COLOR_GRAY2BGR);
for (const KeyPoint &kp : keypoints) {
circle(dst2, Point(kp.pt.x, kp.pt.y), 5, Scalar(0, 0, 255), 2, LINE_AA);
}
resize(dst1, dst1, Size(600, 600));
resize(dst2, dst2, Size(600, 600));
imshow("dst1", dst1);
imshow("dst2", dst2);
waitKey();
}

dst1 goodFeaturesToTrack
dst2 FAST (잡음에 민감)
그러나 둘 모두 코너 검출 가능하며, 특히 FAST의 경우 연산속도가 월등히 빠르다., 이에 코너 검출 시 FAST 로 하는게 유리함
'프로그래머스 > OPENCV' 카테고리의 다른 글
| 지역이진화 (0) | 2022.12.08 |
|---|---|
| 컬러영상 처리 기초 (이진화 게시글과 swap됨 ) (0) | 2022.12.08 |
| 허프변환 알고리즘 (0) | 2022.12.08 |
| 캐니 에지 검출기 (0) | 2022.12.07 |
| 에지검출과 소벨필터(2) (0) | 2022.12.07 |