Skip to content

Commit 1c2981c

Browse files
committed
Detectar objeto plano
Detección de un objeto plano conocido usando el pareo de puntos clave y matriz de homografía.
1 parent f2978bc commit 1c2981c

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

opencv-planar_tracking/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cmake_minimum_required(VERSION 3.4)
2+
3+
project( Tutorial_Detect_Planar_Object )
4+
5+
find_package( OpenCV 3.0.0 REQUIRED )
6+
7+
file(COPY box.png DESTINATION image)
8+
file(COPY box_in_scene.png DESTINATION image)
9+
10+
add_executable( ${PROJECT_NAME} main.cpp)
11+
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} )

opencv-planar_tracking/box.png

49.5 KB
Loading
120 KB
Loading

opencv-planar_tracking/main.cpp

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include <opencv2\highgui.hpp>
2+
#include <opencv2\features2d.hpp>
3+
#include <opencv2\imgproc.hpp>
4+
#include <opencv2\calib3d.hpp>
5+
6+
#include <vector>
7+
8+
using namespace cv;
9+
using namespace std;
10+
11+
void main() {
12+
13+
Ptr<Feature2D> detector = BRISK::create();
14+
Ptr<DescriptorMatcher> matcher = BFMatcher::create(NORM_HAMMING, true);
15+
16+
// cargar la imagen de referencia, aquel objeto plano que deseamos localizar.
17+
Mat img_object = imread("image/box.png", IMREAD_GRAYSCALE);
18+
Mat desc_object;
19+
20+
// cargar la imagen de la escena en donde buscaremos el objeto plano.
21+
Mat img_scene = imread("image/box_in_scene.png", IMREAD_GRAYSCALE);
22+
Mat desc_scene;
23+
24+
// detectar y extraer los puntos de interes y sus respectivos descriptores.
25+
vector<KeyPoint> kp_object;
26+
detector->detectAndCompute(img_object, noArray(), kp_object, desc_object);
27+
28+
// detectar y extraer los puntos de interes y sus respectivos descriptores.
29+
vector<KeyPoint> kp_scene;
30+
detector->detectAndCompute(img_scene, noArray(), kp_scene, desc_scene);
31+
32+
// hacer el pareo de los key points.
33+
vector<DMatch> matches;
34+
matcher->match(desc_object, desc_scene, matches);
35+
36+
// filtrar los mejores key points.
37+
sort(matches.begin(), matches.end());
38+
matches.erase(matches.begin() + 30, matches.end());
39+
40+
vector<Point2f> pts_object, pts_scene;
41+
vector<DMatch> good_match;
42+
43+
// guardar los puntos correspondientes a cada uno de los key points.
44+
for (auto& m : matches)
45+
{
46+
pts_object.push_back(kp_object[m.queryIdx].pt);
47+
pts_scene.push_back(kp_scene[m.trainIdx].pt);
48+
49+
good_match.push_back(m);
50+
}
51+
52+
Mat dst;
53+
54+
// dibujar el pareo
55+
drawMatches(
56+
img_object, kp_object,
57+
img_scene, kp_scene,
58+
good_match, dst, Scalar::all(-1), Scalar::all(-1),
59+
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
60+
61+
// buscar la matriz de homografia que representa la tranformación entre los puntos del objeto y la escena.
62+
Mat H = findHomography(pts_object, pts_scene, CV_RANSAC);
63+
if (!H.empty()) {
64+
65+
// obtener las coordenadas de la imagen de referencia, corresponde a las 4 esquinas de la imagen.
66+
std::vector<Point2f> obj_corners(4);
67+
obj_corners[0] = Point2f(0, 0);
68+
obj_corners[1] = Point2f((float)img_object.cols, 0);
69+
obj_corners[2] = Point2f((float)img_object.cols, (float)img_object.rows);
70+
obj_corners[3] = Point2f(0, (float)img_object.rows);
71+
72+
// aplicar la tranformación a las corredenadas previas para obtener la posición de cada punto en la escena.
73+
std::vector<Point2f> scene_corners(4);
74+
perspectiveTransform(obj_corners, scene_corners, H);
75+
76+
Mat img_scene_dst;
77+
cvtColor(img_scene, img_scene_dst, CV_GRAY2BGR);
78+
79+
// Dibujamos las coordenadas del objeto plano en la escena.
80+
line(img_scene_dst, scene_corners[0], scene_corners[1], Scalar(0, 255, 0), 3, LINE_AA);
81+
line(img_scene_dst, scene_corners[1], scene_corners[2], Scalar(0, 255, 0), 3, LINE_AA);
82+
line(img_scene_dst, scene_corners[2], scene_corners[3], Scalar(0, 255, 0), 3, LINE_AA);
83+
line(img_scene_dst, scene_corners[3], scene_corners[0], Scalar(0, 255, 0), 3, LINE_AA);
84+
85+
imshow("Detected Object", img_scene_dst);
86+
87+
/**/
88+
line(dst, scene_corners[0] + Point2f((float)img_object.cols, 0), scene_corners[1] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 1);
89+
line(dst, scene_corners[1] + Point2f((float)img_object.cols, 0), scene_corners[2] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 1);
90+
line(dst, scene_corners[2] + Point2f((float)img_object.cols, 0), scene_corners[3] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 1);
91+
line(dst, scene_corners[3] + Point2f((float)img_object.cols, 0), scene_corners[0] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 1);
92+
/**/
93+
}
94+
95+
imshow("Planar Object Detect", dst);
96+
waitKey();
97+
}

0 commit comments

Comments
 (0)