Skip to content

Commit f3e3436

Browse files
committedFeb 5, 2017
Fotomontaje con OpenCV
Uso de la función cv::seamlessClone para crear un fotomontaje.
1 parent 90967c8 commit f3e3436

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed
 

‎opencv-fotomontaje/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cmake_minimum_required(VERSION 3.4)
2+
3+
project( Tutorial_OpenCV )
4+
5+
find_package( OpenCV 3.0.0 REQUIRED )
6+
7+
file(COPY face.jpg DESTINATION images)
8+
9+
add_executable( ${PROJECT_NAME} source.cpp )
10+
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} )

‎opencv-fotomontaje/face.jpg

153 KB
Loading

‎opencv-fotomontaje/fotomontaje.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <opencv2/photo.hpp>
2+
#include <opencv2/highgui.hpp>
3+
#include <iostream>
4+
5+
using namespace cv;
6+
using namespace std;
7+
8+
int main(int, char** argv)
9+
{
10+
// Load and show images...
11+
Mat source = imread("source1.png", IMREAD_COLOR);
12+
Mat destination = imread("destination1.png", IMREAD_COLOR);
13+
Mat mask = imread("mask.png", IMREAD_COLOR);
14+
15+
imshow("source", source);
16+
imshow("mask", mask);
17+
imshow("destination", destination);
18+
19+
Mat result;
20+
21+
Point p; // p will be near top right corner
22+
p.x = (float)2*destination.size().width/3;
23+
p.y = (float)destination.size().height/4;
24+
25+
seamlessClone(source, destination, mask, p, result, NORMAL_CLONE);
26+
27+
imshow("result", result);
28+
cout << "\nDone. Press any key to exit...\n";
29+
30+
waitKey(); // Wait for key press
31+
return 0;
32+
}

‎opencv-fotomontaje/source.cpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include <opencv2\opencv.hpp>
2+
#include <iostream>
3+
#include <vector>
4+
5+
using namespace cv;
6+
using namespace std;
7+
8+
int main(int argc, char** argv)
9+
{
10+
try {
11+
String face_xml = R"(c:\developer\opencv-3.2.0\etc\haarcascades\haarcascade_frontalface_default.xml)";
12+
String eyel_xml = R"(c:\developer\opencv-3.2.0\etc\haarcascades\haarcascade_eye.xml)";
13+
14+
CascadeClassifier face_detector, eye_detector;
15+
16+
// cargar los clasificadores en cascada
17+
if (!eye_detector.load(eyel_xml) || !face_detector.load(face_xml)) {
18+
cout << "Error: no se ecuentra el cascade .xml" << endl;
19+
}
20+
21+
Mat frame, gray_frame;
22+
23+
// leer la imagen de entrada
24+
frame = imread("images/face.jpg");
25+
26+
if (frame.empty()) {
27+
cout << "Error: no se puede abrir la imagen de entrada." << endl;
28+
}
29+
30+
cvtColor(frame, gray_frame, COLOR_BGR2GRAY);
31+
equalizeHist(gray_frame, gray_frame);
32+
33+
// detectar rostro, almacenar la region en faces
34+
std::vector<cv::Rect> faces;
35+
face_detector.detectMultiScale(gray_frame, faces);
36+
37+
double EYE_SX = 0.12;
38+
double EYE_SY = 0.17;
39+
double EYE_SW = 0.42;
40+
double EYE_SH = 0.36;
41+
42+
// procesar los rostros encontrados
43+
for (auto& region : faces) {
44+
45+
// crear un cv::Mat que contine el rostro
46+
Mat face = frame(region);
47+
48+
int leftX = cvRound(face.cols * EYE_SX);
49+
int topY = cvRound(face.rows * EYE_SY);
50+
int widthX = cvRound(face.cols * EYE_SW);
51+
int heightY = cvRound(face.rows * EYE_SH);
52+
int rightX = cvRound(face.cols * (1.0 - EYE_SX - EYE_SW));
53+
54+
// crear cv::Mat que contiene la region aproximada de los ojos
55+
Mat topLeftOfFace = face(Rect(leftX, topY, widthX, heightY));
56+
Mat topRightOfFace = face(Rect(rightX, topY, widthX, heightY));
57+
58+
std::vector<cv::Rect> left_eye, right_eye;
59+
60+
// detectar los ojos, izquierdo y derecho, respectivamente
61+
eye_detector.detectMultiScale(topLeftOfFace, left_eye);
62+
//eye_detector.detectMultiScale(topRightOfFace, right_eye);
63+
64+
// clonar el ojo izquierdo
65+
if (!left_eye.empty())
66+
{
67+
// crear el cv::Mat que contiene el ojo izquierdo
68+
Mat eye = topLeftOfFace(left_eye[0]);
69+
70+
// crear el cv::Mat para la mascara
71+
Mat mask(eye.rows, eye.cols, CV_8U, Scalar::all(0));
72+
73+
Point pos_ellipse(mask.size() / 2);
74+
Point pos_clone(face.size().width / 2, face.size().height / 5);
75+
76+
Size size(mask.size().width / 2, (mask.size().height / 2) - 15);
77+
78+
// crear la mascara y aplicar seamless cloning
79+
cv::ellipse(mask, pos_ellipse, size , 0, 0, 360, Scalar::all(255), CV_FILLED, LINE_AA);
80+
cv::seamlessClone(eye, face, mask, pos_clone, face, NORMAL_CLONE);
81+
82+
imshow("mask", mask);
83+
imshow("src", eye);
84+
}
85+
86+
imshow("dst", face);
87+
88+
//// clonar el ojo derecho
89+
//if (!right_eye.empty())
90+
//{
91+
// Mat eye = topRightOfFace(right_eye[0]);
92+
// Mat mask(eye.rows, eye.cols, CV_8U, Scalar::all(0));
93+
//
94+
// cv::ellipse(mask, Point(mask.size() / 2), Size(mask.size().width / 2, (mask.size().height / 2) - 2), 0, 0, 360, Scalar::all(255), CV_FILLED, LINE_AA);
95+
// cv::seamlessClone(eye, face, mask, Point(face.size().width / 2, face.size().height / 5), face, MIXED_CLONE);
96+
//}
97+
}
98+
99+
imshow("Fotomontajes", frame);
100+
101+
waitKey(0);
102+
}
103+
catch (Exception ex) {
104+
cout << "Exception: " << ex.what() << endl;
105+
}
106+
107+
return 0;
108+
}
109+
110+
111+
112+
113+
114+

0 commit comments

Comments
 (0)