Point de vue de Transformer + Culture dans iOS avec OpenCV
Je suis en train de mettre en œuvre un recadrage & correction de la perspective de la fonctionnalité dans une prochaine application. Tout en faisant des recherches, je suis tombé sur:
L'exécution de cv::warpPerspective pour un faux correction sur un ensemble de cv::Point
http://sudokugrab.blogspot.ch/2009/07/how-does-it-all-work.html
J'ai donc décidé de tenter la mise en œuvre de cette fonctionnalité avec OpenCV - le cadre est en place pour que l'installation a été rapide. Cependant, je ne suis pas d'obtenir les résultats que j'espère pour: (2ème photo est le résultat)
J'ai traduit tout le code pour travailler avec Xcode et triple vérifié les Coordonnées. Pouvez-vous me dire quel est le problème avec mon code? Par souci d'exhaustivité, j'ai aussi pris le UIImage -> Tapis de conversion + inversion:
- (void)confirmedImage
{
if ([_adjustRect frameEdited]) {
cv::Mat src = [self cvMatFromUIImage:_sourceImage];
//My original Coordinates
//4-------3
//| |
//| |
//| |
//1-------2
CGFloat scaleFactor = [_sourceImageView contentScale];
CGPoint p1 = [_adjustRect coordinatesForPoint:4 withScaleFactor:scaleFactor];
CGPoint p2 = [_adjustRect coordinatesForPoint:3 withScaleFactor:scaleFactor];
CGPoint p3 = [_adjustRect coordinatesForPoint:1 withScaleFactor:scaleFactor];
CGPoint p4 = [_adjustRect coordinatesForPoint:2 withScaleFactor:scaleFactor];
std::vector<cv::Point2f> c1;
c1.push_back(cv::Point2f(p1.x, p1.y));
c1.push_back(cv::Point2f(p2.x, p2.y));
c1.push_back(cv::Point2f(p3.x, p3.y));
c1.push_back(cv::Point2f(p4.x, p4.y));
cv::RotatedRect box = minAreaRect(cv::Mat(c1));
cv::Point2f pts[4];
box.points(pts);
cv::Point2f src_vertices[3];
src_vertices[0] = pts[0];
src_vertices[1] = pts[1];
src_vertices[2] = pts[3];
cv::Point2f dst_vertices[4];
dst_vertices[0].x = 0;
dst_vertices[0].y = 0;
dst_vertices[1].x = box.boundingRect().width-1;
dst_vertices[1].y = 0;
dst_vertices[2].x = 0;
dst_vertices[2].y = box.boundingRect().height-1;
dst_vertices[3].x = box.boundingRect().width-1;
dst_vertices[3].y = box.boundingRect().height-1;
cv::Mat warpAffineMatrix = getAffineTransform(src_vertices, dst_vertices);
cv::Mat rotated;
cv::Size size(box.boundingRect().width, box.boundingRect().height);
warpAffine(src, rotated, warpAffineMatrix, size, cv::INTER_LINEAR, cv::BORDER_CONSTANT);
[_sourceImageView setNeedsDisplay];
[_sourceImageView setImage:[self UIImageFromCVMat:rotated]];
[_sourceImageView setContentMode:UIViewContentModeScaleAspectFit];
rotated.release();
src.release();
}
}
- (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorSpace;
if ( cvMat.elemSize() == 1 ) {
colorSpace = CGColorSpaceCreateDeviceGray();
}
else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef provider = CGDataProviderCreateWithCFData( (__bridge CFDataRef)data );
CGImageRef imageRef = CGImageCreate( cvMat.cols, cvMat.rows, 8, 8 * cvMat.elemSize(), cvMat.step[0], colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault );
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease( imageRef );
CGDataProviderRelease( provider );
CGColorSpaceRelease( colorSpace );
return finalImage;
}
- (cv::Mat)cvMatFromUIImage:(UIImage *)image
{
CGColorSpaceRef colorSpace = CGImageGetColorSpace( image.CGImage );
CGFloat cols = image.size.width;
CGFloat rows = image.size.height;
cv::Mat cvMat( rows, cols, CV_8UC4 );
CGContextRef contextRef = CGBitmapContextCreate( cvMat.data, cols, rows, 8, cvMat.step[0], colorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault );
CGContextDrawImage( contextRef, CGRectMake(0, 0, rows, cols), image.CGImage );
CGContextRelease( contextRef );
CGColorSpaceRelease( colorSpace );
return cvMat;
}
Est-ce la bonne solution à mon problème? Avez-vous un exemple de code qui pourrait m'aider?
Merci d'avoir lu ma question!
UDATE:
En fait, j'ai Open Source mon UIImagePickerController de remplacement ici: https://github.com/mmackh/MAImagePickerController-of-InstaPDF
qui comprend le réglage de recadrage de la vue, de filtres et de correction de la perspective.
- Votre question est bien encadrée mate!
- Je vous remercie, une fois terminé, je suis la planification à la libération de l'ensemble du code source pour aider les autres aussi. C'est de me donner quelques maux de tête à l'instant.
- Votre question est à propos de faire une perspective de transformation, mais votre code à l'aide de getAffineTransform et warpAffine.
- La raison d'être de l'efficacité et de la vitesse -> stackoverflow.com/a/7885428/1091044 Est-ce incorrect?
- votre post très utile pour moi, merci pour elle, je veut savoir qu'est-ce que _adjustRect , pouvez-vous me donner peu de code pour faire glisser les coins, je SUIS aux prises avec ce dernier quelques jours, merci
- Comment contrôlez-vous le plus de points? pouvez-vous expliquer _adjustRect? voir mon post stackoverflow.com/questions/13594391/...
- Découvrez: MAImagePickerController (github.com/mmackh/MAImagePickerController-of-InstaPDF)
- Je veux le même dans Android. Je ne suis pas en mesure de culture détectés Mat objet. Je suis noir de l'image lors du cadrage. Pouvez-vous svp m'aider??
Vous devez vous connecter pour publier un commentaire.
Alors après quelques jours d'essayer de le résoudre, je suis venu avec une solution de (Ignorer les points bleus sur la deuxième image):
Comme promis, voici une copie complète du code:
Espère que cela vous aide + codage heureux!
Je pense que le point de correspondance dans
getAffineTransform
est incorrect.Vérifier les coordonnées du point de sortie par
box.points(pts);
Pourquoi ne pas simplement utiliser
p1 p2 p3 p4
pour calculer la transformation?