【发布时间】:2018-07-19 17:13:45
【问题描述】:
我需要使用 OpenCV 库在我的 android 应用程序中对齐不同的图像。我在thread 中找到了解决方案。
public static Bitmap alignImagesHomography(Bitmap A, Bitmap B)
{
final int warp_mode = MOTION_HOMOGRAPHY;
Mat matA = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8UC3);
Mat matAgray = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8U);
Mat matB = new Mat(B.getHeight(), B.getWidth(), CvType.CV_8UC3);
Mat matBgray = new Mat(B.getHeight(), B.getWidth(), CvType.CV_8U);
Mat matBaligned = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8UC3);
Mat warpMatrix = Mat.eye(3, 3, CV_32F);
Utils.bitmapToMat(A, matA);
Utils.bitmapToMat(B, matB);
Imgproc.cvtColor(matA, matAgray, Imgproc.COLOR_BGR2GRAY);
Imgproc.cvtColor(matB, matBgray, Imgproc.COLOR_BGR2GRAY);
int numIter = 5;
double terminationEps = 1e-10;
TermCriteria criteria = new TermCriteria(TermCriteria.COUNT + TermCriteria.EPS, numIter, terminationEps);
findTransformECC(matAgray, matBgray, warpMatrix, warp_mode, criteria, matBgray);
Imgproc.warpPerspective(matA, matBaligned, warpMatrix, matA.size(), Imgproc.INTER_LINEAR + Imgproc.WARP_INVERSE_MAP);
Bitmap alignedBMP = Bitmap.createBitmap(A.getWidth(), A.getHeight(), Bitmap.Config.RGB_565);
Utils.matToBitmap(matBaligned, alignedBMP);
return alignedBMP;
}
public static Bitmap alignImagesEuclidean(Bitmap A, Bitmap B)
{
final int warp_mode = MOTION_EUCLIDEAN;
Mat matA = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8UC3);
Mat matAgray = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8U);
Mat matB = new Mat(B.getHeight(), B.getWidth(), CvType.CV_8UC3);
Mat matBgray = new Mat(B.getHeight(), B.getWidth(), CvType.CV_8U);
Mat matBaligned = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8UC3);
Mat warpMatrix = Mat.eye(2,3,CV_32F);
Utils.bitmapToMat(A, matA);
Utils.bitmapToMat(B, matB);
Imgproc.cvtColor(matA, matAgray, Imgproc.COLOR_BGR2GRAY);
Imgproc.cvtColor(matB, matBgray, Imgproc.COLOR_BGR2GRAY);
int numIter = 5;
double terminationEps = 1e-10;
TermCriteria criteria = new TermCriteria(TermCriteria.COUNT + TermCriteria.EPS, numIter, terminationEps);
findTransformECC(matAgray, matBgray, warpMatrix, warp_mode, criteria, matBgray);
Imgproc.warpAffine(matA, matBaligned, warpMatrix, matA.size(), Imgproc.INTER_LINEAR + Imgproc.WARP_INVERSE_MAP);
Bitmap alignedBMP = Bitmap.createBitmap(A.getWidth(), A.getHeight(), Bitmap.Config.RGB_565);
Utils.matToBitmap(matBaligned, alignedBMP);
return alignedBMP;
}
public static Bitmap alignExposures(Bitmap A, Bitmap B) {
Mat matA = new Mat(A.getHeight(), A.getWidth(), CvType.CV_8UC3);
Mat matB = new Mat(B.getHeight(), B.getWidth(), CvType.CV_8UC3);
Utils.bitmapToMat(A, matA);
Utils.bitmapToMat(B, matB);
List<Mat> src = new ArrayList<>();
src.add(matA);
src.add(matB);
Bitmap output = Bitmap.createBitmap(A.getWidth(),A.getHeight(), Bitmap.Config.RGB_565);
AlignMTB align = createAlignMTB(8, 4, false);
align.process(src,src);
for(int i = 1; i < src.size(); i++) {
add(src.get(0),src.get(i),src.get(0));
}
Utils.matToBitmap(src.get(0),output);
return output;
}
我尝试了用户 wegenerEDV 编写的所有三种方法。无论如何,前两个方法返回与作为输入给出的“位图 A”相同的图片;第三种方法实际上是对齐图片,但结果图像曝光过度:
原文:https://i.imgur.com/cknHM23.jpg
对齐:https://i.imgur.com/kXCQl6x.jpg
有没有人找到不同的解决方案?还是这些方法真的有效而我做错了什么?
对我来说最好的解决方案是更正 alignImagesHomography 方法。它实际上做了一些事情,因为处理最终图片大约需要 30 秒,但它与输入图像完全相等。
【问题讨论】:
-
您尝试对齐的示例图像是什么?您需要仿射、单应还是非刚性对齐?
-
在我的应用程序中,我必须对齐一系列图像,因此它们是快速连续拍摄的几张照片。我的算法的伪代码需要通过SIFT algorithm 和ORSA 算法(RANSAC 变体)进行对齐,但实际上并不需要使用该特定算法。所以我觉得应该是单应对齐。
标签: android opencv image-registration