Я пытаюсь реализовать обрезку и коррекцию перспективы.Я использую IOS (Swift) для разработки приложений и OpenCV для обрезки и преобразования перспективы.
Я получил функцию определения края, чтобы определить точку контура для меня.Таким образом, в основном, четыре точки, которые составляют прямоугольник.
Однако, когда я отправляю точки в OpenCV, я получаю искаженное изображение ниже.Или мне возвращается искаженное изображение ниже.
Ниже приведен результат, который я получаю.
Это оригинальное изображение:
Это сценарийгде краеугольный камень был крайним:
Это сценарий, где я взял изображение сверху:
У меня естьследуя приведенной ниже статье, но безуспешно.
Перспективное Преобразование + Обрезка в iOS с OpenCV
Я делаю что-то неправильно с точки зрения ориентации изображения исортировка точек.
Я использую OpenCV4 с Swift, чтобы попытаться снять перекос, выровнять и, возможно, обрезать изображение, снятое с камеры устройства.
Я позволяю пользователям перетаскивать точки на экране в четыре угла изображения.После того, как пользователи выбрали точки, я отправляю их в OpenCV, чтобы попытаться де-перекосить их.В настоящее время я использую cv :: warpPerspective для достижения этой цели.
Я искал и пробовал несколько примеров, и я не могу найти проблему с тем, что я делаю.
+(UIImage*)confirmedImage
:(UIImage *)sourceImage
:(CGFloat)contentScale
:(CGPoint)point1
:(CGPoint)point2
:(CGPoint)point3
:(CGPoint)point4
{
vector<Point2f> pointsToSort;
pointsToSort.push_back(Point2f(point1.x, point1.y));
pointsToSort.push_back(Point2f(point2.x, point2.y));
pointsToSort.push_back(Point2f(point3.x, point3.y));
pointsToSort.push_back(Point2f(point4.x, point4.y));
NSLog(@"\npoints before sorting in objective c");
vector<Point2f> sortedPoints = [self sortCorners:pointsToSort];
CGPoint p1 = CGPointMake(CGFloat(sortedPoints[0].x), CGFloat(sortedPoints[0].y));
CGPoint p2 = CGPointMake(CGFloat(sortedPoints[1].x), CGFloat(sortedPoints[1].y));
CGPoint p3 = CGPointMake(CGFloat(sortedPoints[2].x), CGFloat(sortedPoints[2].y));
CGPoint p4 = CGPointMake(CGFloat(sortedPoints[3].x), CGFloat(sortedPoints[3].y));
NSLog(@"\npoint1.x %f", p1.x);
NSLog(@"point1.y %f", p1.y);
NSLog(@"\npoint1.x %f", p2.x);
NSLog(@"point1.y %f", p2.y);
NSLog(@"\npoint1.x %f", p3.x);
NSLog(@"point1.y %f", p3.y);
NSLog(@"\npoint1.x %f", p4.x);
NSLog(@"point1.y %f", p4.y);
NSLog(@"\npoints after sorting in objective c");
CGFloat scaleFactor = contentScale;
NSLog(@"\n scaleFactor: %f", scaleFactor);
CGPoint ptBottomLeft = CGPointMake(CGFloat(p1.x / scaleFactor), CGFloat(p1.y / scaleFactor));
CGPoint ptBottomRight = CGPointMake(CGFloat(p2.x / scaleFactor), CGFloat(p2.y / scaleFactor));
CGPoint ptTopRight = CGPointMake(CGFloat(p3.x / scaleFactor), CGFloat(p3.y / scaleFactor));
CGPoint ptTopLeft = CGPointMake(CGFloat(p4.x / scaleFactor), CGFloat(p4.y / scaleFactor));
CGFloat w1 = sqrt( pow(ptBottomRight.x - ptBottomLeft.x , 2) + pow(ptBottomRight.x - ptBottomLeft.x, 2));
CGFloat w2 = sqrt( pow(ptTopRight.x - ptTopLeft.x , 2) + pow(ptTopRight.x - ptTopLeft.x, 2));
CGFloat h1 = sqrt( pow(ptTopRight.y - ptBottomRight.y , 2) + pow(ptTopRight.y - ptBottomRight.y, 2));
CGFloat h2 = sqrt( pow(ptTopLeft.y - ptBottomLeft.y , 2) + pow(ptTopLeft.y - ptBottomLeft.y, 2));
NSLog(@"\n w1 : %f", w1);
NSLog(@"\n w2 : %f", w2);
NSLog(@"\n h1 : %f", h1);
NSLog(@"\n h2 : %f", h2);
CGFloat maxWidth = (w1 < w2) ? w1 : w2;
CGFloat maxHeight = (h1 < h2) ? h1 : h2;
NSLog(@"\n maxWidth : %f", maxWidth);
NSLog(@"\n maxHeight : %f", maxHeight);
cv::Point2f src[4], dst[4];
src[0].x = ptTopLeft.x;
src[0].y = ptTopLeft.y;
src[1].x = ptTopRight.x;
src[1].y = ptTopRight.y;
src[2].x = ptBottomLeft.x;
src[2].y = ptBottomLeft.y;
src[3].x = ptBottomRight.x;
src[3].y = ptBottomRight.y;
dst[0].x = 0;
dst[0].y = 0;
dst[1].x = maxWidth - 1;
dst[1].y = 0;
dst[2].x = 0;
dst[2].y = maxHeight - 1;
dst[3].x = maxWidth - 1;
dst[3].y = maxHeight - 1;
// dst[0].x = 0;
// dst[0].y = 0;
// dst[1].x = 0;
// dst[1].y = maxHeight - 1;
// dst[2].x = maxWidth - 1;
// dst[2].y = maxHeight - 1;
// dst[3].x = maxWidth - 1;
// dst[3].y = 0;
//ORIG
// dst[0].x = 0;
// dst[0].y = 0;
// dst[1].x = maxWidth - 1;
// dst[1].y = 0;
// dst[2].x = maxWidth - 1;
// dst[2].y = maxHeight - 1;
// dst[3].x = 0;
// dst[3].y = maxHeight - 1;
cv::Size matSize = cv::Size(maxWidth, maxHeight);
cv::Mat undistorted = cv::Mat(matSize, CV_8UC1);
cv::Mat original = [OpenCVWrapperInternal cvMatFromUIImage:sourceImage];
cv::warpPerspective(original, undistorted, cv::getPerspectiveTransform(src, dst), matSize);
original.release();
// Rotate
cv::Mat rotated;
rotate(undistorted, rotated, 2);
// Flip
// cv:: Mat flipped;
// cv::flip(rotated, flipped, 1);
UIImage *newImage = [OpenCVWrapperInternal UIImageFromCVMat:undistorted :sourceImage];
undistorted.release();
// flipped.release();
rotated.release();
return newImage;
}
Я ожидаю, когда я беру изображение независимо от ориентацииили забивание камнями, чтобы оно было сужено, перекошено и чтобы правильно отображалось окончательное изображение.