我刚刚计划将openCV用于我的iOS应用程序。
我创建了相机预览,但它在横向模式下显示的方向不正确。我不知道如何以正确的方向旋转相机意味着如果移动设备是纵向的,那么相机应该以纵向模式打开..
有没有解决方案?
答案 0 :(得分:1)
如果您使用的是CvVideoCameraDelegate,请在viewDidLoad方法中初始化相机参数后添加以下代码行。
self->videoCamera.rotateVideo = YES;
答案 1 :(得分:0)
您并不具体说明相关窗口是视图还是图层,还是实时视频或保存到文件中。您也没有指定视频是通过OpenCV录制还是通过其他方式录制。
因此,我列出了每个意外情况的代码片段;如果您熟悉OpenCV以及iOS视图编程的基础知识,应该明白应该使用的内容(在我的情况下,顺便说一句,我使用了所有内容):
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
switch ([UIDevice currentDevice].orientation) {
case UIDeviceOrientationPortraitUpsideDown:
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
break;
case UIDeviceOrientationLandscapeLeft:
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationLandscapeLeft;
break;
case UIDeviceOrientationLandscapeRight:
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationLandscapeRight;
break;
default:
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
break;
}
[self refresh];
}
- (void)processImage:(cv::Mat &)mat {
if (self.videoCamera.running) {
switch (self.videoCamera.defaultAVCaptureVideoOrientation) {
case AVCaptureVideoOrientationLandscapeLeft:
case AVCaptureVideoOrientationLandscapeRight:
// The landscape video is captured upside-down.
// Rotate it by 180 degrees.
cv::flip(mat, mat, -1);
break;
default:
break;
}
}
- (void)convertBlendSrcMatToWidth:(int)dstW height:(int)dstH {
double dstAspectRatio = dstW / (double)dstH;
int srcW = originalBlendSrcMat.cols;
int srcH = originalBlendSrcMat.rows;
double srcAspectRatio = srcW / (double)srcH;
cv::Mat subMat;
if (srcAspectRatio < dstAspectRatio) {
int subMatH = (int)(srcW / dstAspectRatio);
int startRow = (srcH - subMatH) / 2;
int endRow = startRow + subMatH;
subMat = originalBlendSrcMat.rowRange(startRow, endRow);
} else {
int subMatW = (int)(srcH * dstAspectRatio);
int startCol = (srcW - subMatW) / 2;
int endCol = startCol + subMatW;
subMat = originalBlendSrcMat.colRange(startCol, endCol);
}
cv::resize(subMat, convertedBlendSrcMat, cv::Size(dstW, dstH), 0.0, 0.0, cv::INTER_LANCZOS4);
- (int)imageWidth {
AVCaptureVideoDataOutput *output = [self.captureSession.outputs lastObject];
NSDictionary *videoSettings = [output videoSettings];
int videoWidth = [[videoSettings objectForKey:@"Width"] intValue];
return videoWidth;
}
- (int)imageHeight {
AVCaptureVideoDataOutput *output = [self.captureSession.outputs lastObject];
NSDictionary *videoSettings = [output videoSettings];
int videoHeight = [[videoSettings objectForKey:@"Height"] intValue];
return videoHeight;
}
- (void)updateSize {
// Do nothing.
}
- (void)layoutPreviewLayer {
if (self.parentView != nil) {
// Center the video preview.
self.customPreviewLayer.position = CGPointMake(0.5 * self.parentView.frame.size.width, 0.5 * self.parentView.frame.size.height);
// Find the video's aspect ratio.
CGFloat videoAspectRatio = self.imageWidth / (CGFloat)self.imageHeight;
// Scale the video preview while maintaining its aspect ratio.
CGFloat boundsW;
CGFloat boundsH;
if (self.imageHeight > self.imageWidth) {
if (self.letterboxPreview) {
boundsH = self.parentView.frame.size.height;
boundsW = boundsH * videoAspectRatio;
} else {
boundsW = self.parentView.frame.size.width;
boundsH = boundsW / videoAspectRatio;
}
} else {
if (self.letterboxPreview) {
boundsW = self.parentView.frame.size.width;
boundsH = boundsW / videoAspectRatio;
} else {
boundsH = self.parentView.frame.size.height;
boundsW = boundsH * videoAspectRatio;
}
}
self.customPreviewLayer.bounds = CGRectMake(0.0, 0.0, boundsW, boundsH);
}
}
- (void)processImage:(cv::Mat &)mat {
if (self.videoCamera.running) {
switch (self.videoCamera.defaultAVCaptureVideoOrientation) {
case AVCaptureVideoOrientationLandscapeLeft:
case AVCaptureVideoOrientationLandscapeRight:
// The landscape video is captured upside-down.
// Rotate it by 180 degrees.
cv::flip(mat, mat, -1);
break;
default:
break;
}
}
- (void)convertBlendSrcMatToWidth:(int)dstW height:(int)dstH {
double dstAspectRatio = dstW / (double)dstH;
int srcW = originalBlendSrcMat.cols;
int srcH = originalBlendSrcMat.rows;
double srcAspectRatio = srcW / (double)srcH;
cv::Mat subMat;
if (srcAspectRatio < dstAspectRatio) {
int subMatH = (int)(srcW / dstAspectRatio);
int startRow = (srcH - subMatH) / 2;
int endRow = startRow + subMatH;
subMat = originalBlendSrcMat.rowRange(startRow, endRow);
} else {
int subMatW = (int)(srcH * dstAspectRatio);
int startCol = (srcW - subMatW) / 2;
int endCol = startCol + subMatW;
subMat = originalBlendSrcMat.colRange(startCol, endCol);
}
cv::resize(subMat, convertedBlendSrcMat, cv::Size(dstW, dstH), 0.0, 0.0, cv::INTER_LANCZOS4);
- (int)imageWidth {
AVCaptureVideoDataOutput *output = [self.captureSession.outputs lastObject];
NSDictionary *videoSettings = [output videoSettings];
int videoWidth = [[videoSettings objectForKey:@"Width"] intValue];
return videoWidth;
}
- (int)imageHeight {
AVCaptureVideoDataOutput *output = [self.captureSession.outputs lastObject];
NSDictionary *videoSettings = [output videoSettings];
int videoHeight = [[videoSettings objectForKey:@"Height"] intValue];
return videoHeight;
}
- (void)updateSize {
// Do nothing.
}
- (void)layoutPreviewLayer {
if (self.parentView != nil) {
// Center the video preview.
self.customPreviewLayer.position = CGPointMake(0.5 * self.parentView.frame.size.width, 0.5 * self.parentView.frame.size.height);
// Find the video's aspect ratio.
CGFloat videoAspectRatio = self.imageWidth / (CGFloat)self.imageHeight;
// Scale the video preview while maintaining its aspect ratio.
CGFloat boundsW;
CGFloat boundsH;
if (self.imageHeight > self.imageWidth) {
if (self.letterboxPreview) {
boundsH = self.parentView.frame.size.height;
boundsW = boundsH * videoAspectRatio;
} else {
boundsW = self.parentView.frame.size.width;
boundsH = boundsW / videoAspectRatio;
}
} else {
if (self.letterboxPreview) {
boundsW = self.parentView.frame.size.width;
boundsH = boundsW / videoAspectRatio;
} else {
boundsH = self.parentView.frame.size.height;
boundsW = boundsH * videoAspectRatio;
}
}
self.customPreviewLayer.bounds = CGRectMake(0.0, 0.0, boundsW, boundsH);
}
}
这里有很多,你必须知道把它放在哪里。如果你无法弄清楚,请告诉我。