J'essaie de faire un transformation des perspectives d'un ensemble de points afin d'obtenir une désensorceler effet :
http://nuigroup.com/?ACT=28&fid=27&aid=1892_H6eNAaign4Mrnn30Au8d
J'utilise l'image ci-dessous pour les tests, et la fonction vert rectangle affichant la zone d'intérêt.
Je me demandais s'il est possible d'obtenir l'effet que j'espère en utilisant une simple combinaison de cv::getPerspectiveTransform
et cv::warpPerspective
. Je partage le code source que j'ai écrit jusqu'à présent, mais cela ne fonctionne pas. Voici l'image qui en résulte :
Il y a donc un vector<cv::Point>
que définit la région d'intérêt mais les points sont ne sont pas stockés dans un ordre particulier à l'intérieur du vecteur, et c'est quelque chose que je ne peux pas changer dans la procédure de détection. Quoi qu'il en soit, plus tard les points de ce vecteur sont utilisés pour définir un RotatedRect
qui, à son tour, est utilisé pour assembler cv::Point2f src_vertices[4];
l'une des variables requises par cv::getPerspectiveTransform()
.
Ma compréhension de sommets et comment ils sont organisés pourrait être l'un des problèmes . Je pense également que l'utilisation d'un RotatedRect
n'est pas la meilleure idée pour stocker les points d'origine du ROI, puisque l'option les coordonnées vont changer un peu pour s'adapter au rectangle pivoté, et ce n'est pas très cool .
#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
cv::Mat src = cv::imread(argv[1], 1);
// After some magical procedure, these are points detect that represent
// the corners of the paper in the picture:
// [408, 69] [72, 2186] [1584, 2426] [1912, 291]
vector<Point> not_a_rect_shape;
not_a_rect_shape.push_back(Point(408, 69));
not_a_rect_shape.push_back(Point(72, 2186));
not_a_rect_shape.push_back(Point(1584, 2426));
not_a_rect_shape.push_back(Point(1912, 291));
// For debugging purposes, draw green lines connecting those points
// and save it on disk
const Point* point = ¬_a_rect_shape[0];
int n = (int)not_a_rect_shape.size();
Mat draw = src.clone();
polylines(draw, &point, &n, 1, true, Scalar(0, 255, 0), 3, CV_AA);
imwrite("draw.jpg", draw);
// Assemble a rotated rectangle out of that info
RotatedRect box = minAreaRect(cv::Mat(not_a_rect_shape));
std::cout << "Rotated box set to (" << box.boundingRect().x << "," << box.boundingRect().y << ") " << box.size.width << "x" << box.size.height << std::endl;
// Does the order of the points matter? I assume they do NOT.
// But if it does, is there an easy way to identify and order
// them as topLeft, topRight, bottomRight, bottomLeft?
cv::Point2f src_vertices[4];
src_vertices[0] = not_a_rect_shape[0];
src_vertices[1] = not_a_rect_shape[1];
src_vertices[2] = not_a_rect_shape[2];
src_vertices[3] = not_a_rect_shape[3];
Point2f dst_vertices[4];
dst_vertices[0] = Point(0, 0);
dst_vertices[1] = Point(0, box.boundingRect().width-1);
dst_vertices[2] = Point(0, box.boundingRect().height-1);
dst_vertices[3] = Point(box.boundingRect().width-1, box.boundingRect().height-1);
Mat warpMatrix = getPerspectiveTransform(src_vertices, dst_vertices);
cv::Mat rotated;
warpPerspective(src, rotated, warpMatrix, rotated.size(), INTER_LINEAR, BORDER_CONSTANT);
imwrite("rotated.jpg", rotated);
return 0;
}
Quelqu'un peut-il m'aider à résoudre ce problème ?