OPENCV 에서 SIFT 형상을 추출하고 일치시키는 일반적인 프로세스는 다음과 같습니다.
그림 읽기-형상 체크 (위치, 각도, 도면층)-형상 설명 추출 (16*8 차원 형상 벡터)-일치-표시.
이 중 형상 추출은 주로 두 단계로 이루어집니다. 노란색 하위 섹션 상승 을 참조하십시오. 구체적으로 분석해 보겠습니다.
1. opencv 내장 라이브러리를 사용하여 두 장의 그림을 읽습니다.
2. 이름에서 알 수 있듯이 SiftFeatureDetector 의 객체를 생성합니다. SIFT 기능 검사기는 옷 그림에서 SIFT 점의 특징을 감지하고 KeyPoint 유형 벡터에 저장하는 데 사용됩니다. 여기서 keypoint 의 데이터 구조에 대해 이야기할 필요가 있는데, 관련된 내용이 많다. 자세한 분석 opencv 에서 keypoint 의 데이터 구조 분석을 살펴보세요. 당신이 말한 것은 매우 상세합니다. (table beats me ...) ... 요컨대, 가장 중요한 점은 다음과 같습니다.
키는 opencv 의 sift 라이브러리에서 감지한 형상 점에 대한 몇 가지 기본 정보만 유지하고 sift 에서 추출한 형상 벡터는 포함하지 않습니다. SiftDescriptorExtractor 는 고유 벡터를 추출하고 그 결과를 Mat 데이터 구조에 저장합니다. 이 데이터 구조는 실제로 이 특징점에 해당하는 피쳐 벡터를 유지합니다. 자세한 내용은 뒤에 나오는 SiftDescriptorExtractor 생성 객체에 대한 자세한 설명을 참조하십시오.
이것을 모르기 때문에 오전 내내 지체했다. 울어 죽겠다!
3, 이미지의 모든 키 고유 벡터 추출:
키 키 위치와 방향만 있고 형상 점의 고유 벡터는 없습니다. 피쳐 벡터를 추출하려면 SiftDescriptorExtractor 작업을 수행해야 합니다. SiftDescriptorExtractor 객체를 설정한 후 이전 SIFT 생성 형상 점을 통과하여 형상 점에 해당하는 128 차원 형상 벡터를 찾을 수 있습니다. 구체적인 방법은 opencv 에서 SIFTDescriptor 가 만든 SIFT 피쳐 벡터 추출의 간단한 분석을 참조할 수 있습니다. 이 단계 이후 모든 키의 피쳐 벡터는 MAT 데이터 구조에 피쳐로 저장됩니다.
4. 두 이미지의 고유 벡터를 일치시켜 일치하는 값을 얻습니다.
두 그림의 피쳐 벡터를 추출한 후 BruteForceMatcher 객체를 사용하여 두 그림의 설명자를 일치시키고 일치 결과를 일치시킬 수 있습니다. 구체적인 일치 방식은 당분간 꼼꼼히 연구하지 않고 나중에 보충할 것이다.
이제 sift 는 형상 점에서 탐지된 최종 일치를 완료했습니다. 일치하는 부분에 대해서는 잘 알지 못하지만 OPENCV 를 사용하여 SIFT 기능을 추출하는 방법에 대해서는 어느 정도 알고 있습니다. 다음으로, 우리는 다음 단계를 시작할 수 있습니다.
첨부: OPENCV 에서 SIFT 라이브러리를 사용하여 이미지를 일치시키는 루틴.
1
2
셋;삼;3
사
다섯;오;5
여섯;육
일곱
여덟;팔
아홉;구;9
10
1 1
12
13
14
15
16
17
18
19
20
2 1
22
23
24
25
26
27
28
29
30
3 1
32
33
34
35
36
37
38
39
40
4 1
마흔 두 개
43
마흔 네
45
46
47
48
사십구
50
5 1
52 개
53
54
55
56 세
57
58
59
60
6 1
62
63
64
65
66
67
육십팔
육십구
70
7 1
72 개
73
74
75
76
77
일흔여덟
// opencv_empty_proj.cpp: 콘솔 응용 프로그램의 진입점을 정의합니다.
//
# "stdafx.h" 포함
# include opencv.hpp & gt
# includefeatures2d/features2d.hpp >
# include nonfree/nonfree.hpp >
# include elegacy/legacy.hpp >
# 포함
네임스페이스 STD 사용
네임스페이스 cv 사용
Int _tmain(int argc, _TCHAR* argv[])
{
Const char * imagename = "img.jpg
//파일에서 이미지 읽기
Matimg = imread (imagename);
Matimg2 = imread ("img2.jpg");
//이미지를 읽지 못하면 ,
If(img.empty ())
{
Fprintf(stderr, "이미지% s 을 (를) 로드할 수 없습니다. \ n", imagename);
리턴-1;
}
If(img2.empty ())
{
Fprintf(stderr, "이미지% s 을 (를) 로드할 수 없습니다. \ n", imagename);
리턴-1;
}
//이미지 표시
Imshow (전면 이미지, img);
Imshow("image2 before ",img2);
//sift 피쳐 체크
SiftFeatureDetector
Vectorkp 1, kp2
Siftdtc.detect(img, KP1);
Matoutimg1;
DrawKeypoints(img, KP 1, outimg1);
Imshow("image 1 keypoints ",outimg1);
키 KP;
Vector:: 반복자 itvc
For (itvc = KP1.begin (); Itvc! = KP1.end (); Itvc++)
{
Cout & lt& lt "각도:"< 각도<< "\ t"< class _ id<< "\ t"< octave "
}
Siftdtc.detect(img2, kp2);
Mat outimg2
키 그리기 (img2, kp2, outimg2);
Imshow ("이미지 2 키", outimg2);
추출기
Mat descriptor 1, descriptor2
BruteForceMatcher & ltL2 & gt;; Matcher
벡터 일치
Mat img _ matches
Extractor.compute(img, KP 1, descriptor1);
Extractor.compute(img2, kp2, descriptor2);
Imshow("desc ",descriptor1);
Cout & lt< endl & lt< descriptor1< & ltendl
Matcher.match (설명자 1, 설명자 2, matches);
DrawMatches(img, KP 1, img2, kp2, Matches, img _ matches);
Imshow("matches ",img _ matches);
//이 함수는 키를 기다린 다음 키보드의 아무 키나 눌러 반환합니다.
Waitkey ();
0 을 반환합니다
}