在iOS中使用OpenCV人脸检测裁剪图片

5
我在我的人脸检测代码中使用以下代码从图像中裁剪出脸部。但是我没有得到正确的脸部图像,只保存了图像的一部分而不是脸部。我的代码有什么问题?
_faceCascade.detectMultiScale(mat, faces, 1.1, 2, kHaarOptions, cv::Size(40, 40));

在displayfaces函数中,我使用以下代码进行裁剪:

CGRect cropRect = CGRectMake(faces[i].x, faces[i].y, faces[i].width, faces[i].width);
CGImageRef cropped_img = CGImageCreateWithImageInRect(self.storeImage.CGImage, cropRect);
UIImage *img = [UIImage imageWithCGImage:cropped_img];
UIImageWriteToSavedPhotosAlbum( img, self,  nil,nil);

我已经得到了faces[i]的正确坐标。但问题在于裁剪和设置ROI。有人能帮我解决吗?
我尝试了下面的代码,但是我得到的图像仍然是相同的(即,我没有得到实际的人脸图像)。
cv :: Mat image_roi;
cv::Rect roi(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
cv::Mat(testMat, roi).copyTo(image_roi);
UIImage *img = [CaptureViewController imageWithCVMat:image_roi ];
UIImageWriteToSavedPhotosAlbum( img, self,  nil,nil);

注意:我正在使用OpenCV facedetect在实时视频流中检测人脸。我可以得到绿色矩形框围绕着脸部,但是我无法根据脸部参数裁剪出脸部。我还尝试了设置faceroi来检测眼睛,但也失败了。为了缩小问题范围,可能问题出在设置图像ROI上?
更新于11/02/13:
我已经进行了如下裁剪,但ROI没有正确设置,图像裁剪效果不佳:
我发现我的问题是由于旋转问题造成的(感谢@Jameo指出)。我已经对图像做了如下旋转处理。
UIImage *rotateImage = [[UIImage alloc] initWithCGImage: image.CGImage
                               scale: 1.0
                         orientation: UIImageOrientationRight];

使用以下代码对图像进行裁剪:

// get sub image
+ (UIImage*) getSubImageFrom: (UIImage*) img WithRect: (CGRect) rect
{
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    // translated rectangle for drawing sub image
    CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height);
    // clip to the bounds of the image context
    // not strictly necessary as it will get clipped anyway?
    CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height));
    // draw image
    [img drawInRect:drawRect];
    // grab image
    UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return subImage;
}

图片被裁剪但没有使用实际坐标。

我的观察: 1)我正在使用由Affinetransform返回的FaceRect来裁剪图像。这会导致错误的坐标吗?还是因为我的代码有错? 2)在设置仿射变换之前,我无法为图像设置ROI,这是为什么?这是设置ROI的步骤吗?

faceRect = CGRectApplyAffineTransform(faceRect, t);

但是仍然没有正确地裁剪图片,差异如下:

完整图片:

完整图片

裁剪后的图片:

输入图像描述


只是好奇,这个图像保存的是什么?它只是图像的不同子集吗?如果是这样,也许它就是你的ROI。我肯定会NSLog你的ROI并查看它试图做什么。 - Jameo
x = 45,y = 105,width = 124,height = 124。这些是faces[i].x,face[i].y,faces[i].width,faces[i].height的值。但我的主要疑问是,如果坐标不正确,我怎么会得到一个围绕脸部的矩形? - 2vision2
我不确定你最后一句话的意思。不过,我在图像旋转方面遇到了很多问题,这可能是个问题吗?(为了测试,您也可以输出输入帧的x、y、宽度和高度)然后问问自己,这些坐标是否对于该屏幕有意义?我怀疑的原因是因为您的裁剪看起来是正确的。 - Jameo
@Jameo 我也尝试了这篇帖子中的第二个答案来解决旋转问题。但是图像的同一部分仍然被裁剪了。https://dev59.com/QHE85IYBdhLWcg3wvGKm - 2vision2
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/24145/discussion-between-jameo-and-2vision2 - Jameo
显示剩余4条评论
2个回答

1
这个怎么样?
- (UIImage *) getSubImageFrom:(UIImage *)imageToCrop WithRect:(CGRect)rect {

    CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);    
    UIImage *cropped = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    return cropped;    
}

0

尝试使用以下代码获取面部坐标:

CGRect newBounds = CGRectMake(faceFeature.bounds.origin.x, 
                              _picture.size.height - faceFeature.bounds.origin.y - largestFace.bounds.size.height, 
                              faceFeature.bounds.size.width, 
                              faceFeature.bounds.size.height);

使用以下方法裁剪图像:
CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, newBounds);
UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
UIImageView *newView = [[UIImageView alloc] initWithImage:croppedImage];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接