2017-06-06 143 views
0

我想使用OpenCV對齊兩個圖像。我基於這個代碼基於C++/Python教程,我發現:http://www.learnopencv.com/image-alignment-ecc-in-opencv-c-python/Android:使用OpenCV對齊圖像

android中的findTransformECC()函數需要inputMask的額外參數。 C++和Python函數沒有這個。

我的代碼:

import android.graphics.Bitmap; 

import org.opencv.android.Utils; 
import org.opencv.core.CvType; 
import org.opencv.core.Mat; 
import org.opencv.core.TermCriteria; 
import org.opencv.imgproc.Imgproc; 

import static org.opencv.core.CvType.CV_32F; 
import static org.opencv.video.Video.MOTION_EUCLIDEAN; 
import static org.opencv.video.Video.findTransformECC; 

public class ImageProcessor { 

    public static Bitmap alignImages(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(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 = 5000; 
     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(),null); 
     Utils.matToBitmap(matBaligned,alignedBMP); 
     return alignedBMP; 
    } 

} 

我收到以下錯誤

W/System.err: CvException [org.opencv.core.CvException: cv::Exception: /build/master_pack-android/opencv/modules/imgproc/src/imgwarp.cpp:5987: error: (-215) (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 2 && M0.cols == 3 in function void cv::warpAffine(cv::InputArray, cv::OutputArray, cv::InputArray, cv::Size, int, int, const Scalar&) 
W/System.err: ] 
W/System.err:  at org.opencv.video.Video.findTransformECC_0(Native Method) 
W/System.err:  at org.opencv.video.Video.findTransformECC(Video.java:132) 
W/System.err:  at com.test.imgptest.ImageProcessor.alignImages(ImageProcessor.java:42) 
W/System.err:  at com.test.imgptest.MainActivity.onActivityResult(MainActivity.java:141) 
W/System.err:  at android.app.Activity.dispatchActivityResult(Activity.java:6937) 
W/System.err:  at android.app.ActivityThread.deliverResults(ActivityThread.java:4122) 
W/System.err:  at android.app.ActivityThread.handleSendResult(ActivityThread.java:4169) 
W/System.err:  at android.app.ActivityThread.-wrap20(ActivityThread.java) 
W/System.err:  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1552) 
W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:102) 
W/System.err:  at android.os.Looper.loop(Looper.java:154) 
W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:6186) 
W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

回答

1

你輸入一個完整的3x3單應矩陣warpMatrixfindTransformECC但你的選擇warp_modeMOTION_EUCLIDEAN

如果要使用3x3單應性,則應將warp_mode設置爲MOTION_HOMOGRAPHY

如果你想要一個歐幾里得變換,你只需要剪掉輸入的最後一行warpMatrix,因爲歐幾里得變換由2x3矩陣給出。根據findTransformECC() documentation

MOTION_EUCLIDEAN設置一個歐氏(剛性的)變換爲運動模型;估計三個參數; warpMatrix是2x3

然後因爲你會2x3經矩陣來工作,使用warpAffine()代替warpPerspective()對齊圖像。

+0

謝謝!我打算保留它'MOTION_HOMOGRAPHY'。現在感到很蠢。 :P – xSooDx

+1

@xSooDx它發生在我們身上!我編輯我的答案一點,以包括這種可能性,以及其他任何人。 –