使用JavaCV库进行图像旋转的java问题
我正在编写一个Android应用程序,它可以在指定的时间内录制视频。如果我用智能手机的后置摄像头录制,一切都会正常进行。该应用程序具有暂停/录制功能,如Vine应用程序中的功能。当使用设备的前置摄像头进行录制时会出现问题。存储/播放视频时,视频表面帧看起来很好,因为视频是倒置的。关于这个问题,到处都有很多讨论。但我没有找到任何有效的解决方案
看看下面提到的代码和图片
这是前摄像头拍摄的原始图像。为了看得更清楚,我把它翻了个底朝天
以下是我在旋转后实际得到的结果:
方法:
IplImage copy = cvCloneImage(image);
IplImage rotatedImage = cvCreateImage(cvGetSize(copy), copy.depth(), copy.nChannels());
//Define Rotational Matrix
CvMat mapMatrix = cvCreateMat(2, 3, CV_32FC1);
//Define Mid Point
CvPoint2D32f centerPoint = new CvPoint2D32f();
centerPoint.x(copy.width() / 2);
centerPoint.y(copy.height() / 2);
//Get Rotational Matrix
cv2DRotationMatrix(centerPoint, angle, 1.0, mapMatrix);
//Rotate the Image
cvWarpAffine(copy, rotatedImage, mapMatrix, CV_INTER_CUBIC + CV_WARP_FILL_OUTLIERS, cvScalarAll(170));
cvReleaseImage(copy);
cvReleaseMat(mapMatrix);
我已经试过了
double angleTemp = angle;
angleTemp= ((angleTemp / 90)%4)*90;
final int number = (int) Math.abs(angleTemp/90);
for(int i = 0; i != number; ++i){
cvTranspose(rotatedImage, rotatedImage);
cvFlip(rotatedImage, rotatedImage, 0);
}
最终引发异常,表示源和目标与列数和行数不匹配
更新:
视频就是这样录制的
IplImage newImage = null;
if(cameraSelection == CameraInfo.CAMERA_FACING_FRONT){
newImage = videoRecorder.rotate(yuvIplImage, 180);
videoRecorder.record(newImage);
}
else
videoRecorder.record(yuvIplImage);
旋转是这样进行的:
IplImage img = IplImage.create(image.height(), image.width(),
image.depth(), image.nChannels());
for (int i = 0; i < 180; i++) {
cvTranspose(image, img);
cvFlip(img, img, 0);
}
如果你以前有过这样的经历,有人能指出这里的错误吗
# 1 楼答案
# 2 楼答案
进行转置时,图像的宽度和高度值将被替换。这就像将矩形旋转90度,使高度变为宽度,反之亦然。因此,您需要执行以下操作:
# 3 楼答案
鉴于您已经有了IplImage,您可能会发现这一点很有帮助。我已经修改了这个Open Source Android Touch-To-Record library的onPreviewFrame方法,以进行转置并调整捕获帧的大小
我在setCameraParams()方法中定义了“YuvipImage”,如下所示
也可以这样初始化录像机,将宽度作为高度发送,反之亦然:
这是我的onPreviewFrame()方法:
这段代码使用了一个方法“YUV_NV21_TO_BGR”,我从这个link中找到了这个方法
基本上我和你的问题一样,“安卓上的绿魔鬼问题”。在添加“YUV_NV21_TO_BGR”方法之前,我刚刚对YuvIplImage进行了转置,更重要的是转置、翻转(有或没有调整大小)的组合,结果视频中有绿色输出,几乎与您的一样。这种“YUV_NV21_TO_BGR”方法消除了绿色输出问题。感谢上面的google群组帖子中的@David Han
您还应该知道,在onPreviewFrame中,所有这些处理(转置、翻转和调整大小)都需要花费大量时间,这会对每秒帧数(FPS)速率造成严重影响。当我在onPreviewFrame方法中使用这段代码时,录制视频的帧速率从30fps降至3帧/秒
# 4 楼答案
这段代码将帮助您处理旋转IplImage时的问题