本文介绍了Android:使用OpenCV对齐图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用OpenCV对齐两个图像.我基于发现的C ++/Python教程编写此代码: http://www.learnopencv.com/image-alignment-ecc-in-opencv-c-python/

I am trying to align two images using OpenCV. I based this code off of a C++/Python tutorial I found: http://www.learnopencv.com/image-alignment-ecc-in-opencv-c-python/

android中的findTransformECC()函数需要一个用于inputMask的额外参数. C ++和Python函数没有此功能.

The findTransformECC() function in android requires an extra parameter for inputMask. The C++ and Python functions don't have this.

我的代码:

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)

推荐答案

您正在向findTransformECC输入完整的3x3单应性矩阵warpMatrix,但是您选择的warp_modeMOTION_EUCLIDEAN.

You're inputting a full 3x3 homography matrix warpMatrix to findTransformECC but your selected warp_mode is MOTION_EUCLIDEAN.

如果要使用3x3单应性,则应将warp_mode设置为MOTION_HOMOGRAPHY.

If you want to use a 3x3 homography, then you should set warp_mode to MOTION_HOMOGRAPHY.

如果要进行欧几里德变换,则只需将输入warpMatrix中的最后一行剪切掉,因为欧几里德变换由2x3矩阵给出.根据 findTransformECC()文档

If you want a Euclidean transformation, you simply need to clip the last row off your input warpMatrix as Euclidean transformations are given by 2x3 matrices. According to the findTransformECC() documentation,

然后,由于您将使用2x3变形矩阵,因此请使用 warpAffine() 而不是warpPerspective()来对齐图像.

Then since you'll be working with 2x3 warp matrices, use warpAffine() instead of warpPerspective() to align the images.

这篇关于Android:使用OpenCV对齐图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 22:50