J'essaie d'implémenter la correction automatique de perspective dans mon programme iOS et lorsque j'utilise l'image de test que j'ai trouvée sur le tutoriel, tout fonctionne comme prévu. Mais quand je prends une photo, je retrouve un résultat étrange.
J'utilise le code trouvé dans ce tutoriel
Quand je lui donne une image qui ressemble à ceci:
J'obtiens ceci comme résultat:
Voici ce que dst
me donne qui pourrait aider.
J'utilise ceci pour appeler la méthode qui contient le code.
quadSegmentation(Img, bw, dst, quad);
Quelqu'un peut-il me dire quand je reçois autant de lignes vertes par rapport au tutoriel? Et comment pourrais-je résoudre ce problème et recadrer correctement l'image pour ne contenir que la carte?
Pour transformer la perspective dont vous avez besoin,
points source-> Coordonnées des sommets quadrangulaires dans l'image source.
points de destination-> Coordonnées des sommets quadrangulaires correspondants dans l'image de destination.
Ici, nous allons calculer ces points par processus de contour.
Calculer les coordonnées des sommets quadrangulaires dans l'image source
epsilon
pour faire 4 coordonnées.Calculer les coordonnées des sommets quadrangulaires correspondants dans l'image de destination
Dans l'image ci-dessous, le rectangle rouge représente les points source et le vert pour les points de destination.
Ajustez l'ordre des coordonnées et appliquez la transformation Perspective
Voir le résultat final
Code
Mat src=imread("card.jpg");
Mat thr;
cvtColor(src,thr,CV_BGR2GRAY);
threshold( thr, thr, 70, 255,CV_THRESH_BINARY );
vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
int largest_contour_index=0;
int largest_area=0;
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image
findContours( thr.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
for( int i = 0; i< contours.size(); i++ ){
double a=contourArea( contours[i],false); // Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i; //Store the index of largest contour
}
}
drawContours( dst,contours, largest_contour_index, Scalar(255,255,255),CV_FILLED, 8, hierarchy );
vector<vector<Point> > contours_poly(1);
approxPolyDP( Mat(contours[largest_contour_index]), contours_poly[0],5, true );
Rect boundRect=boundingRect(contours[largest_contour_index]);
if(contours_poly[0].size()==4){
std::vector<Point2f> quad_pts;
std::vector<Point2f> squre_pts;
quad_pts.Push_back(Point2f(contours_poly[0][0].x,contours_poly[0][0].y));
quad_pts.Push_back(Point2f(contours_poly[0][1].x,contours_poly[0][1].y));
quad_pts.Push_back(Point2f(contours_poly[0][3].x,contours_poly[0][3].y));
quad_pts.Push_back(Point2f(contours_poly[0][2].x,contours_poly[0][2].y));
squre_pts.Push_back(Point2f(boundRect.x,boundRect.y));
squre_pts.Push_back(Point2f(boundRect.x,boundRect.y+boundRect.height));
squre_pts.Push_back(Point2f(boundRect.x+boundRect.width,boundRect.y));
squre_pts.Push_back(Point2f(boundRect.x+boundRect.width,boundRect.y+boundRect.height));
Mat transmtx = getPerspectiveTransform(quad_pts,squre_pts);
Mat transformed = Mat::zeros(src.rows, src.cols, CV_8UC3);
warpPerspective(src, transformed, transmtx, src.size());
Point P1=contours_poly[0][0];
Point P2=contours_poly[0][1];
Point P3=contours_poly[0][2];
Point P4=contours_poly[0][3];
line(src,P1,P2, Scalar(0,0,255),1,CV_AA,0);
line(src,P2,P3, Scalar(0,0,255),1,CV_AA,0);
line(src,P3,P4, Scalar(0,0,255),1,CV_AA,0);
line(src,P4,P1, Scalar(0,0,255),1,CV_AA,0);
rectangle(src,boundRect,Scalar(0,255,0),1,8,0);
rectangle(transformed,boundRect,Scalar(0,255,0),1,8,0);
imshow("quadrilateral", transformed);
imshow("thr",thr);
imshow("dst",dst);
imshow("src",src);
imwrite("result1.jpg",dst);
imwrite("result2.jpg",src);
imwrite("result3.jpg",transformed);
waitKey();
}
else
cout<<"Make sure that your are getting 4 corner using approxPolyDP..."<<endl;
teethe Cela se produit généralement lorsque vous comptez sur du code de quelqu'un d'autre pour résoudre votre problème particulier au lieu d'adopter le code. Regardez les étapes de traitement et aussi la différence entre leur et votre image (c'est une bonne idée en passant de commencer par leur image et de vous assurer que le code fonctionne):
Pour résoudre votre problème, vous devez vous assurer que seules les lignes de la périphérie sont extraites. Si vous avez toujours un fond sombre, vous pouvez utiliser ce fait pour supprimer les lignes avec d'autres contrastes/polarités. Vous pouvez également extraire toutes les lignes, puis sélectionner celles qui sont les plus proches de la limite de l'image (si votre arrière-plan n'a pas de lignes).